Результаты поиска в нескольких таблицах MYSQL - PullRequest
0 голосов
/ 26 сентября 2011

Привет, у меня есть запрос, который вызывает у меня несколько проблем, и было предложено задать отдельный вопрос о конечном результате, а не о проблеме.

Итак, у меня есть три таблицы и некоторые пользовательские данные.

таблицы:

  • пользователи,
  • usersLanguages ​​и
  • usersSkills

каждая таблица имеет связанный идентификатортаблица пользователей имеет идентификатор, а в двух других они имеют идентификатор пользователя для сопоставления навыков и языков пользователям

пользовательский ввод динамический, но, например, он может быть 1 для usersLanguages ​​и 2 для usersSkills

Пользовательский ввод берется из формы, и мне нужно сопоставить результаты поиска пользователей в зависимости от идентификаторов языков или идентификаторов навыков, которые были пройдены.например, я могу передать два идентификатора пользователя и три идентификатора языка.

SELECT DISTINCT users.ID, users.name
FROM users 
INNER JOIN usersSkills 
ON users.ID = usersSkills.userID 
INNER JOIN usersLanguages ON users.ID = usersLanguages.userID 
WHERE activated = "1" 
      AND type = "GRADUATE" AND usersSkills.skillID IN(2) 
      AND usersLanguages.languageID IN(2)
GROUP BY usersSkills.userID HAVING COUNT(*) = 1,
         usersLanguages.userID HAVING COUNT(*) = 1 

Ответы [ 3 ]

1 голос
/ 26 сентября 2011

что-то вроде

SELECT * from users left join usersLanguage on users.id=usersLanguage.userID 
left join usersSkills on usersSkills.userID=users.id 
where usersLanguage.id in (1, 2, 3) and usersSkills.id in (1, 2, 3)
GROUP BY users.id

, вероятно, будет работать

1 голос
/ 12 мая 2012

попробуйте

SELECT users.ID,user.name
FROM users 
INNER JOIN usersSkills ON users.ID = usersSkills.userId
INNER JOIN AND usersLanguages ON users.ID = usersLanguages.userID
WHERE activate = '1'
AND type = 'GRADUATE'
AND usersSkill.skillID IN (2)
AND usersLanguages.languageID IN (2)
GROUP BY users.ID
1 голос
/ 26 сентября 2011

Вы не смешиваете group by и having предложения.
наличие не входит в группу by, фактически вы можете иметь having без группы by, в этом случае оно будет работать как более способное (и более медленное) where предложение.

SELECT u.ID, u.name
FROM users u 
INNER JOIN usersSkills us ON u.ID = us.userID 
INNER JOIN al ON u.ID = ul.userID 
WHERE u.activated = '1' 
      AND u.type LIKE 'GRADUATE' AND us.skillID IN('2') 
      AND ul.languageID IN('2')
GROUP BY u.ID
HAVING COUNT(*) = 1
  • из-за критериев соединения, ul.userID = us.userID = u.ID, поэтому нет смысла группировать по обоим. Просто сгруппируйте по u.id, потому что это идентификатор, который вы выбираете в конце концов.
  • u.name функционально зависит от идентификатора, поэтому указывать его не нужно (*) .
  • При выполнении теста, подобного u.type = 'GRADUATE', я предпочитаю делать u.type LIKE 'GRADUATE', поскольку LIKE не учитывает регистр и = может не зависеть от параметров сортировки, но это только я
  • Distinct не требуется; group by уже делает результаты отчетливыми.

Having работает с результирующим набором до * 1033 включительно, поэтому в этом случае вам нужно иметь только одно предложение. Если вы хотите иметь больше, вы должны обращаться с ними так же, как с предложением where:

having count(*) = 1 AND SUM(money) > 10000 

(*) это верно только для MySQL, в других SQL вам нужно перечислить все неагрегированные выбранные столбцы в вашей группе по выражению. Являются ли они функционально зависимыми от группы по столбцу или нет. Это замедляет работу и приводит к очень длинному синтаксису запросов, но предотвращает ошибки некоторых новичков.
Лично мне нравится, как MySQL работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...