Ich habe eine Tabelle, die eine Liste von Objekten enthält und welche Anforderungen sie erfüllen. Dann habe ich eine Tabelle, die eine Liste von Aufgaben enthält und welche Anforderungen ein Objekt erfüllen muss, um die Aufgabe ausführen zu können. Ich möchte folgende Fragen stellen: Zeigen Sie mir bei gegebener Aufgabe alle Objekte, die diese Aufgabe ausführen können, und zeigen Sie mir bei gegebenem Objekt alle Aufgaben, die das Objekt ausführen kann:
Beispiel:
task_req Tabelle
tasks | reqs
-----------------
taskA | req1
taskA | req2
taskA | req3
taskB | req4
taskB | req5
taskB | req6
In dieser Tabelle heißt es also, dass für die Ausführung von Aufgabe A die Anforderungen req1, req2 und req3 erforderlich sind.
obj_reqs Tabelle
object | reqs
----------------
obj1 | req3
obj1 | req4
obj2 | req1
obj2 | req2
obj2 | req3
obj2 | req4
Ich könnte also die Frage stellen: Welche Objekte können taskA ausführen? Die Antwort sollte nur eine Zeile sein:
tasks | objects
-------------------
taskA | object2
weil obj2 das einzige ist, das die Anforderungen req1, req2, req3 erfüllt. Andere Frage: Welche Objekte können Aufgabe B ausführen? Die Antwort lautet keine, da es kein Objekt mit den Anforderungen req4, req5, req6 gibt. Die Abfrage sollte eine Handle-Logik sein, bei der eine Aufgabe von mehreren Objekten ausgeführt werden kann, indem mehrere Zeilen zurückgegeben werden.
Die Frage ist: Welche Abfrage macht das?
Mein Problem ist, dass ich es geschafft habe, eine solche Abfrage zu finden, aber es scheint mir zu kompliziert. Die Abfrage führt im Wesentlichen Folgendes aus: A) innere Verknüpfung task_reqs-Tabelle mit obj_reqs-Tabelle, Gruppieren nach Aufgaben und objs und Zählen unterschiedlicher Anforderungen, B) Auswählen von Aufgaben, Zählen (unterscheiden (Anforderungen)) von task_reqs-Gruppieren nach Aufgaben, C) innerer Join A und B. sowohl für die Aufgabe als auch für die Anzahl (verschieden (Anforderungen)).
Sicher gibt es einen einfacheren Weg, um diese Abfrage durchzuführen, oder?
Ich füge unter dem SQL-Code ein, um die Tabellen und meine Abfrage zu generieren.
create table task_reqs (task varchar, req varchar);
create table obj_reqs (object varchar, req varchar);
insert into task_reqs values ('taskA', 'req1');
insert into task_reqs values ('taskA', 'req2');
insert into task_reqs values ('taskA', 'req3');
insert into task_reqs values ('taskB', 'req4');
insert into task_reqs values ('taskB', 'req5');
insert into task_reqs values ('taskB', 'req6');
insert into obj_reqs values ('obj1','req1');
insert into obj_reqs values ('obj1','req3');
insert into obj_reqs values ('obj2','req1');
insert into obj_reqs values ('obj2','req2');
insert into obj_reqs values ('obj2','req3');
insert into obj_reqs values ('obj2','req4');
und meine Anfrage:
select t.task,t.object,n.n_reqs
from (
select task,object,count(distinct(obj_reqs.req)) as n_reqs
from task_reqs
inner join obj_reqs on task_reqs.req=obj_reqs.req
group by task,object
) t
inner join (
select task,count(distinct(req)) as n_reqs
from task_reqs
group by task
) n
on n.n_reqs=t.n_reqs and n.task=t.task;
was zurückgibt:
task | object | n_reqs
-------+--------+--------
taskA | obj2 | 3
Sicher gibt es einen einfacheren Weg.
distinct
ist keine Funktion. Das Einschließen einer Spalte indistinct
Klammern ändert nichts und ist nutzlos.count(distinct (a))
ist das gleiche wiecount(distinct a)
Antworten:
Hier ist ein möglicher einfacher Weg:
Demo
quelle
Sie können dies mit einem Cross-Join der Tabellen tun:
Siehe die Demo .
Ergebnisse:
quelle
Ihre Anfrage scheint in Ordnung zu sein. Ich glaube, dies wird kompliziert, egal wie Sie es verfolgen, da die Join-Kriterien und / oder wo Prädikate von beiden
req
und der Anzahl derreq
Übereinstimmungen abhängen .Fensterfunktionen können hier die Verarbeitungszeit verkürzen, da Sie einen Tabellenscan aus Ihrer ursprünglichen Abfrage entfernen können.
Wenn Sie einen Index für haben
obj_reqs.req
, würde diese Abfrage meiner Meinung nach auch ziemlich schnell sein. Wenn Sie nur an einer bestimmten Aufgabe interessiert sind, können Sie diese derWHERE
Klausel in der innersten Unterabfrage (trqs
) hinzufügen .SQLFiddle hier
Das Umkehren dieser Logik funktioniert für Frage 2
SQLFiddle hier
quelle