Выбор с несколькими условиями WHERE в одном столбце
хорошо, я думаю, что я мог бы упустить что-то очевидное/простое здесь... но мне нужно написать запрос, который возвращает только записи, соответствующие нескольким критериям в одном столбце...
моя таблица-это очень простая настройка ссылок для применения флагов к пользователю ...
ID contactid flag flag_type
-----------------------------------
118 99 Volunteer 1
119 99 Uploaded 2
120 100 Via Import 3
121 100 Volunteer 1
122 100 Uploaded 2
etc... в этом случае вы увидите, что оба контакта 99 и 100 помечены как "волонтер" и "загружены"...
что мне нужно, чтобы быть в состоянии сделать, это вернуть те contactid только что матч несколько критериев, введенных через форму поиска...contactid должен соответствовать всем выбранным флагам... в голове SQL должен выглядеть примерно так:
SELECT contactid
WHERE flag = 'Volunteer'
AND flag = 'Uploaded'...
но... это ничего не возвращает... Что я здесь делаю не так?
11 ответов:
можно использовать
GROUP BY
иHAVING COUNT(*) = _
:SELECT contact_id FROM your_table WHERE flag IN ('Volunteer', 'Uploaded', ...) GROUP BY contact_id HAVING COUNT(*) = 2 -- // must match number in the WHERE flag IN (...) list
(если
contact_id, flag
уникально).или использовать Join:
SELECT T1.contact_id FROM your_table T1 JOIN your_table T2 ON T1.contact_id = T2.contact_id AND T2.flag = 'Uploaded' -- // more joins if necessary WHERE T1.flag = 'Volunteer'
если список флагов очень длинный и есть много совпадений, первый, вероятно, быстрее. Если список флагов короткий и есть несколько совпадений, вы, вероятно, обнаружите, что второй быстрее. Если производительность является проблемой, попробуйте протестировать оба на ваших данных, чтобы увидеть, что работает лучше всего.
использование:
SELECT t.contactid FROM YOUR_TABLE t WHERE flag IN ('Volunteer', 'Uploaded') GROUP BY t.contactid HAVING COUNT(DISTINCT t.flag) = 2
главное, что подсчет
t.flag
необходимо равнять количество аргументов вIN
предложения.использование
COUNT(DISTINCT t.flag)
в случае, если нет уникального ограничения на комбинацию contactid и flag - если нет никаких шансов на дубликаты, вы можете опустить отличное от запроса:SELECT t.contactid FROM YOUR_TABLE t WHERE flag IN ('Volunteer', 'Uploaded') GROUP BY t.contactid HAVING COUNT(t.flag) = 2
рассмотрите возможность использования INTERSECT следующим образом:
SELECT contactid WHERE flag = 'Volunteer' INTERSECT SELECT contactid WHERE flag = 'Uploaded'
Я думаю, что это самое логистическое решение.
Не могу видеть вашу таблицу, но флаг не может быть как "добровольцем", так и "загруженным". Если у вас есть несколько значений в столбце, вы можете использовать
WHERE flag LIKE "%Volunteer%" AND flag LIKE "%UPLOADED%"
не очень применимо, видя отформатированную таблицу.
попробуйте использовать этот альтернативный запрос:
SELECT A.CONTACTID FROM (SELECT CONTACTID FROM TESTTBL WHERE FLAG = 'VOLUNTEER')A , (SELECT CONTACTID FROM TESTTBL WHERE FLAG = 'UPLOADED') B WHERE A.CONTACTID = B.CONTACTID;
изменить и на или. Простая ошибка. Подумайте об этом, как на простом английском языке, я хочу выбрать что-нибудь с тем, что равно тому или этому.
SELECT contactid, Count(*) FROM <YOUR_TABLE> WHERE flag in ('Volunteer','Uploaded') GROUP BY contactid HAVING count(*)>1;
AND
вернет вам ответ только тогда, когда обаvolunteer
иuploaded
присутствуют в вашей колонке. В противном случае он вернетсяnull
значение...попробуйте использовать
OR
в своем заявлении ...SELECT contactid WHERE flag = 'Volunteer' OR flag = 'Uploaded'
иногда вы не можете видеть лес за деревьями :)
ваш исходный SQL ..
SELECT contactid WHERE flag = 'Volunteer' AND flag = 'Uploaded'...
должно быть:
SELECT contactid WHERE flag = 'Volunteer' OR flag = 'Uploaded'...
select purpose.pname,company.cname from purpose Inner Join company on purpose.id=company.id where pname='Fever' and cname='ABC' in ( select mname from medication where mname like 'A%' order by mname );
код :
SELECT contactid WHERE flag = 'Volunteer' AND flag = 'Uploaded' [...]
не будет работать, потому что вы не объявили имя таблицы. при выполнении будет возвращено сообщение об ошибке.
и если вы хотите, чтобы оба запроса поиска отображались, ваш код должен выглядеть примерно так.
SELECT * FROM (your_table_name) WHERE flag = 'Volunteer' OR flag = 'Uploaded';
и не такой, потому что он всегда будет возвращать false Выберите * FROM (your_table_name) где flag = 'волонтер' и flag = 'загружено';
вы также можете сделать это
SELECT * FROM (your_table_name) WHERE flag = 'Volunteer' OR flag = 'Uploaded' ORDER BY contactid, flag asc;
(asc для по возрастанию, вы также можете изменить его на desc, если вы хотите, чтобы он отображался в порядке убывания)