在同一列上使用多个 WHERE 条件进行 SELECTING

SELECTING with multiple WHERE conditions on same column

提问人:RyanNehring 提问时间:10/29/2010 最后编辑:Bill KarwinRyanNehring 更新时间:8/8/2022 访问量:537297

问:

好吧,我想我可能在这里忽略了一些明显/简单的东西......但我需要编写一个查询,该查询仅返回与同一列上的多个条件匹配的记录......

我的表格是一个非常简单的链接设置,用于将标志应用于用户......

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

等。。。在这种情况下,您会看到联系人 99 和 100 都被标记为“志愿者”和“已上传”......

我需要做的是仅返回那些与通过搜索表单输入的多个条件匹配的联系人 ID......contactid 必须匹配所有选择的标志......在我的脑海中,SQL应该看起来像这样:

SELECT contactid 
 WHERE flag = 'Volunteer' 
   AND flag = 'Uploaded'...

但。。。什么也没回来......我在这里做错了什么?

mysql sql 聚合函数 where-clause 关系除法

评论

3赞 Johar Zaman 2/28/2019
此语句不起作用,因为 flag 不能同时等于 'Volunteer' 和 'Upload'。您可以使用 OR 运算符而不是 AND,它会起作用。

答:

6赞 Brandon Frohbieter 10/29/2010 #1

无法真正看到您的表格,但标志不能同时为“志愿者”和“已上传”。如果列中有多个值,则可以使用

WHERE flag LIKE "%Volunteer%" AND flag LIKE "%UPLOADED%"

看到格式化的表格并不真正适用。

120赞 Mark Byers 10/29/2010 #2

您可以使用 和 :GROUP BYHAVING 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

或者使用联接:

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'

如果标志列表很长,并且有很多匹配项,则第一个可能更快。如果标志列表很短并且匹配项很少,您可能会发现第二个更快。如果性能是一个问题,请尝试在数据上测试两者,看看哪个效果最好。

评论

1赞 OMG Ponies 10/29/2010
JOIN 的问题在于,如果有多个与“已上传”标志关联的 contactid 记录,则 T1 引用将有重复项。
0赞 Bangash 12/10/2018
SELECT contact_id FROM your_table WHERE ( flag IN ('Volunteer', 'Uploaded', ...) and one_type = sometype_one ) AND flag IN ('someOtherVolunteer', 'Uploaded', ...) and second_type = sometype_two GROUP BY contact_id HAVING COUNT(*) = 2 先生,我有与上面查询相同的 senario,但它返回 null。零行。
0赞 Sri 2/11/2020
在自联接的情况下,对于 N 个值,您将需要 N 个自联接。在该示例中,如果您必须获得包含所有这三个标志“已上传”、“志愿者”和“通过导入”的结果,该怎么办?所以,我认为使用 with 更有意义。GROUP BYHAVING COUNT
28赞 OMG Ponies 10/29/2010 #3

用:

  SELECT t.contactid
    FROM YOUR_TABLE t
   WHERE flag IN ('Volunteer', 'Uploaded')
GROUP BY t.contactid
  HAVING COUNT(DISTINCT t.flag) = 2

关键是计数需要等于子句中的参数数。t.flagIN

如果 contactid 和 flag 的组合没有唯一约束,则使用 is -- 如果没有重复的可能性,则可以从查询中省略 DISTINCT:COUNT(DISTINCT t.flag)

  SELECT t.contactid
    FROM YOUR_TABLE t
   WHERE flag IN ('Volunteer', 'Uploaded')
GROUP BY t.contactid
  HAVING COUNT(t.flag) = 2
-6赞 Kevin 7/27/2012 #4

有时你看不到树木的木头:)

您的原始 SQL ..

SELECT contactid 
 WHERE flag = 'Volunteer' 
   AND flag = 'Uploaded'...

应该是:

SELECT contactid 
 WHERE flag = 'Volunteer' 
   OR flag = 'Uploaded'...

评论

2赞 Kildareflare 7/23/2013
我不相信这会返回 OP 想要的结果。contactId 需要匹配 ALL 标志,而不是一个或多个标志。
-3赞 talha 11/10/2013 #5

AND只有当两者都出现在您的列中时,才会返回答案。否则将返回值...volunteeruploadednull

尝试在您的陈述中使用...OR

SELECT contactid  WHERE flag = 'Volunteer' OR flag = 'Uploaded'

评论

0赞 kero 11/10/2013
这将显示所有为 OR 的条目,但他希望条目是两次,并且每个条目一次VolunteerUploaded
3赞 Pankaj Singh 2/4/2014 #6

尝试使用此备用查询:

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;
0赞 vivek 8/6/2015 #7
SELECT contactid, Count(*) 
FROM <YOUR_TABLE> WHERE flag in ('Volunteer','Uploaded')  
GROUP BY contactid 
HAVING count(*)>1;
-3赞 user6310881 5/9/2016 #8
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
); 
-3赞 user981298 6/24/2016 #9

将 AND 更改为 OR。简单的错误。把它想象成简单的英语,我想选择任何等于这个或那个的东西。

12赞 wtct 3/29/2017 #10

考虑像这样使用 INTERSECT:

SELECT contactid WHERE flag = 'Volunteer' 
INTERSECT
SELECT contactid WHERE flag = 'Uploaded'

我认为这是最物流的解决方案。

评论

1赞 linkonabe 7/13/2020
由于提问者标记了 mysql,我认为最好指出 INTERSECT 不适用于 MySql
1赞 JulieC 1/29/2021
提问者可能已经标记了 mysql,但为这个 TSQL 用户竖起大拇指,这很有效。
-4赞 Aitha Tarun 2/28/2019 #11

使用这个: 例如:

select * from ACCOUNTS_DETAILS
where ACCOUNT_ID=1001
union
select * from ACCOUNTS_DETAILS
where ACCOUNT_ID=1002
0赞 Farhan 10/8/2021 #12

像这样的东西应该对你有用

SELECT * FROM `product_options` GROUP BY product_id 
HAVING COUNT(option_id IN (1,2,3) OR NULL) > 0 AND COUNT(option_id IN (7) OR NULL) > 0