[英]SQL - how to select all rows which have value1 in column but not value2 in same column?
I have a sql table like this: 我有一个这样的SQL表:
------------------------------------------
ID | SKU | Name | Type
-------------------------------------------
2 | ABC | Pasta | 2
3 | XYZ | Maggi | 5
2 | ABC | Pasta | 5
6 | MNO | Macroni | 2
3 | XYZ | Maggi | 0
3 | XYZ | Maggi | 2
I need to find rows which have type 2 but not have an entry for type 5 or 0 我需要找到类型2但没有类型5或0的条目的行
For example: It should result in 例如:它应导致
------------------------------------------
ID | SKU | Name | Type
-------------------------------------------
6 | MNO | Macroni | 2
Is it possible to result so using this one table only? 是否有可能因此只使用一张桌子呢? Of course it is.
当然是的。 This table has 1.4M rows and I used this query (not sure if it is correct)
该表有140万行,我使用了此查询(不确定是否正确)
SELECT e1.* FROM reportmal e1, reportmal e2
WHERE e1.id= e2.id
AND e1.type=2 AND e2.type=5
The query never returned anything, because it is still running. 该查询从未返回任何内容,因为它仍在运行。 Can you help?
你能帮我吗?
I like to do this with having
and group by
: 我喜欢通过
having
和group by
来做到这一点:
select e.id
from reportmal e
group by e.id
having sum(e.type = 2) > 0 and
sum(e.type in (0, 5)) = 0;
MySQL treats boolean expressions as integers in a numeric context, with "1" for true and "0" for false. MySQL在数字上下文中将布尔表达式视为整数,其中“ 1”为true,“ 0”为false。 Hence
sum(e.type = 2)
counts the number of records in each group where type = 2
. 因此,
sum(e.type = 2)
计算type = 2
每个组中的记录数。 The > 0
means that at least one such row exists. > 0
表示至少存在这样的一行。 The = 0
means that no such rows exist. = 0
表示不存在这样的行。
If you want the original rows you can join
this result back to the table. 如果要原始行,可以将此结果重新
join
表中。
Sounds like a typical "not exists"-query: 听起来像是典型的“不存在”查询:
select * from atable result
where result.type = 2 and not exists
(select 1 from atable no50
where no50.type in (5,0)
and no50.sku = result.sku
)
or: 要么:
select * from atable result
where result.type = 2 and result.sku not in
(select sku from atable no50
where no50.type in (5,0)
)
Try this using group by
to find the ID which has 2 and not 0 or 5 using conditional count and then using IN
to get the relevant rows. 使用
group by
尝试使用条件计数查找ID为2而不是0或5的ID,然后使用IN
获取相关行。
select *
from your_table
where id in (
select
id
from your_table t
group by id
having count(case when type = 2 then 1 end) > 0
and count(case when type in (0,5) then 1 end) = 0
);
select *
from reportmal e
where e.type = 2
and not exists
(
select null
from reportmal e2
where e2.id = e.id
and e2.type in (0,5)
)
As for the performance issue - 至于性能问题-
The minimum you need is an index on reportmal (id). 您需要的最低要求是报告(id)的索引。
Index on reportmal (id,type) might be better. 报告编号(id,type)的索引可能更好。
I think you should use this: 我认为您应该使用此:
SELECT a.*
FROM reportmal a
WHERE a.type = 2
AND NOT EXISTS (SELECT 1
FROM reportmal b
WHERE b.name = a.name
AND b.type IN (5,0));
It's like: "All rows with TYPE 2, and NOT EXISTS a row with same NAME and TYPE 5 or 0" 就像:“所有具有TYPE 2的行,并且不存在具有相同NAME和TYPE 5或0的行”
I don't know what's your parameter to define an "entry". 我不知道您定义“入口”的参数是什么。 Maybe you should add SKU on subquery (it all depends your data model).
也许您应该在子查询上添加SKU(这完全取决于您的数据模型)。
Your query was close, but you were joining on Id which will give you a Cartesian product. 您的查询已结束,但您要加入Id,这将为您提供笛卡尔积。
This is how I'd do it. 这就是我要做的。
Select p1.*
From pasta p1
Left outer join pasta p2 on p1.sku=p2.sku
And p2.type in (0,5)
Where p2.type is null
Hope that helps you. 希望对您有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.