2012-03-16 14 views
48

Moje zapytanie brzmi:MySQL gdzie w()

SELECT * FROM table WHERE id IN (1,2,3,4);

Używam go do grupy użytkowników, a użytkownik może mieć więcej niż jednej grupy. ale wydaje się, że gdy rekord ma wiele id takich jak 1 i 3, mySQL nie zwraca tego wiersza.

Czy istnieje sposób na uzyskanie tego wiersza też?

+6

Proszę podać przykład wierszy, które nie zwracają prawidłowo z tego zapytania. Zakładając, że nie przechowujesz "id" jako listy rozdzielanej przecinkami lub czegoś takiego, wiele wierszy _will_ zwróci z zapytania. –

+1

cóż, jest to oddzielna przecinka lista, na przykład => 3,4 nie zostanie zwrócone przez mySQL. Widzę problem, chodzi o przecinek, ale jak mogłem to zrobić? – netcase

+0

@ user762683, Proszę użyć poprawnej nazwy profilu? i jaki jest typ danych tego 'id', varchar lub set lub enum? – Starx

Odpowiedz

52

Zapytanie przekłada się

SELECT * FROM table WHERE id='1' or id='2' or id='3' or id='4'; 

Powróci tylko wyniki, które nie pasują do siebie.


Jednym ze sposobów rozwiązania tego uniknąć złożoności byłoby chaning typ danych do SET. Następnie można użyć, FIND_IN_SET

SELECT * FROM table WHERE FIND_IN_SET('1', id); 
+0

Nie można odtworzyć żadnego błędu. Żądane zapytanie działa dla mnie. Dostaję WSZYSTKIE rekordy z "tabeli" z wymienionymi identyfikatorami. –

22

Masz zły projekt bazy danych i należy wziąć czas na przeczytanie czegoś o normalizacji baz danych (wikipedia/stackoverflow).

I zakładamy, że stół wygląda nieco jak to

TABLE 
================================ 
| group_id | user_ids | name | 
-------------------------------- 
| 1  | 1,4,6 | group1 | 
-------------------------------- 
| 2  | 4,5,1 | group2 |  

tego w spisie grup użytkowników, każdy wiersz reprezentuje jedną grupę i user_ids kolumnie ustawiono identyfikatorów użytkowników przypisanych do tej grupy.

Znormalizowany wersja tej tabeli będzie wyglądać następująco

GROUP 
===================== 
| id  | name | 
--------------------- 
| 1  | group1 | 
--------------------- 
| 2  | group2 |  

GROUP_USER_ASSIGNMENT 
====================== 
| group_id | user_id | 
---------------------- 
| 1  | 1  | 
---------------------- 
| 1  | 4  | 
---------------------- 
| 1  | 6  | 
---------------------- 
| 2  | 4  | 
---------------------- 
| ...  

Następnie można łatwo wybrać wszystkie użytkownikom przypisanym grupie lub wszystkich użytkowników w grupie lub wszystkich grup użytkowników, czy cokolwiek można myśleć z. Również zapytanie SQL będzie działać:

/* Your query to select assignments */ 
SELECT * FROM `group_user_assignment` WHERE user_id IN (1,2,3,4); 

/* Select only some users */ 
SELECT * FROM `group_user_assignment` t1 
JOIN `group` t2 ON t2.id = t1.group_id 
WHERE user_id IN (1,4); 

/* Select all groups of user */ 
SELECT * FROM `group_user_assignment` t1 
JOIN `group` t2 ON t2.id = t1.group_id 
WHERE t1.`user_id` = 1; 

/* Select all users of group */ 
SELECT * FROM `group_user_assignment` t1 
JOIN `group` t2 ON t2.id = t1.group_id 
WHERE t1.`group_id` = 1; 

/* Count number of groups user is in */ 
SELECT COUNT(*) AS `groups_count` FROM `group_user_assignment` WHERE `user_id` = 1; 

/* Count number of users in group */ 
SELECT COUNT(*) AS `users_count` FROM `group_user_assignment` WHERE `group_id` = 1; 

ten sposób będzie również łatwiejsze do aktualizacji bazy danych, jeśli chcesz dodać nowe zadanie, po prostu wystarczy wstawić nowy wiersz w group_user_assignment, gdy chcesz usunąć przypisanie po prostu usuwasz wiersz w group_user_assignment.

W projekcie bazy danych, aby zaktualizować przypisania, należy pobrać zestaw przydziałów z bazy danych, przetworzyć go i zaktualizować, a następnie zapisać w bazie danych.

Oto sqlFiddle do zabawy.