如何比较同一个表中的值

时间:2016-07-02 07:48:39

标签: sql oracle

Filename||status
---------------
A|10
A|22
B|10

我的预期输出是

B|10

我不应该得到文件名为10和22状态的输出

4 个答案:

答案 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