2016-12-07 2 views
0

Ich wollte Klarheit darüber, wie die HAVING-Komponente in einer SQL-Anweisung, insbesondere mit einer SQL-Anweisung, die mehrere Joins hat. Betrachten Sie die folgende SQL-Select-Anweisung:Question über die Verwendung von HAVING in ACCESS SQL

SELECT 
    p.id, 
    p.first_name as [First Name], 
    p.last_name as [Last Name] 
FROM 
    ([tbl_person] as p 
INNER JOIN [tbl_person_languages] as pl 
    ON [p].[id] = [pl].[person_id]) 
INNER JOIN [tbl_person_crossCuttingSkills] As ccp 
    ON [p].[id] = [ccp].[person_id] 
WHERE 
    cint(pl.language_id) in (12,14) AND 
    cint(ccp.skill_id) in (55) 
GROUP BY 
    p.id, 
    p.first_name, 
    p.last_name 
HAVING 
    count(pl.language_id) =2 AND 
    count(ccp.skill_id) = 1 

Ich möchte Aufzeichnungen ziehen, aus tbl_person, wo ein Datensatz alle der WHERE Anforderungen. Zum Beispiel: Ich möchte alle Benutzer auswählen, in denen sie eine Sprache Italienisch (mit ID 12) und Spanisch (ID 15) sprechen UND eine Kochkünste haben (55). Sie müssen alle Anforderungen haben, nicht nur eine oder mehrere. Ich war unter der Annahme, das ist, wo Sie GROUP BY und HAVING verwenden würden. Mit dem MIT:

count(pl.language_id) =2 

verwende ich count = 2, da gibt es zwei Möglichkeiten in der Sprache WHERE-Klausel (12 und 14)

Und ich

count(ccp.skill_id) = 1 

Da ein Wert ist in der WHERE-Klausel (55).

Ist dies der richtige Weg, dies zu tun? Aus irgendeinem Grund gibt dies keine Datensätze zurück (ich habe einen Datensatz in meiner Datenbank von einer Person, die genau diese Anforderungen erfüllt). Aber wenn ich meine ändern zu müssen:

count(pl.language_id) =2 AND 
count(ccp.skill_id) = 2 

Es funktioniert gut. Warum ist das? Sind meine Annahmen, wie das funktioniert, falsch oder gibt es etwas anderes?

+0

Es bedeutet, dass keine Person mit dem gleichen, ID, Vornamen und Nachnamen 2 Sprachen und 1 Fähigkeit hat. Es kann Fälle geben, in denen 2 Sprachen und 2 Fähigkeiten wie du erwähnt wurden. Wie viele Sprachen/Fähigkeiten sehen Sie angesichts Ihrer Wo-Klausel? Ist es möglich, eine kleine Datenmenge bereitzustellen? – Reisclef

Antwort

1

Denken Sie daran, was count() tut. . . Es zählt Nicht-NULL-Werte. Also zählen Sie zwei Nicht-NULL-Werte, dann sind die Zählungen gleich.

In den meisten Dialekten von SQL können Sie dieses Problem beheben, indem Sie:

HAVING count(distinct pl.language_id) = 2 AND count(distinct ccp.skill_id) = 1 

Aber das funktioniert nicht in MS Access, da MS Access nicht COUNT(DISTINCT) nicht unterstützt.

So können Sie ausführlicher sein. In Ihrem Fall:

HAVING SUM(iif(cint(pl.language_id) = 12, 1, 0)) > 0 AND 
     SUM(iif(cint(pl.language_id) = 14, 1, 0)) > 0 AND 
     SUM(iif(cint(ccp.skill_id) = 55, 1, 0)) > 0 

Es tut mir leid diese HAVING Klausel ist nicht einfacher. Sie könnte wechseln zu einer anderen Datenbank (wie SQL Server Express), die enger mit ANSI-Funktionalität ausgerichtet ist.

+0

Es gibt keine Chance, dass dieselbe Person mehr als einmal dieselbe Sprache oder Fähigkeit hat. Ich verstehe immer noch nicht, warum das nicht funktioniert. Ich habe eine Person mit diesen beiden lanaguate IDs und Skill ID, aber es gibt immer noch einen leeren Datensatz zurück – jason

+0

Das ist, weil 'count (ccp.skill_id)' 2 zurückgibt, wenn zwei Zeilen alle anderen Bedingungen übereinstimmen. –

+0

gibt es eine Möglichkeit, dies in meinem SQL zu berücksichtigen? Oder ist es am besten, dies über Code zu tun? Unglücklicherweise ist Access unsere einzige Option. – jason