我正在寻找表中的错误,并且希望报告重复项和缺失值。我不确定执行此操作的最佳方法,并且正在寻求实现此目标的更好方法的建议。这是在Oracle 12c中。
这似乎达到了预期的效果:
SELECT a.id,
a.mainfield,
a.location,
b.counter
FROM maintable a
INNER JOIN (
SELECT mainfield,
Count(*) counter
FROM maintable
GROUP BY mainfield
HAVING Count(mainfield) > 1 OR mainfield IS NULL
) b ON a.mainfield = b.mainfield OR
( a.mainfield IS NULL AND b.mainfield IS NULL )
ORDER BY a.mainfield;
这可以正常工作,并为我提供ID,可能为空的MAINFIELD,位置和重复MAINFIELD值或空MAINFIELD值的计数。
我可以使用更简单或更有效的方法吗?我不得不承认我的SQL技能非常生锈。
示例数据可能有帮助,也可能没有帮助,但是ID是主键,是数字,不能为空。其他字段都是NVARCHAR2并且可为空。这些都没有索引。这是输出的样子。有些记录是完全错误的。有些是明显的错别字。有些似乎是测试数据。
ID MAINFIELD LOCATION COUNTER
------- --------- --------------------------------- -------
16626 206000650 9A OLIVER ST CENTRAL STATION 2
18805 206000650 3 SWIFT CT CENTRAL STATION 2
22409 940000170 2 MARKET ST NEWARK DE 2
22003 940000170 1 MARKET ST NEWARK NJ 2
29533 970000030 95 MILL RD ANDOVER 2
20256 970000030 12 RAILROAD AVE 2
29018 978900050 44 BROAD STREET 2
28432 978900050 WASHINGTON ST AND HAMILTON AVE 2
21831 980700050 BROADWAY NEWTOWN 2
24147 980700050 MAIN STREET LEVITTOWN 2
26418 3
26738 TEST DATA 3
26755 3
最后三行的MAINFIELD为空,并且有三条这样的记录(其中两行的位置也为空)。
在对以上数据进行了一些了解之后,我意识到我可能会考虑使用NVL来消除部分条件,例如这样(假设我选择的值在主字段中不是有效值):
SELECT a.id,
a.mainfield,
a.location,
b.counter
FROM maintable a
INNER JOIN (
SELECT mainfield,
Count(*) counter
FROM maintable
GROUP BY mainfield
HAVING Count(mainfield) > 1 OR mainfield IS NULL
) b ON NVL(a.mainfield,'***NULL***') = NVL(b.mainfield.'***NULL***')
ORDER BY a.mainfield;
这执行起来更快,并且似乎产生了预期的结果。我一直在尝试其他替代方案,但都没有成功,因此这可能是最好的替代方案。
我放弃的另一种选择可能适用于稍微不同的情况(但对我而言效果最差)是
SELECT id,
mainfield,
location,
COUNT (id) OVER (PARTITION BY mainfield) counter
FROM maintable a
WHERE mainfield IS NULL
OR EXISTS(SELECT 1 from maintable b
WHERE mainfield = a.mainfield AND ROWID <> a.ROWID)
ORDER BY a.mainfield;
我真的很喜欢将其组合在一起的方式,并希望它会有所帮助。我们并不是在说它运行了好几天,但是我试图在Oracle中重新学习使用SQL / DS进行编码时曾经具有的技能。
如果以上任何一项给任何人提供了更好的选择的想法,我将不胜感激。 (例如,是否有一种方法可以在WHERE子句中引用计数器[PARTITION BY主字段上的COUNT(标识)?)
再次感谢。
答案 0 :(得分:1)
这似乎是Balazs Papp在dba.stackexchange.com板上提供的可读性,可靠性和效率之间的良好折衷: https://dba.stackexchange.com/a/210998/154392
SELECT * FROM (
SELECT id,
mainfield,
location,
COUNT (id) OVER (PARTITION BY mainfield) counter
FROM maintable a
) where counter > 1 or mainfield IS NULL
ORDER BY mainfield;
这是原始帖子的最后一个替代方案的简化。就我所知,它似乎没有比我原来的替代方法低效率,但对我来说,它更具可读性。