"Christmas - the time to fix the computers of your loved ones" « Lord Wyrm

[SQL] Select ... where x in all ()

Mr. Zet 10.07.2007 - 17:47 2454 12
Posts

Mr. Zet

Super Moderator
resident spacenerd
Avatar
Registered: Oct 2000
Location: Edge of Tomorrow
Posts: 12040
Hallo allerseits, ich habe folgendes Problem mit einem SQL Query:

Datenbank: HSQLDB

tabelle NodesToTags sieht etwa so aus:
Code:
NodesToTags
----------------
NodeId | TagId
----------------
0      | 0
0      | 1
0      | 3
0      | 4
7      | 3
7      | 4
7      | 22
...etc

jetzt will ich davon alle selektieren, die 1 bis n tagIds gemeinsam haben
also zum beispiel habe ich die tags mit id 1 und id 4 also sollte ich nur nodeid 0 bekommen, weil nur dieser node mit beiden tags assoziiert ist.

watchout hätte folgende lösung dafür, die ähem etwas komplex ist :D
außerdem in unserer anwendung wäre das ganze auch noch ein subquery eines komplexeren querys, was die sache dann total unübersichtlich macht :(

Code:
SELECT cnt.nodeid
FROM nodestotags
LEFT OUTER JOIN
  (SELECT count(*) as cn, nodeid
   FROM nodestotags
   WHERE TagId IN(0,4)
   GROUP BY nodeid) as cnt
ON (cnt.nodeid=nodestotags.nodeid)
WHERE
 TagId IN(6,14,19) AND
 cn = (SELECT count(*)
       FROM (SELECT DISTINCT tagid
             FROM nodestotags
             WHERE tagid IN(0,4)))
GROUP BY cnt.nodeid


daher: alternativen wären sehr hilfreich.

Danke im voraus, Zet & watchout



EDIT: falls jemand den (langen) post vor dem edit gelesen hat: sorry ich hab den bullshit gelöscht der gar keinen sinn ergeben kann :rolleyes:
bin manchmal etwas langsam von begriff ;)
Bearbeitet von Mr. Zet am 10.07.2007, 19:24

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
hmm, werds vielleicht später genauer ansehen, aber müsst das nicht mit "having" gehen.

Mr. Zet

Super Moderator
resident spacenerd
Avatar
Registered: Oct 2000
Location: Edge of Tomorrow
Posts: 12040
also ica du hattest ein ähnliches problem hier:
http://www.overclockers.at/include_...ighlight=select

aber bei uns kann die liste eben (leider) beliebig lang werden und ist nicht auf 2 gemeinsamkeiten beschränkt.

das zugrundeliegende problem: IN ist eine oder verknüpfung.
wir bräuchten aber eben eine UND verknüpfung für alle elemente einer liste.
was aber aufgrund der tupelorientierung von sql ja gar nicht gehen kann so wie ich das sehe.

einzige alternative: aufgrund der liste den query komplett dynamisch aufbauen im Programmcode.
Aber das muss doch auch in sql irgendwie "einfach" zu realisieren sein.
Bearbeitet von Mr. Zet am 10.07.2007, 18:03

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
achso ich hab das glaub ich falsch verstanden. versteh ich das jetzt richtig, dass du 2 tagids gegeben hast und damit in diese join-tabelle gehst und nodes suchst die zu diesen beiden tags gehören?

kleinerChemiker

Here to stay
Avatar
Registered: Feb 2002
Location: Wien
Posts: 4281
eine idee:

SELECT nodeid, count() as count FROM table GROUP by nodeid Where id in () AND count =<anzahl der gewünschten nodeids>

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
wenn dann so

SELECT *, count(tagid) as counter FROM nodestotags WHERE tagid in (1,4) GROUP by nodeid HAVING counter > 1

kleinerChemiker

Here to stay
Avatar
Registered: Feb 2002
Location: Wien
Posts: 4281
ja, so auswendig kenn ich die genaue syntaxordnung nicht.

aber, nicht counter > 1 sondern counter=<anzahl der gewünschten tagid's> also in unserem fall counter=2

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
jo gut, dachte es geht immer um 2 und > 1 ist nunmal auch 2 :)

Mr. Zet

Super Moderator
resident spacenerd
Avatar
Registered: Oct 2000
Location: Edge of Tomorrow
Posts: 12040
@ ica, kleinerChemiker
also
SELECT *, count(tagid) as counter FROM nodestotags WHERE tagid in (1,4) GROUP by nodeid HAVING counter = 2;

geht mal gar nicht, weil man nichts selektieren kann, was nicht in der group by clause ist.

SELECT nodeid, count(tagid) as counter FROM nodestotags WHERE tagid in (1,4) GROUP by nodeid HAVING counter = 2;
liefert:
java.sql.SQLException:
NULL value as BOOLEAN / Error Code: -106 / State: S1000

Mr. Zet

Super Moderator
resident spacenerd
Avatar
Registered: Oct 2000
Location: Edge of Tomorrow
Posts: 12040
ok lösung:

HSQLDB kann KEINE alias für funktionsergebnisse und/oder in der having clause... ->

SELECT nodeid, count(tagid) FROM nodestotags WHERE tagid in (1,4) GROUP by nodeid HAVING [/b]count(tagid)[/b] = 2;


-> SOLVED

Danke für die antworten :)
Bearbeitet von Mr. Zet am 10.07.2007, 19:30

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
mit mysql gehts :)

zu hsqldb kann ich nichts sagen weil ichs noch nie gehört hab.

Mr. Zet

Super Moderator
resident spacenerd
Avatar
Registered: Oct 2000
Location: Edge of Tomorrow
Posts: 12040
http://www.hsqldb.org/

ist ganz nett für kleinere Projekte, weil es in-memory in der runtime der application laufen kann -> User braucht keine stand-alone Datenbank aufsetzen.

geht auch im Server-Mode für größere Projekte aber dazu kann ich nicht viel sagen.

ica

hmm
Avatar
Registered: Jul 2002
Location: Graz
Posts: 9818
ah, sowas also. kenne in diesem zusammenhang eigentlich nur sqlite.
Kontakt | Unser Forum | Über overclockers.at | Impressum | Datenschutz