Выбор с несколькими условиями 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 и флага-если нет шансов на дубликаты, вы можете опустить отличное от запроса:
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 = 'Volunteer' и flag = 'Uploaded';
вы также можете сделать это
SELECT * FROM (your_table_name)
WHERE flag = 'Volunteer' OR flag = 'Uploaded'
ORDER BY contactid, flag asc;
(asc для по возрастанию, вы также можете изменить его на desc, если хотите, чтобы он отображался в порядке убывания)