2012-04-04 1 views
1

Haben Sie die folgenden Beispieldaten in einer Oracle-Tabelle namens MY_ATTRIBUTES:Wie Zurückgeben Distinct Datensätze Basierend auf zwei verschiedenen Werten

Date  Emp_No Attribute 
----------------------------------------------------- 
01/04/2012 1234567 APPLE 
01/04/2012 1234567 ORANGE 
01/04/2012 1234567 PINEAPPLE 
01/04/2012 1234567 BANANA 
01/04/2012 8888888 APPLE 
01/04/2012 8888888 ORANGE 
01/04/2012 2222222 APPLE 
01/04/2012 2222222 ORANGE 
01/04/2012 2222222 PINEAPPLE 

Basierend auf den obigen Beispieldaten, brauche ich nur nur die unterschiedlichen Datensätze zurück mit Datum und eMP_NO wo diese Datensätze Daten enthält, die sowohl die Attribute von ‚APPLE‘ haben und ‚PINEAPPLE‘

So auf der Grundlage dieser Kriterien würde ich die folgenden beiden Ergebnissätze erwarten nur, das heißt:

01/04/2012 1234567 
01/04/2012 2222222 

Hoffentlich kann jemand mit einer Oracle SQL-Abfrage helfen, die diese Ergebnismenge basierend auf den beschriebenen Kriterien zurückgibt.

Entschuldigung, ich hätte auch darauf hingewiesen werden müssen, dass ich diese SQL-Abfrage als eine Unterabfrage aus dem Haupt-SELECT verwenden muss.

Danke.

+0

Ihre Frage enthält die Antwort ... wenn Sie verschiedene Datensätze bestimmte Funktion verwenden. ..für ein Beispiel Wählen Sie distinct von der Tabelle wo ..... –

+0

Verstehen Sie, was Sie sagen, aber ich war nicht sicher, wie man die Aufzeichnungen herauszieht, in denen das Attribut APPLE und PINEAP war PLE. – tonyf

+0

Sie können IN-Funktion verwenden .. oder UNION..Wählen Sie ein anderes Datum, emp_no von (wählen Sie * aus der Tabelle, wo Attribut = Apfel Union * aus Tabelle auswählen, wo Attribut = Apfel) .... –

Antwort

2

versuchen

SELECT DISTINCT A.Date, A.Emp_no 
FROM (SELECT * FROM MY_ATTRIBUTES WHERE ATTRIBUTE = 'APPLE') A 
INNER JOIN (SELECT * FROM MY_ATTRIBUTES WHERE ATTRIBUTE = 'PINEAPPLE') B ON B.Date = A.Date AND B.Emp_No = A.Emp_No 
2

Es kann ein effizienter Weg sein, aber dies sollte funktionieren: (Bsp. 2 Äpfel am selben Tag und emp)

SELECT DISTINCT DATE, EMP_NO 
FROM (
    SELECT DATE, EMP_NO 
    FROM MY_ATTRIBUTES 
    WHERE ATTRIBUTE = 'APPLE' 
    INTERSECT 
    SELECT DATE, EMP_NO 
    FROM MY_ATTRIBUTES 
    WHERE ATTRIBUTE = 'PINEAPPLE' 
); 
+0

das alles funktioniert gut, aber ich bin jetzt Auf diese Weise ein Leistungsproblem finden - irgendwelche Ideen, wie man die Abfrage beschleunigt/abstimmt? – tonyf

+1

INTERSECT sollte eine Reihe eindeutiger Kombinationen bereitstellen, sodass die DISTINCT-Klausel nicht erforderlich ist, die eine zusätzliche Sortierung erfordert. – APC

+0

@APC guten Fang (Abstimmungspunkt), aber ich denke, dass neue Oracle-Optimierer es wissen, und die Sortierung nicht zweimal tun wird. Ich habe keine Zeit, es zu testen ... –

2

Wenn es keine Duplikate dieser könnte effizienter sein, da es keine Joins:

SELECT DATE, EMP_NO 
FROM MY_ATTRIBUTES 
WHERE ATTRIBUTE = 'APPLE' OR ATTRIBUTE = 'PINEAPPLE' 
GROUP BY DATE, EMP_NO 
HAVING COUNT(*) = 2 
+0

danke Barsju, aber ich benutze diese Abfrage Anforderung als Teil einer Unterabfrage und leider nicht in der Lage, GROUP BY in einer Unterabfrage zu verwenden. Würden Sie es zu schätzen, wenn es eine Problemumgehung gab, wenn als Unterabfrage verwendet? Vielen Dank. – tonyf

+0

Nun, muss es eine Unterabfrage sein? Vielleicht sollten Sie die gesamte Abfrage veröffentlichen, damit wir stattdessen einen Fehler machen können. – barsju

-1
SELECT DISTINCT DATE, EMP_NO 
WHERE ATTRIBUTE IN('APPLE','PINEAPPLE') 
+0

Dies wird ein Ergebnis liefern, wo die Kombination DATE, EMP_NO mit einem der beiden Attribute übereinstimmt. Das OP benötigt nur Kombinationen, die für beide Datensätze enthalten. – APC

-1
SELECT DISTINCT Emp_No, Date 
FROM (
    SELECT * 
    FROM MY_ATTRIBUTES m 
    WHERE m.Attribute IN ('Apple','Pineapple') 
) 
LIMIT 2 
ORDER BY Emp_No 
+0

Dies liefert ein Ergebnis, bei dem die Kombination DATE, EMP_NO mit einem der beiden Attribute übereinstimmt. Das OP benötigt nur Kombinationen, die für beide Datensätze enthalten. Außerdem ist LIMIT keine Oracle-Syntax, aber selbst wenn dies der Fall wäre, würde dies nicht den richtigen Effekt erzeugen. – APC

2

Eine Variante zu einem Thema:

with cte as 
(select date, empno, attribute 
    from my_attributes 
    where attribute in ('PINEAPPLE', 'APPLE')) 
select * 
from ( select date, emp_no 
     from cte 
     where attribute = 'PINEAPPLE' 
     intersect 
     select date, emp_no 
     from cte 
     where attribute = 'APPLE') 

Die Leistung jeder dieser Lösungen auf die Selektivität von ATTRIBUTE abhängen. Wenn Sie nur ein halbes Dutzend Früchte in Ihrer Schüssel haben, sehen Sie sich einen vollen Tisch an, und es gibt nur begrenzte Möglichkeiten, diese zu tunen. Auf der anderen Seite, wenn die Spalte ist ein Gemüsehändler ist voll von fruchtigen Köstlichkeiten (sagen 150+ verschiedene Werte), dann sollten Sie die Rückkehr von einem Index. Aber das hängt immer noch von Verteilung und Skew ab: Wenn ATTRIBUTE zu 90% aus Äpfeln und Ananas besteht, sehen Sie möglicherweise keinen Nutzen aus einem Index: In diesem Fall ist ein vollständiger Tabellenscan immer noch die bessere Option.

tl; dr

Tuning ist schwer

0

Sie können versuchen, die folgenden:

SELECT DATE, EMP_NO FROM YOUR_TABLE WHERE ATTRIBUTE = 'APPLE' OR ATTRIBUTE = 'PINEAPPLE' GROUP BY DATE, EMP_NO HAVING COUNT(*) = 2;

+0

dies ist bereits beantwortet. –

+0

@FlorinGhita Antwort ist eine kann es anders sein als die tatsächliche Antwort? Ja, Sie können es anders schreiben – harry

+0

Ich verstehe nicht, was Sie sagen. Ihre Antwort ist die gleiche wie bei Barsju. Er hat bereits gesagt, was in deiner Antwort ist (4 Stunden vor dir), außer der Formatierung. Es ist nicht nützlich, zwei Antworten mit der gleichen Sache zu haben. –