问题描述
我正在使用Postgresql v.11。我有一张三列的桌子。我的目标是在数据内部发现冗余。
首先,我做一个简单的GROUP BY:
SELECT client,block,"date"
FROM lines
GROUP BY client,"date"
ORDER BY client,block
结果如下:
1 | P10001 | 2020-01-01
1 | P10002 | 2020-04-17
1 | P10002 | 2020-05-04
1 | P10003 | 2020-05-05
现在,我想标识具有相同“块”但具有不同“日期”的行。在此示例中,第2行和第3行就是这种情况(block = P10002)
现在,我使用javascript解析完整的结果集并找到这2个多余的行(我使用result.reduce(...)
)
预期结果是这样
1 | P10002 | 2020-04-17
1 | P10002 | 2020-05-04
最好将两个日期保留在结果集中,因为我只需要更改其中一个的“块”即可。如果结果集中没有date列,则需要再次请求查找所有受影响的行。
这是表和数据的脚本
CREATE TABLE lines (
"client" integer NOT NULL,"block" text NOT NULL,"date" date NOT NULL
);
INSERT INTO lines ("client","block","date") VALUES
(1,'P10001','2020-01-01'),(1,'P10002','2020-04-17'),'2020-05-04'),'P10003','2020-05-05');
非常感谢
解决方法
您可以将HAVING
子句与GROUP
和BY block
一起使用,以明确计数dates
:
SELECT block
FROM lines
GROUP BY block
HAVING COUNT( DISTINCT "date" ) > 1;
block
------
P10002
,
您应该使用HAVING
条款来获取冗余数据集。我假设您在冗余检测中也需要客户端。
查询看起来像这样。
SELECT client,block
FROM lines
GROUP BY client,block
HAVING count(distinct "date") > 1
ORDER BY client,block
,
您可以使用select l.* from lines l
where exists (
select 1 from lines
where client = l.client and block = l.block and date <> l.date
)
来做到这一点:
client,block
如果每个COUNT(*)
都没有重复的日期,则还可以使用select client,block,date
from (
select *,count(*) over (partition by client,block) counter
from lines
) t
where counter > 1
窗口函数:
> client | block | date
> -----: | :----- | :---------
> 1 | P10002 | 2020-04-17
> 1 | P10002 | 2020-05-04
请参见demo。
结果:
getData(): Observable<{items: MyData[]}> {
return new Observable(subscriber => {
this.myNext(subscriber);
});;
}
,
这适用于所有数据库管理系统。
某些DBMS(您未指定)也提供GROUP BY ROLLUP()
。在您的DBMS文档中查找。
如前所述,该代码无处不在-它们对NULL的排序可能不同。
WITH
lines(client,dt) AS (
SELECT 1,'P10001',DATE '2020-01-01'
UNION ALL SELECT 1,'P10002',DATE '2020-04-17'
UNION ALL SELECT 1,DATE '2020-05-04'
UNION ALL SELECT 1,'P10003',DATE '2020-05-05'
UNION ALL SELECT 1,DATE '2020-05-05'
)
SELECT
client,dt
FROM lines
UNION ALL
SELECT
client,NULL::DATE AS dt
FROM lines
GROUP BY
client,block
ORDER BY
client,dt
-- out client | block | dt
-- out --------+--------+------------
-- out 1 | P10001 |
-- out 1 | P10001 | 2020-01-01
-- out 1 | P10001 | 2020-01-01
-- out 1 | P10002 |
-- out 1 | P10002 | 2020-04-17
-- out 1 | P10002 | 2020-04-17
-- out 1 | P10002 | 2020-05-04
-- out 1 | P10002 | 2020-05-04
-- out 1 | P10003 |
-- out 1 | P10003 | 2020-05-05
-- out 1 | P10003 | 2020-05-05