PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : SQL Proble/Frage


TheGamer
2011-12-16, 16:48:04
Hallo,

ich habe eine MSSQL Datenbank folgendermassen befuellt (reduziert auf das noetigste).


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 3
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 4
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA a
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA b
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 1
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 2


Ich brauche nun alle FileIds bei denen der Value 1 UND 2 ist.

Ich weiss das ein Satz natuerlich nur einen Wert in Value haben kann.

Im Beispiel waere das


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1


und


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2


Ich moechte das gerne in einem einzigen Select haben. Dann weiss ich schonmal die FileId naemlich FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5

Dann moechte ich aber noch einen Select haben wie SELECT * FROM table WHERE FileId = 'FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5'

Dann bekomme ich


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 3
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 4


Und genau das brauche ich.

Das ganze ist aber natuerlich langsam. Weil das 3 Selects sind. Ich versuche das irgendwie in einen einzigen Select unterzubringen. Vielleicht ist auch der Grundsaetzliche Ansatz falsch.

Anderes Beispiel. Ich suche nach Value 1 UND 2 UND a dann muss das Ergebnis des Queries wie folgt ausschauen


FileId Value
===================================================
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA a
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA b
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 1
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 2


Noch ein Beispiel. Ich suche nach Value 1 UND 2 dann muss das Ergebnis des Queries wie folgt ausschauen


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 3
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 4
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA a
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA b
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 1
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 2


Noch ein Beispiel. Ich suche nach Value 1 dann muss das Ergebnis des Queries wie folgt ausschauen


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 3
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 4
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA a
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA b
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 1
65565E6E-BDD9-4C9E-B26D-9C411FE99CEA 2


Noch ein Beispiel. Ich suche nach Value 4 dann muss das Ergebnis des Queries wie folgt ausschauen


FileId Value
===================================================
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 1
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 2
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 3
FB1C52B7-CBF5-43E2-83F5-FEF41D7BEFB5 4


Das Design der Tabelle kann ich nicht aendern.

Gast
2011-12-16, 18:30:09
Vielleicht klappts mit einer Subquery?

SELECT FileId, Value
FROM table
WHERE FileId IN (SELECT FileId
FROM table
WHERE Value= '[selectedvalue]');

TheGamer
2011-12-16, 18:39:40
Vielleicht klappts mit einer Subquery?

SELECT FileId, Value
FROM table
WHERE FileId IN (SELECT FileId
FROM table
WHERE Value= '[selectedvalue]');

Nein weil das Subquery bei mir mehrfach Saetze liefern kann. Ein Subquery funktioniert ja nur bei einem Resultsatz.

Zur Info. Ich habe den Eingangstext umgeschrieben und mit mehr Beispielen versehen. Hoffe es ist verstaendlicher geworden.

Gast von oben
2011-12-16, 18:57:55
Dann in der Subquery einfach auch IN benutzen:

SELECT FileId, Value
FROM table
WHERE FileId IN (SELECT FileId
FROM table
WHERE Value IN (beliebigvielewertedurchkommagetrennt)');

gereggter Gast
2011-12-16, 23:48:04
Dann in der Subquery einfach auch IN benutzen:

SELECT FileId, Value
FROM table
WHERE FileId IN (SELECT FileId
FROM table
WHERE Value IN (beliebigvielewertedurchkommagetrennt)');
Und das funktioniert so wie du erwartest? :uponder:

BadCop
2011-12-17, 01:52:46
ob du das in 3 oder eine verschachtelte abfrage packst, wird dein performance-problem nicht wirklich lösen, dafür ist deine zugriffsart auf die daten viel zu schlecht bzw garnicht für schnelle db-anfragen ausgelegt.
probieren kannst du folgendes, um es mit einer query zu lösen:
group_concat auf value mit group nach fileid und where IN für deine suchparameter, das group_concat vergleichste mit concat deiner suchparameter und davon das ergebnis in eine select * query übergeben, bzw da als subquery.

Mr_Karlo
2011-12-17, 13:58:12
Ich finde den Ansatz mit dem Subquery schon OK. Aufgrund der ungünstigen Datenbankstruktur ist das eigentliche Problem, dass man im Subquery die Parameter weder mit AND noch mit OR oder IN angeben kann.
AND funktioniert in diesem Zusammenhang ohnehin nicht. OR und IN geben auch die Datensätze zurück die nur einem Suchkriterium entsprechen.

Wenn man zusätzlich zu den Suchkriterien noch die Anzahl der jeweils notwendigen Suchkriterien angibt funktioniert das mit folgenden Workaround-SQL-Statement.

z.B. Suchkriterien 1,2,a. Anzahl der Kriterien somit 3:

SELECT * FROM [table]
WHERE
FileID IN (
SELECT FileID FROM
(
SELECT FileId, COUNT(FileId) AS c FROM [table]
WHERE
Value IN ('1','2','a')
GROUP BY FileId)AS tbl
WHERE c = 3)


Imo funktioniert das mit allen von Dir angegebenen Beispielen. Ob das jetzt performant ist oder ob man das Problem besser in der Programmlogik löst ist wieder eine andere Geschichte. Wenn die Tabelle nicht zu groß ist wird es egal sein.