我需要帮助来过滤表格中的数据:tbl_entso_cdbf
。
该表包含从一个地区到其他地区的贸易信息:
Utc | date |area_in|area_out| value |
------------------------------------------------------------------
2015-12-05T03:00Z |2015-12-05 03:00:00| 275 | 40 | 320 |
2015-12-05T03:00Z |2015-12-05 03:00:00| 40 | 275 | 0 |
2015-12-06T03:00Z |2015-12-06 03:00:00| 100 | 175 | 550 |
2015-12-06T03:00Z |2015-12-06 03:00:00| 175 | 100 | 0 |
2015-11-04T03:00Z |2015-11-04 03:00:00| 280 | 310 | 0 |
2015-11-04T03:00Z |2015-11-04 03:00:00| 310 | 280 | 0 |
2016-09-19T00:00Z |2016-09-19 00:00:00| 187 | 292 | 45 |
2016-09-19T00:00Z |2016-09-19 00:00:00| 292 | 187 | 0 |
表格包含area_in
和area_out
之间的导出和导入值。
此表包含值列中的双重条目,引用date
列。例如,前两行具有相同的日期和时间2015-12-05 03:00:00
,但有两个不同的值320
和0
。我希望只有一个值320
并删除具有0
值的第二行。这意味着在同一日期和时间275
下,area_in 40
和area_out 2015-12-05 03:00:00
之间的交易应具有唯一的正值。同样意味着行号。 3,4,7和8。
但是在第5行和第6行中都有0
个值,所以我想只有一个记录(其中任何一个)。
所以,最后我希望我的表看起来像:
Utc | date |area_in|area_out| value |
------------------------------------------------------------------
2015-12-05T03:00Z |2015-12-05 03:00:00| 275 | 40 | 320 |
2015-12-06T03:00Z |2015-12-06 03:00:00| 100 | 175 | 550 |
2015-11-04T03:00Z |2015-11-04 03:00:00| 310 | 280 | 0 |
2016-09-19T00:00Z |2016-09-19 00:00:00| 187 | 292 | 45 |
此表有数百万种此类行要过滤。任何人都可以帮我写一个SQL查询吗?
答案 0 :(得分:0)
我假设你的主键表看起来像这样:
pk | Utc | date |area_in|area_out| value |
-----------------------------------------------------------------------
1 | 2015-12-05T03:00Z |2015-12-05 03:00:00| 275 | 40 | 320 |
2 | 2015-12-05T03:00Z |2015-12-05 03:00:00| 40 | 275 | 0 |
3 | 2015-12-06T03:00Z |2015-12-06 03:00:00| 100 | 175 | 550 |
4 | 2015-12-06T03:00Z |2015-12-06 03:00:00| 175 | 100 | 0 |
5 | 2015-11-04T03:00Z |2015-11-04 03:00:00| 280 | 310 | 0 |
6 | 2015-11-04T03:00Z |2015-11-04 03:00:00| 310 | 280 | 0 |
7 | 2016-09-19T00:00Z |2016-09-19 00:00:00| 187 | 292 | 45 |
8 | 2016-09-19T00:00Z |2016-09-19 00:00:00| 292 | 187 | 0 |
执行此查询后,您应该能够删除要删除的行:
DELETE FROM tbl_entso_cdbf
WHERE pk IN (SELECT PK_DEL
FROM (Select pk AS PK_DEL
, utc
, value
, ROW_NUMBER() OVER(PARTITION BY utc ORDER BY value desc) AS DUB_IND
FROM tbl_entso_cdbf
WHERE DUB_IND <> 1
)
);
该查询用于删除子查询返回中pk in的所有行。子查询应返回记录的所有主键,其中值为次要值作为重复项。但是,在尝试使用shure之前,请查询此查询返回应删除的记录的所需结果:
Select pk AS PK_DEL
, utc
, value
, ROW_NUMBER() OVER(PARTITION BY utc ORDER BY value desc) AS DUB_IND
FROM tbl_entso_cdbf
WHERE DUB_IND <> 1
如果是这样,您应该能够删除重复项!
答案 1 :(得分:0)
使用此查询查找要删除的行:
select t0.*
from tbl_entso_cdbf t0
join tbl_entso_cdbf t1
on t1.Utc = t0.Utc
and t1.date = t0.date
and t1.area_in = t0.area_out
and t1.area_out = t0.area_in
where t0.value = 0
and (t1.value <> 0 or t1.area_in < t0.area_in);
条件是:
value = 0
Utc
和相同的date
,但area_in
和area_out
已切换。value
不是0
或 area_in
更小。查询将返回以下行:
| Utc | date | area_in | area_out | value |
|-------------------|---------------------|---------|----------|-------|
| 2015-12-05T03:00Z | 2015-12-05 03:00:00 | 40 | 275 | 0 |
| 2015-12-06T03:00Z | 2015-12-06 03:00:00 | 175 | 100 | 0 |
| 2015-11-04T03:00Z | 2015-11-04 03:00:00 | 310 | 280 | 0 |
| 2016-09-19T00:00Z | 2016-09-19 00:00:00 | 292 | 187 | 0 |
现在在delete语句的子查询中使用它:
delete t1
from tbl_entso_cdbf t1
natural join (
select t0.*
from tbl_entso_cdbf t0
join tbl_entso_cdbf t1
on t1.Utc = t0.Utc
and t1.date = t0.date
and t1.area_in = t0.area_out
and t1.area_out = t0.area_in
where t0.value = 0
and (t1.value <> 0 or t1.area_in < t0.area_in)
) t0;
NATURAL JOIN
表示所有列值必须相等。如果您有主键(或任何唯一键),则只需选择子查询中的主(唯一)键列而不是*
。
现在表中只剩下以下行:
| Utc | date | area_in | area_out | value |
|-------------------|---------------------|---------|----------|-------|
| 2015-12-05T03:00Z | 2015-12-05 03:00:00 | 275 | 40 | 320 |
| 2015-12-06T03:00Z | 2015-12-06 03:00:00 | 100 | 175 | 550 |
| 2015-11-04T03:00Z | 2015-11-04 03:00:00 | 280 | 310 | 0 |
| 2016-09-19T00:00Z | 2016-09-19 00:00:00 | 187 | 292 | 45 |