根据某些列过滤 table 中的记录
Filter records in a table based on some columns
我有一个 table(比如说,table 名称是“items”),如下所示。
id
timestamp
name
amount
100
16106800
pqr
10
100
16106800
pqr
0
100
16106400
pqr
15
如果有多个记录具有相同的名称和相同的时间戳,那么我想排除一个数量为零的记录。例如 - 在上面的 table 中,我们有两条记录(第一条和第二条记录)具有相同的名称和相同的时间戳,所以我必须排除一条金额为零的记录。
预期结果如下:
id
timestamp
name
amount
100
16106800
pqr
10
100
16106400
pqr
15
我写了一个如下的查询,但它并不完全有效。
SELECT *
FROM items w
WHERE EXISTS (
SELECT *
FROM items x
WHERE x.timestamp = w.timestamp AND x.name=w.name
) AND w.amount > 0
当所有时间戳都不同时,我的上述查询失败。如果没有具有相同名称和相同时间戳的记录,那么它不会从项目 table.
中排除任何内容
EDIT :如果 table 中只有一行的金额为零,则不应将其排除在外。
我的查询产生了这些结果:
如果您只有一条记录,不管金额多少,都会显示
如果您有多条记录,它只会显示金额> 0的记录
所以,试试这个:
SELECT *
FROM items t1
WHERE NOT EXISTS
(SELECT 1 FROM items t2
WHERE t1.id = t2.id
AND t1.timestamp = t2.timestamp
AND t1.name = t2.name
AND t2.amount > 0)
OR t1.amount > 0
请注意:我已经用不同的 DBMS 在 SQL Fiddle 上写过,但使用的 SQL 是标准的,因此 SQL 服务器也可以。
或者您可以使用 count() over()
SELECT id, timestamp, name, amount
FROM (
SELECT *, count(*) over(partition by id, timestamp, name) cnt
FROM yourtable) t
WHERE cnt = 1 OR amount > 0
;with a as (
select distinct id,timestamp,name from items
),
with b as (
select * from items
where amount > 0
)
select a.id,a.timestamp,a.name,isnull(b.amount,0) amount
from a join b on a.timestamp = b.timestamp and a.name = b.name
条件 Window 聚合 COUNT(CASE...) OVER...
可能是您最好的选择:
SELECT id, timestamp, name, amount
FROM (
SELECT *,
count(case when amount > 0 then 1 end)
over(partition by timestamp, name) CountNonZeroes
FROM Table
) t
WHERE CountNonZeroes = 0 OR amount > 0
为什么不聚合?
select id, timestamp, name, sum(amount) as amount
from items
group by id, timestamp, name;
此 return 每个 id
/timestamp
/name
组合一行,以及该组合的总金额。我怀疑这确实是您真正想要的。
但是,您也可以通过调整逻辑来修改查询:
SELECT i.*
FROM items i
WHERE i.amount > 0 OR
NOT EXISTS (SELECT 1
FROM items i2
WHERE i2.timestamp = i.timestamp AND
i2.name = i.name AND
i2.amount > 0
);
即 return amount > 0
所在的所有行。然后 return timestamp
/name
组合的所有行,其中没有包含 amount > 0
.
的行
我有一个 table(比如说,table 名称是“items”),如下所示。
id | timestamp | name | amount |
---|---|---|---|
100 | 16106800 | pqr | 10 |
100 | 16106800 | pqr | 0 |
100 | 16106400 | pqr | 15 |
如果有多个记录具有相同的名称和相同的时间戳,那么我想排除一个数量为零的记录。例如 - 在上面的 table 中,我们有两条记录(第一条和第二条记录)具有相同的名称和相同的时间戳,所以我必须排除一条金额为零的记录。
预期结果如下:
id | timestamp | name | amount |
---|---|---|---|
100 | 16106800 | pqr | 10 |
100 | 16106400 | pqr | 15 |
我写了一个如下的查询,但它并不完全有效。
SELECT *
FROM items w
WHERE EXISTS (
SELECT *
FROM items x
WHERE x.timestamp = w.timestamp AND x.name=w.name
) AND w.amount > 0
当所有时间戳都不同时,我的上述查询失败。如果没有具有相同名称和相同时间戳的记录,那么它不会从项目 table.
中排除任何内容EDIT :如果 table 中只有一行的金额为零,则不应将其排除在外。
我的查询产生了这些结果:
如果您只有一条记录,不管金额多少,都会显示
如果您有多条记录,它只会显示金额> 0的记录
所以,试试这个:
SELECT *
FROM items t1
WHERE NOT EXISTS
(SELECT 1 FROM items t2
WHERE t1.id = t2.id
AND t1.timestamp = t2.timestamp
AND t1.name = t2.name
AND t2.amount > 0)
OR t1.amount > 0
请注意:我已经用不同的 DBMS 在 SQL Fiddle 上写过,但使用的 SQL 是标准的,因此 SQL 服务器也可以。
或者您可以使用 count() over()
SELECT id, timestamp, name, amount
FROM (
SELECT *, count(*) over(partition by id, timestamp, name) cnt
FROM yourtable) t
WHERE cnt = 1 OR amount > 0
;with a as (
select distinct id,timestamp,name from items
),
with b as (
select * from items
where amount > 0
)
select a.id,a.timestamp,a.name,isnull(b.amount,0) amount
from a join b on a.timestamp = b.timestamp and a.name = b.name
条件 Window 聚合 COUNT(CASE...) OVER...
可能是您最好的选择:
SELECT id, timestamp, name, amount
FROM (
SELECT *,
count(case when amount > 0 then 1 end)
over(partition by timestamp, name) CountNonZeroes
FROM Table
) t
WHERE CountNonZeroes = 0 OR amount > 0
为什么不聚合?
select id, timestamp, name, sum(amount) as amount
from items
group by id, timestamp, name;
此 return 每个 id
/timestamp
/name
组合一行,以及该组合的总金额。我怀疑这确实是您真正想要的。
但是,您也可以通过调整逻辑来修改查询:
SELECT i.*
FROM items i
WHERE i.amount > 0 OR
NOT EXISTS (SELECT 1
FROM items i2
WHERE i2.timestamp = i.timestamp AND
i2.name = i.name AND
i2.amount > 0
);
即 return amount > 0
所在的所有行。然后 return timestamp
/name
组合的所有行,其中没有包含 amount > 0
.