我有一个数据库,里面有600万条记录,这些记录是从PDF会计文档中提取的。
在数据库中,我在列A中有一条记录,其值为:“员工姓名”。以及B列中从1到6百万的递增索引。
值“EmployeeName”上方的记录有时是雇员的姓名,带有一个数字。
有时它是一个空值,有时它是一个数字。在这两种情况下,员工姓名都将列在该记录的上方。
示例:
| 一个|B|
| --------------|--------------|
| “约翰·史密斯12345”|十九岁|
| “员工姓名”|二十|
| 《Something Else》|二十一|
| 《Something Else》|二十二|
| “简·史密斯56789”|二十三|
| “空”|二十四|
| “员工姓名”|二十五|
| 《Something Else》|二十六|
| 《Something Else》|二十七个|
| “小雅各布·约翰·史密斯”|二十八|
| “九八七六五”|二十九|
| “员工姓名”|三十|
| 《Something Else》|三十一|
我需要雇员的名字。过滤掉这个数字可能是一个不错的奖励,但现在我很高兴至少能得到这个名字。
SELECT DISTINCT A
FROM PAYROLL_RECORDS
WHERE B IN (SELECT (B - 1) FROM PAYROLL_RECORDS
WHERE A = 'Employee Name')
ORDER BY A;
如果名称总是位于其顶部的行,则这将非常有效。
我可能需要一个SELECT
语句,它可以抓取上面的两行,并检查A列中是否有CHARACTERS(而不是数字或NULL)。
我需要一份所有员工姓名的清单,完整扫描所有600万条记录。
想法?
5条答案
按热度按时间daupos2t1#
选择这两行并使用regex丢弃错误的行
成功也取决于“其他东西”中的内容。您可能还必须丢弃正则表达式中的其他值。
a0zr77ik2#
我知道您希望列中每次出现字符串
'Employee Name'
时的“前一个”非空值和非数字值。我推荐使用带有条件表达式和
ignore nulls
选项的lag
:技巧是让
lag()
中的表达式将所有数字值转换为null
s,以便ignore null
s选项在查找实际雇员姓名时跳过它们。请注意:
Demo-在nbk的小提琴(谢谢nbk)。
drkbr07n3#
您可以使用窗口函数
LEAD
检查两行的值fiddle
如果你有空格,你可以
TRIM
Afiddle
3z6pesqy4#
不需要联接或子查询。在where子句的帮助下,您可以从A列中删除null和数字值,然后
lag()over()
窗口函数将帮助您获得每个“员工姓名”的前一个值。第一行始终为null
查询:
输出:
| 一个|
| --------------|
| 联系我们|
| 约翰·史密斯|
| 简·史密斯|
| 小雅各布·约翰·史密斯|
fiddle
如果你想删除第一行空值,那么:
查询:
输出:
| 一个|
| --------------|
| 约翰·史密斯|
| 简·史密斯|
| 小雅各布·约翰·史密斯|
fiddle
在Oracle 10 g中,
validate_conversion()
不可用。您可以使用REGEXP_LIKE()
查询:
输出:
| 一个|
| --------------|
| 约翰·史密斯|
| 简·史密斯|
| 小雅各布·约翰·史密斯|
fiddle
uurv41yg5#
使用第一个CTE从值中删除任何空值和数字,然后将“员工姓名”标记为1,将其他值标记为0。
第二个CTE用于检索每个“员工姓名”行的前面的行。
Demo here