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
我有两个要求:
- 所有
ncode
== 1 且 code
== ABC
的记录
- 但前提是
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)
我有一个 table 如下所示:
id | ncode | code
=================
1 1 ABC
1 2 DEF
2 1 ABC
3 1 ABC
4 1 ABC
4 2 DEF
我有两个要求:
- 所有
ncode
== 1 且code
==ABC
的记录
- 但前提是
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)