查询子集

时间:2019-04-20 17:52:29

标签: sql oracle

我想编写一个SQL查询来查找包含特定列的记录,而从该子集中想查找不包含其他值的记录。您如何为此查询?

cid  id2  attribute
--------------------------------
 1  100  delete 
 1  100  payment
 1  100  void
 2  100  delete
 2  102  payment
 2  102  void
 3  102  delete
 3  103  payment

在上面的示例中,我想列出存在付款和删除属性但不存在void属性的cid。因此,它应该从上面的示例中列出3,因为它没有void属性。

忘记提及可能会有更多属性。但是,我需要列出存在删除和付款的记录,而与其他属性无关,但不存在无效记录。

4 个答案:

答案 0 :(得分:1)

您可以使用条件聚合:

SELECT 1 AS DAY FROM DAY1 WHERE C=1 UNION
SELECT 2 AS DAY FROM DAY2 WHERE C=1 UNION
...
SELECT 9 AS DAY FROM DAY9 WHERE C=1 UNION
SELECT 10 AS DAY FROM DAY10 WHERE C=1 

如果没有比这3个更多的属性,则可以省略select cid from tablename where attribute in ('delete', 'payment', 'void') group by cid having count(distinct attribute) = 2 and sum( case attribute when 'void' then 1 else 0 end ) = 0 子句。
请参见demo
结果:

WHERE

答案 1 :(得分:1)

我将此称为“集内查询”查询,因为您要在每个cid中查找特定的属性集。

我会用group byhaving中的条件来表达这一点:

select cid
from t
group by cid
having sum(case when attribute = 'payment' then 1 else 0 end) > 0 and
       sum(case when attribute = 'delete' then 1 else 0 end) > 0 and
       sum(case when attribute = 'void' then 1 else 0 end) = 0 ;

在某些数据库中,可以使用字符串聚合来简化此操作-假设cid没有重复的属性。例如,使用MySQL函数:

select cid
from t
where attribute in ('payment', 'delete' 'void')
group by cid
having group_concat(attribute order by attribute) = 'delete,payment';

答案 2 :(得分:0)

我假设只有三个属性,所以此查询的逻辑是:

首先COUNT个属性GROUP BY cid的数量,然后LEFT JOIN原始表ON的属性为 void 。您应该获取具有2个属性且没有 void 的cid。

原始表命名为temp

SELECT
    subq2.result_cid
FROM (
    SELECT
        *
    FROM (
      SELECT
          T.cid AS result_cid,
          COUNT(T.attribute) AS count
      FROM
          temp AS T
      GROUP BY
          T.cid
    ) AS subq
    LEFT OUTER JOIN temp AS T2 ON subq.result_cid = T2.cid AND T2.attribute = 'void'
) AS subq2
WHERE subq2.count = 2 AND subq2.id2 IS NULL

答案 3 :(得分:-3)

使用| cid | | --- | | 3 |

来使用相关子查询
not exists

demo online