编辑:解决了Dems的大量帮助,我将发布一个截断版本的查询,现在效果非常好!
SELECT
*
FROM
O_PERSONS
/*The below left join returns the most recently added ethnicity classification*/
LEFT JOIN
(SELECT
ROW_NUMBER() OVER (PARTITION BY O_CLASSIFICATIONS.CLA_SUBJECT_ID ORDER BY O_CLASSIFICATIONS.CLA_DATE_NOTIFIED DESC) AS Sequence_ID,
O_CLASSIFICATIONS.CLA_CAT_ID,
O_CLASSIFICATIONS.CLA_SUBJECT_ID
FROM
O_CLASSIFICATIONS
WHERE
O_CLASSIFICATIONS.CLA_SUBJECT_IND = 'P'
AND
O_CLASSIFICATIONS.CLA_TOP_CAT_ID = 'ETHNIC'
AND
O_CLASSIFICATIONS.CLA_CAT_ID <> 'DECLINED'
) ETHNIC
ON ETHNIC.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND ETHNIC.Sequence_ID = 1
/*The below left join returns the most recently added PCG classification*/
LEFT JOIN
(SELECT
ROW_NUMBER() OVER (PARTITION BY O_CLASSIFICATIONS.CLA_SUBJECT_ID ORDER BY O_CLASSIFICATIONS.CLA_DATE_NOTIFIED DESC) AS Sequence_ID,
O_CLASSIFICATIONS.CLA_CAT_ID,
O_CLASSIFICATIONS.CLA_SUBJECT_ID
FROM
O_CLASSIFICATIONS
WHERE
O_CLASSIFICATIONS.CLA_SUBJECT_IND = 'P'
AND
O_CLASSIFICATIONS.CLA_TOP_CAT_ID = 'PRIMARY'
AND
O_CLASSIFICATIONS.CLA_CAT_ID <> 'DECLINED'
) PCG
ON PCG.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND PCG.Sequence_ID = 1
WHERE
O_PERSONS.PER_ID LIKE 'P%'
我目前正在尝试编写一个查询,该查询将返回我们系统上客户端的某些详细信息。虽然客户只有一个出生日期,性别和P ID,但他们可能有多个种族(由于数据质量)以及客户群体(这更合理,因为客户的需求可能会发生变化)。但是,对于这些特定项目,我只对最近添加的种族或客户群感兴趣。下面我写了一个查询,它为种族和客户组分配一个行号,计划只返回等于1的那些,因为这些通常是最新的。但是,我遇到了两个问题,其中一个我可以解决,另一个我不太确定。
首先,一些客户不会记录种族或客户群。运行以下查询时,它们返回非常奇怪的行号(通常为数千)。但是,我知道在我的'where'中我可以指定如果客户端组或种族是空的,则返回一行(因为这些将是需要解决的数据质量案例)。
第二个问题稍微棘手,我将尝试用下表来表示。请注意,为了便于输入和理解,我缩写了表格。
P ID Ethnicity PCG RN E RN P
P1 WB OV 1 2
P1 WI OV 2 1
上述客户有两个种族,虽然WB是最新的(因此行号E中的1是正确的)。但是,客户端只记录了一个PCG,但行号在第一行返回2(可以说是我要返回的行)。我不知道为什么虽然我猜是因为ETHNIC.CLA_SUBJECT_ID在O_PERSONS.PER_ID上加入而PER_ID出现两次,这就是为什么它认为该特定字段有两行。但是,即使是这种情况,有没有办法迫使1只出现在一行?或者我可以采用完全不同的方式吗?希望这个查询有道理,如果部分不清楚则道歉。谢谢,
SELECT
O_PERSONS.PER_ID as "P ID",
olm_bo.get_per_name(O_PERSONS.PER_ID) as "Full Name",
O_PERSONS.PER_BIRTH_DATE as "Date of Birth",
case
when O_PERSONS.PER_DECEASED_DATE is null then FLOOR(MONTHS_BETWEEN(sysdate,O_PERSONS.PER_BIRTH_DATE)/12)
else FLOOR(MONTHS_BETWEEN(O_PERSONS.PER_DECEASED_DATE,O_PERSONS.PER_BIRTH_DATE)/12)
end as "Age",
O_PERSONS.PER_DECEASED_DATE as "Date Deceased",
olm_bo.get_gender_desc('P', O_PERSONS.PER_GENDER) as "Gender",
CASE
WHEN ETHNIC.CLA_CAT_ID IN ('C1','C2','C3','C4','ABAN','AIND','AOTH','APKN') THEN 'Asian or Asian British'
ELSE NULL
End as "Ethnicity - Top" ,
CASE
WHEN ETHNIC.CLA_CAT_ID IN ('BAFR','D2') THEN 'African'
ELSE NULL
End as "Ethnicity - Detail" ,
CASE
WHEN PCG.CLA_CAT_ID IN ('ASYLUM','REFUGEE') THEN 'Asylum Seeker/Refugee'
ELSE NULL
End as "PCG",
CASE
WHEN PCG.CLA_CAT_ID IN ('ASYLUM','REFUGEE') THEN 'Asylum Seeker/Refugee'
ELSE NULL
End as "PCG - Top",
CASE
WHEN PCG.CLA_CAT_ID IN ('ASYLUM','REFUGEE') THEN 'Asylum Seeker/Refugee'
ELSE NULL
End as "PCG - DETAIL",
to_char(row_number() over(PARTITION BY ETHNIC.CLA_SUBJECT_ID ORDER BY abs(sysdate - ETHNIC.CLA_DATE_NOTIFIED) asc)) as "Row Number E",
to_char(row_number() over(PARTITION BY PCG.CLA_SUBJECT_ID ORDER BY abs(sysdate - PCG.CLA_DATE_NOTIFIED) asc))as "Row Number P"
FROM
O_PERSONS
LEFT JOIN O_CLASSIFICATIONS ETHNIC ON ETHNIC.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND ETHNIC.CLA_SUBJECT_IND = 'P'
AND ETHNIC.CLA_TOP_CAT_ID = 'ETHNIC'
AND ETHNIC.CLA_CAT_ID <> 'DECLINED'
LEFT JOIN O_CLASSIFICATIONS PCG ON PCG.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND PCG.CLA_SUBJECT_IND = 'P'
AND PCG.CLA_TOP_CAT_ID = 'PRIMARY'
AND PCG.CLA_CAT_ID <> 'DECLINED'
WHERE
/*Following line excludes any clients whose is less than 18)*/
O_PERSONS.PER_BIRTH_DATE > trunc(add_months(O_PERSONS.PER_BIRTH_DATE,-216))
AND O_PERSONS.PER_ID LIKE 'P%'
答案 0 :(得分:1)
您应该在进行加入之前应用ROW_NUMBER()
。
SELECT
* -- Your calculations here, '*' used for brevity
FROM
O_PERSONS
LEFT JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY CLA_SUBJECT_ID ORDER BY CLA_DATE_NOTIFIED DESC) AS sequence_id,
*
FROM
O_CLASSIFICATIONS
WHERE
CLA_SUBJECT_IND = 'P'
AND CLA_TOP_CAT_ID = 'ETHNIC'
AND CLA_CAT_ID <> 'DECLINED'
)
ETHNIC
ON ETHNIC.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND ETHNIC.sequence_id = 1
LEFT JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY CLA_SUBJECT_ID ORDER BY CLA_DATE_NOTIFIED DESC) AS sequence_id,
*
FROM
O_CLASSIFICATIONS
WHERE
CLA_SUBJECT_IND = 'P'
AND CLA_TOP_CAT_ID = 'PRIMARY'
AND CLA_CAT_ID <> 'DECLINED'
)
PCG
ON PCG.CLA_SUBJECT_ID = O_PERSONS.PER_ID
AND PCG.sequence_id = 1
WHERE
/*Following line excludes any clients whose is less than 18)*/
O_PERSONS.PER_BIRTH_DATE > trunc(add_months(O_PERSONS.PER_BIRTH_DATE,-216))
AND O_PERSONS.PER_ID LIKE 'P%'