Filename||status
---------------
A|10
A|22
B|10
我的预期输出是
B|10
我不应该得到文件名为10和22状态的输出
答案 0 :(得分:2)
让我们尝试重述您的问题 - 您正在寻找状态为10但状态为22的文件。一旦问题的措辞如此,我们就可以轻松地将需求转换为SQL exists
运算符:
SELECT *
FROM mytable a
WHERE status = 10 AND
NOT EXISTS (SELECT *
FROM mytable b
WHERE a.filename = b.filename AND
b.status = 22)
答案 1 :(得分:0)
这是获取结果的查询:
WITH files AS(
SELECT 'A' AS filename, 10 AS status FROM dual UNION ALL
SELECT 'A' AS filename, 22 AS status FROM dual UNION ALL
SELECT 'B' AS filename, 10 AS status FROM dual UNION ALL
SELECT 'C' AS filename, 22 AS status FROM dual
)
SELECT filename, status
FROM files
WHERE filename NOT IN (
SELECT f1.filename
FROM files f1, files f2
WHERE f1.filename = f2.filename
AND f1.status = 22
AND f2.status = 10
);
我在表格中添加了一条C记录来检查结果的正确性:
B 10
C 22
答案 2 :(得分:0)
我不应该得到文件名为10和22状态的输出
换句话说,您可以拥有状态10
,但不能拥有状态为22
的行,或者您可以拥有状态22
,且不能拥有状态为10
的行。
这些查询都不需要自联接(它们都只使用单个表扫描):
<强>查询强>:
SELECT filename
FROM table_name
GROUP BY filename
HAVING ( COUNT( CASE status WHEN 10 THEN 1 END ) > 0
AND COUNT( CASE status WHEN 22 THEN 1 END ) = 0 )
OR ( COUNT( CASE status WHEN 10 THEN 1 END ) = 0
AND COUNT( CASE status WHEN 22 THEN 1 END ) > 0 );
<强>输出强>:
FILENAME
--------
B
<强>查询强>:
SELECT filename,
status
FROM (
SELECT t.*,
COUNT( CASE status WHEN 10 THEN 1 END )
OVER ( PARTITION BY filename ) AS s10,
COUNT( CASE status WHEN 22 THEN 1 END )
OVER ( PARTITION BY filename ) AS s22
FROM table_name t
WHERE status IN ( 10, 22 )
)
WHERE ( s10 > 0 AND s22 = 0 )
OR ( s10 = 0 AND s22 > 0 );
<强>输出强>:
FILENAME STATUS
-------- ------
B 10
答案 3 :(得分:-2)
select Filename, min(status)
from [table_name]
group by Filename
having count(*) = 1