SQL Select 个来自 table ID 不重复的案例

SQL Select cases from a long table where ID is not duplicated

我有一个 table 如下所示:

id | ncode | code
=================
1      1     ABC
1      2     DEF
2      1     ABC
3      1     ABC
4      1     ABC
4      2     DEF

我有两个要求:

  1. 所有 ncode == 1 且 code == ABC
  2. 的记录
  3. 但前提是 id 在 table 中的某处没有重复(即,我不想要 code == ABC 的记录,如果相同的话id 在 table 的某处也有一个 ncode > 1。

select * from table where code == "ABC" and ncode == 1 将满足第一个要求,但我不知道如何满足第二个要求。

根据上面的例子 table 我想要的输出是:

id | ncode | code
=================
2      1     ABC
3      1     ABC

根据下面的回答,我使用了一个 window 函数:

select *
from (
   select *,
    sum(case when ncode > 1 then 1 else 0 end) over(partition by id) cnt
   from mytable
)
where code = 'ABC' and ncode = 1 and cnt = 0 order by id

然后我实现了接受的答案提供的 Google BiqQuery 特定语法:

select id, ANY_VALUE(ncode) ncode, ANY_VALUE(code) code
from mytable
group by id
having count(1) = 1
and (cpt, ncode) = ('ABC', 1)

您可以使用 NOT EXISTS 和一个相关的子查询来搜索 table 具有相同 id 但大 ncode.

的记录
SELECT t1.*
       FROM elbat t1
       WHERE t1.code = 'ABC'
             AND t1.ncode = 1
             AND NOT EXISTS (SELECT *
                                    FROM elbat t2
                                    WHERE t2.id = t1.id
                                          AND t2.ncode > t1.ncode);

顺便说一句:停止对字符串文字使用双引号。尽管您的 DBMS 可能会接受这一点,但在标准中,双引号用于标识符,单引号用于字符串文字。通过遵循你的代码得到更多的 portable。 == 作为比较运算符也是如此。最好使用 =.

为了性能,您需要在 (id, ncode) 上建立索引。

最简单的方法可能是使用 NOT EXISTS 条件 - 应该是这样的:

SELECT  t.*
FROM    TABLE t
WHERE   t.code = "ABC"
        AND t.ncode = 1
        AND NOT EXISTS
        (
        SELECT  NULL
        FROM    TABLE ti
        WHERE   ti.id = t.id
                AND ti.ncode > 1
        );
        

您可以使用 window 函数:

select *
from (select t.*, count(*) over(partition by id, code) cnt from mytable) t
where code = 'ABC' and ncode = 1 and cnt = 1

这假设每个 code 没有重复的 ncode,并且没有低于 1 的值。否则,我们可以在 window 函数中更具体:

select *
from (
    select t.*, 
        sum(case when ncode > 1 then 1 else 0 end) over(partition by id, code) cnt 
    from mytable 
) t
where code = 'ABC' and ncode = 1 and cnt = 0

以下也应该有效(BigQuery 标准 SQL)

#standardSQL
SELECT id, 
  ANY_VALUE(ncode) ncode, 
  ANY_VALUE(code) code
FROM `project.dataset.table`
GROUP BY id
HAVING COUNT(1) = 1
AND (code, ncode) = ('ABC', 1)