2012-10-31 11 views
5

Muszę więc powiedzieć, że SQL jest moją najsłabszą stroną jako programisty. Być może to, co próbuję osiągnąć, jest dość łatwe. Mam coś takiego (To nie jest prawdziwy model, ale aby uczynić go prostym do zrozumienia bez marnowania zbyt wiele czasu na jego wyjaśnienie, wymyśliłem przykład, który naśladuje dokładnie stosunki tabel, których muszę użyć). Z jednej strony stół, nazwijmy go "Użytkownicy". Kolumny, takie jak klucz podstawowy "UserId", "UserName" i tak dalej.Wybierz opcję Distinct w filtrowaniu sprzężeń wewnętrznych przy użyciu wielu wartości w jednej kolumnie?

Następnie inna tabela "Licencje". Relacja 1: N z użytkownikiem, każda licencja należy do jednego użytkownika, użytkownik może mieć wiele licencji. Tak więc mielibyśmy PK IdLicense, FK IdUser i tak dalej.

Następnie tabela o nazwie "Urządzenia". tutaj zdefiniowaliśmy różne urządzenia. IdEquipment, EquipmentName. Niewiele więcej do powiedzenia na ten temat.

Wreszcie tabela, która tworzy relację N: M między "Licencjami" a "Urządzeniami". gdy użytkownik definiuje licencję, może określić różne urządzenia, na które licencja pozwala im manipulować. Tak więc licencja może odnosić się do kilku urządzeń, a część sprzętu może odnosić się do wielu licencji.

Prawdziwa oferta jest tutaj. Kazano mi wdrożyć jakiś system wyszukiwania, który pozwala na pozyskanie użytkowników w oparciu o sprzęt, który kwalifikują się do obsługi. Możliwe jest dokonanie wielokrotnego wyboru, aby wyszukać użytkowników, którzy są wykwalifikowani do obsługi sprzętu "A "," B "i" C ". Na przykład mamy 2 użytkowników, Jamesa i Dave'a. James ma 2 licencje, a Dave ma. James ma kwalifikacje do używania maszyn "A" i "D" na swojej pierwszej licencji, "B" i "C" na drugiej. Dave kwalifikuje się do obsługi sprzętu typu "B" i "C" na swojej jedynej licencji. Jeśli ktoś spróbuje wyszukać użytkowników w stanie obsłużyć sprzęt "A", "B" I "C", tylko James będzie rekordem powracającym.

tej pory przyjęto chciałbym zrobić coś podobnego

SELECT DISTINCT IdUser 
FROM Users 
INNER JOIN Licenses 
    ON Licenses.IdUser = Users.idUser 
INNER JOIN LicensesEquipments 
    ON LicensesEquipments.IdLicense = Licenses.IdLicense 
INNER JOIN Equipment 
    ON Equipment.IdEquipment = LicensesEquipments.IdEquipment 

WHERE Equipment.IdEquipment = ?? 

Jak można filtrować to na wszystkich 3 różnych idEquipments dla "A" "B" i "C".? Oczywiście, nie mogę wykonać GDZIE Equipment.IdEquipment = 1 i Equipment.IdEquipment = 2, ponieważ komórka nie może być równa 2 różnym wartościom. Nie mogę ani zrobić GDZIE Equipment.IdEquipment = 1 lub Equipment.IdEquipment = 2, ponieważ użycie OR oznaczałoby, że każdy użytkownik posiadający co najmniej JEDEN z możliwości byłby uważany za prawidłowy wynik, i szukam takiego, który ma WSZYSTKIE 3 różne urządzenia w tej sprawie.

Najpierw założyłem, że będę musiał utworzyć wiele wewnętrznych sprzężeń ze sprzętem stołowym, używając aliasu, robiąc to tyle razy, co filtry na sprzęcie, które posiadam, i używając każdego aliasu z innym filtrem. Ale wtedy mój kod kierownik przyszedł i powiedział mi o tym zapomnieć, ponieważ powiedział, że spowodowałoby zbyt kosztowne, ponieważ coraz więcej filtrów, gdzie dodatkiem (choć nie dał mi lepszą alternatywę ...)

Odpowiedz

4
SELECT Users.idUser 
FROM Users 
INNER JOIN Licenses ON Licenses.IdUser = Users.idUser 
INNER JOIN LicensesEquipments ON LicensesEquipments.IdLicense = Licenses.IdLicense 
INNER JOIN Equipment ON Equipment.IdEquipment = LicensesEquipments.IdEquipment 
WHERE Equipment.IdEquipment IN ('A', 'B', 'C') 
GROUP BY IdUser 
HAVING COUNT(DISTINCT Equipment.IdEquipment) = 3 <--must be # of unique items in IN clause 

Jeśli naprawdę wystarczy identyfikator użytkownika, można upuścić Users i Licenses tabel z zapytanie:

SELECT Licenses.IdUser 
FROM Licenses 
INNER JOIN LicensesEquipments ON LicensesEquipments.IdLicense = Licenses.IdLicense 
WHERE LicensesEquipments.IdEquipment in ('A', 'B', 'C') 
GROUP BY Licenses.IdUser 
HAVING COUNT(DISTINCT LicensesEquipments.IdEquipment) = 3 

również niektóre aliasy sprawia, że ​​łatwiejsze do odczytania:

SELECT l.IdUser 
FROM Licenses l 
INNER JOIN LicensesEquipments le ON le.IdLicense = l.IdLicense 
WHERE le.IdEquipment in ('A', 'B', 'C') 
GROUP BY l.IdUser 
HAVING COUNT(DISTINCT le.IdEquipment) = 3 
+0

Dzięki, ale czy nie powróciłoby to do użytkowników posiadających 3 urządzenia, nieważne, kim są, o ile jeden z nich to "A", "B", "C" ?.Na przykład, ktoś może obsługiwać "A" "F" i "T". Ta osoba byłaby wśród wyników, ale chcę tych, którzy potrafią obsłużyć "A" "B" "C". JEŚLI mogą one również obsługiwać więcej rzeczy jest ok, ale MUSZĄ być w stanie obsłużyć wszystkie zawarte w filtrze, nie tylko jeden z nich ... – Hobbes

+0

ok, zapomnij, nie miałem jeszcze mojej porannej kawy, lol. wielkie dzięki! – Hobbes

0
SELECT l.IdUser 
FROM Licenses l 
INNER JOIN LicensesEquipments le ON le.IdLicense = l.IdLicense 
WHERE le.IdEquipment in (`enter code here`'A', 'B', 'C') 
GROUP BY l.IdUser 
HAVING COUNT(DISTINCT le.IdEquipment) = 3 
Powiązane problemy