[英]Subquery in SELECT: trying to move to main query
我有以下結構的查詢:
SELECT
PEOPLE.ID,
(
SELECT MIN(R.VALUE) KEEP (DENSE_RANK FIRST ORDER BY R.DATE_OF_CREATION)
FROM REFERENCE_NUMBERS R
WHERE
R.DELETED IS NULL
AND R.PERSON_ID(+) = PEOPLE.ID
) AS PRIMARY_REFERENCE_NUMBER,
PEOPLE.NAME,
PEOPLE.DATE_OF_BIRTH
FROM
PEOPLE
WHERE
PEOPLE.DELETED IS NULL
AND PEOPLE.DATE_OF_BIRTH > TO_DATE('2000-01-01','yyyy-mm-dd')
關鍵是一個人可以有多個參考號:但是我只想為每個人返回一個參考號,而不是多行。 因此,我選擇了最早創建的具有最小值的參考。 我使用主SELECT子句中的子查詢來執行此操作。 上面的代碼有效。
我想看看是否可以將其移動到主查詢中。 從邏輯上講,我本以為應該這樣:
SELECT
PEOPLE.ID,
MIN(R.VALUE) KEEP (DENSE_RANK FIRST ORDER BY R.DATE_OF_CREATION),
PEOPLE.NAME,
PEOPLE.DATE_OF_BIRTH
FROM
PEOPLE,
REFERENCE_NUMBERS R
WHERE
PEOPLE.DELETED IS NULL
AND PEOPLE.DATE_OF_BIRTH > TO_DATE('2000-01-01','yyyy-mm-dd')
AND R.DELETED IS NULL
AND R.PERSON_ID(+) = PEOPLE.ID
但是我得到了錯誤: ORA-00937: not a single-group function
根據https://www.techonthenet.com/oracle/errors/ora00937.php-我需要在主查詢中使用GROUP BY語句。 但是,如果我添加以下行:
GROUP BY R.VALUE
...然后我得到錯誤ORA-00979: not a GROUP BY expression
我覺得我快到了,但是只需要一些額外的指導即可。 有人可以幫忙嗎?
注意:我完全了解“新”樣式的JOIN語法,並且人們傾向於建議使用此語法。 但是我使用“舊式”聯接是有原因的。 以上只是一個最小的可驗證示例。 我的真實代碼要復雜得多,涉及到以復雜方式連接的多個表-當涉及到這種復雜程度時,舊語法更容易理解。 請盡可能提供老式語法的答案。
沒有什么反對在您的SELECT
子句中有該子查詢。 如果要將其移至FROM
子句,請按person_id
,以便每人獲得一行,並對沒有參考號的人使用外部person_id
。
SELECT
p.id,
r.primary_reference_number,
p.name,
p.date_of_birth
FROM people p
LEFT JOIN
(
SELECT person_id, MIN(value) KEEP (DENSE_RANK FIRST ORDER BY date_of_creation)
AS primary_reference_number
FROM reference_numbers
WHERE deleted IS NULL
GROUP BY person_id
) r ON r.person_id = p.id
WHERE p.deleted is null
AND p.date_of_birth > date '2000-01-01;
您可以將每個人與其所有參考文獻一起加入,然后匯總整個混亂情況。 這會使查詢看起來更簡單,但是我不喜歡這種方法。 您希望每人一個參考號,因此請為每個人添加一個參考號。
無論如何,這將是編寫此類查詢的方式:
SELECT
p.id,
MIN(r.value) KEEP (DENSE_RANK FIRST ORDER BY r.date_of_creation)
AS primary_reference_number,
p.name,
p.date_of_birth
FROM people p
LEFT JOIN reference_numbers r ON r.person_id = p.id AND r.deleted IS NULL
WHERE p.deleted is null
AND p.date_of_birth > date '2000-01-01
GROUP BY p.id, p.name, p.date_of_birth;
Oracle強制您為在GROUP BY
子句中選擇的所有非聚合列命名。 根據SQL標准,您僅需要people.id
因為其他列在功能上都依賴於此,但是不幸的是,Oracle沒有此功能。
查詢中的第二列與其他列不同步,按其他列分組可能會如下所示
SELECT
PEOPLE.ID,
MIN(R.VALUE) KEEP (DENSE_RANK
FIRST ORDER BY
R.DATE_OF_CREATION),
PEOPLE.NAME,
PEOPLE.DATE_OF_BIRTH
FROM
PEOPLE P,
REFERENCE_NUMBERS R
WHERE
PEOPLE.DELETED IS NULL
AND PEOPLE.DATE_OF_BIRTH >
TO_DATE('2000-01-01','yyyy-mm-dd')
AND R.DELETED IS NULL
AND R.PERSON_ID(+) = PEOPLE.ID
GROUP BY
P.ID, P.NAME, P.DATE_OF_BIRTH
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.