2016-05-26 4 views
2

ich eine Tabelle (mit mehreren Zeilen), dass, um die Dinge zu vereinfachen, lassen Sie uns wie folgt betrachten:Auswahl nach Wertepaar

Table: data 
+---+--------+-------+-----+---------+ 
|id | name |objId |src | type | 
+---+--------+-------+-----+---------+ 

In dieser Tabelle ther mehrere Einträge für die gleiche name sein kann Allerdings sollte nur einer den Typ descriptor haben. Der Typ mit dem Typ descriptor gibt die Standardquelle in der Spalte src an.

Ich möchte eine Abfrage wo, wenn ich weiß, die Standard-src für jeden Namen, um die Einträge aus der data Tabelle, die diese src haben.

Eine Lösung wäre so etwas wie diese: SELECT * FROM data WHERE (objId=<id1> AND type=<dflt1>) OR (objId=<id2> AND type=<dflt2>) OR ... OR (objId=<idN> AND type=<dfltN>) AND type<>descriptor

aber ich würde gerne wissen, ob es ein einfacherer ist (schneller) Weg, dies zu tun.

example: 
+---+--------+-------+-----+----------+ 
|id | name |objId |src | type  | 
+---+--------+-------+-----+----------+ 
|1 | file1 | 1  | srv |descriptor| 
+---+--------+-------+-----+----------+ 
|2 | file 1 | 1  | srv |data  | 
+---+--------+-------+-----+----------+ 
|3 | file 1 | 1  | srv |data  | 
+---+--------+-------+-----+----------+ 
|4 | file 1 | 1  | lcl |data  | 
+---+--------+-------+-----+----------+ 
|5 | file 2 | 2  | lcl |descriptor| 
+---+--------+-------+-----+----------+ 
|6 | file 2 | 2  | srv |data  | 
+---+--------+-------+-----+----------+ 
|7 | file 2 | 2  | lcl |data  | 
+---+--------+-------+-----+----------+ 

Query should return entries with IDs: 2, 3, 7 

Danke.

Antwort

0

Eine Lösung ist eine Unterabfrage zu verwenden, um die Datensätze zu beschränken in data nur für diejenigen, deren Wert src dem Wert src im Deskriptorsatz für jede Objektgruppe entspricht:

SELECT t1.* 
FROM data t1 
INNER JOIN 
(
    SELECT objId, src 
    FROM data 
    WHERE type = 'descriptor' 
) t2 
    ON t1.src = t2.src AND t1.objId = t2.objId AND t1.type != 'descriptor' 

Folgen Sie dem Link unten für eine laufende Demo:

SQLFiddle

0
SELECT * FROM data 
    WHERE (objId,type) in (select objid,type from data where type<>'descriptor') 

hinzufügen alle Kombinationen von id und DFLT in "in" -Klausel

0

Etwas wie folgt aus:

SELECT t2.* 
FROM mytable AS t1 
JOIN mytable AS t2 ON t1.objId = t2.objId AND t1.id <> t2.id AND t1.src = t2.src 
WHERE t1.type = 'descriptor' 

Demo here

0

Betrachten Sie Ihre Tabellen zu normalisieren und nie wieder so Probleme haben.

Tabelle objects:

| objId | name | defaultSrc | 
|-------|--------|------------| 
|  1 | file 1 |  srv | 
|  2 | file 2 |  lcl | 

Tabelle data:

| id | objId | src | 
|----|-------|-----| 
| 2 |  1 | srv | 
| 3 |  1 | srv | 
| 4 |  1 | lcl | 
| 6 |  2 | srv | 
| 7 |  2 | lcl | 

Dann yor Abfrage wäre:

select o.name, d.* 
from objects o 
join data d 
    on d.objId = o.objId 
    and d.src = o.defaultSrc; 

Ergebnis:

| name | id | objId | src | 
|--------|----|-------|-----| 
| file 1 | 2 |  1 | srv | 
| file 1 | 3 |  1 | srv | 
| file 2 | 7 |  2 | lcl | 

sqlfiddle

Auf diese Weise können nicht nur einfachere Anfragen haben, aber auch Festplatte/Speicherraum und (wichtiger) sparen weniger IO. Durch das Hinzufügen von korrekten Fremdschlüsseln können Sie die Datenintegrität sicherstellen.