我有一个简单的SQL表,其中包含以下内容:
+---------------------+
| id | mode | value |
+---------------------+
| 1 | EXCLUDE | 10 |
| 2 | INCLUDE | 10 |
| 3 | EXCLUDE | 10 |
| 3 | EXCLUDE | 20 |
+---------------------+
想象一下这些是产品。产品1的所有值均为10.产品2的值仅为10。产品3的所有值都是10和20。
我需要一个给出值的sql,我应该返回该值有效的所有产品。
e.g。值10应返回产品2.值30应返回产品1和3.
试过这个:
SELECT *
FROM products
WHERE ( mode = 'INCLUDE' AND value IN( 10) ) OR
( mode = 'EXCLUDE' AND value NOT IN ( 10 ) )
例如,对于值10,,但它也返回第4行,这是基于sql的预期。我该如何解决?我想基于id和检查内部的值以某种方式对排除的那些进行分组?
答案 0 :(得分:3)
使用not exists()
select distinct p.id
from products p
where (mode = 'INCLUDE' and value in (30))
or (
not exists (
select 1
from products i
where i.id = p.id
and mode = 'EXCLUDE'
and value in (30)
)
and exists (
select 1
from products i
where i.id = p.id
and mode = 'EXCLUDE'
and value not in (30)
)
)
答案 1 :(得分:2)
您的问题是id
位于多行。因此,请考虑group by
中的条件having
:
SELECT p.id
FROM products p
GROUP BY p.id
HAVING SUM(CASE WHEN mode = 'INCLUDE' and VALUE IN (10) THEN 1 ELSE 0 END) > 0 OR
(SUM(CASE WHEN mode = 'EXCLUDE' THEN 1 ELSE 0 END) > 0 AND -- has excludes
SUM(CASE WHEN mode = 'EXCLUDE' and VALUE IN (10) THEN 1 ELSE 0 END) = 0 -- but not this one
);
这是一个复杂的逻辑。我认为逻辑是:
id
明确包含该值,请保留该ID。id
明确排除了该值,则删除该ID。答案 2 :(得分:2)
{{1}}