我的任務是處理 4 個不同的表。我認為我的“邏輯”是正確的,但我認為我未能將各種單獨作業的事物結合在一起。
- 當比較為真時,Case 以某種方式回傳兩行;如果不是,它(正確)只顯示一個。無需連接即可正常作業。
- 計數子查詢單獨作業時,但是當我試圖將它系結在一起時,它會顯示任何內容,從到處顯示相同的數字或顯示太大的數字(可能是倍數或倍數)。
Select Distinct RPD_PERSONS.PERSON_ID "id",
RPD_PERSONS.SURN_TXT ||' '|| RPD_PERSONS.NAME_TXT "Name",
Case ADD_ROLE_PERS.ROLE_CODE When 'Manager'
Then 'yes'
Else 'no'
End "Manager",
(
Select Count(LDD_CERTS.Cert_ID)
From LDD_CERTS
Join LDD_PERS_CERTS
On LDD_PERS_CERTS.CERT_ID = LDD_CERTS.CERT_ID
Where MONTHS_BETWEEN(LDD_CERTS.VALID_TO,SYSDATE)>0
And LDD_PERS_CERTS.CERT_CHANGE_TYPE>=0
) "no. of certificates"
From RPD_PERSONS
Join ADD_ROLE_PERS
On ADD_ROLE_PERS.Person_ID = RPD_PERSONS.Person_ID
Where RPD_PERSONS.Partic_ID = 1
Group By RPD_PERSONS.PERSON_ID, RPD_PERSONS.SURN_TXT ||' '|| RPD_PERSONS.NAME_TXT, ADD_ROLE_PERS.ROLE_CODE
Order By RPD_PERSONS.Person_ID;
這是子查詢,它本身似乎作業得很好。
Select LDD_PERS_CERTS.PERSON_UID,Count(LDD_CERTS.Cert_ID)
From LDD_CERTS
Join LDD_PERS_CERTS
ON LDD_PERS_CERTS.CERT_ID = LDD_CERTS.CERT_ID
Where MONTHS_BETWEEN(LDD_CERTS.VALID_TO,SYSDATE)>0
AND LDD_PERS_CERTS.CERT_CHANGE_TYPE>=0
Group By LDD_PERS_CERTS.PERSON_UID
order by LDD_PERS_CERTS.PERSON_UID;
uj5u.com熱心網友回復:
盡管有一個簡短的查詢來獲取它,但您有很多事情要做,但讓我嘗試總結一下我認為您想要獲取的內容。
您想要一份公司內不同人員的串列,并計算每人有多少 ACTIVE 證書(未過期)。由此,您還想知道他們是否處于管理職位(通過角色)。
問:對于一個既可能是經理,又可能是上級經理的人,您是否希望看到該人同時擔任這兩個角色,因為典型的業務結構可能具有多層管理,或者...只關心見一個人一次,如果他們是經理或其他級別。如果一個人有 3 個或更多角色,你想在每個實體中看到它們怎么辦?如果您的主要關心是經理是或否,則查詢將更加簡化。
現在,您查詢有效證書的計數。MONTHS_BETWEEN() 函式似乎是您在 Oracle 中運行。基于 Valid_To 日期與 sysdate 相比的兩個引數,表明有效日期始終是在未來(即:仍然具有活動證書)。如果是這種情況,您將無法優化查詢,因為函式呼叫不是Sargable 相反,您應該只需要執行 Valid_To > SysDate,換句話說,只需要那些尚未過期的。您甚至可以通過預先匯總每個證書 ID 的所有仍處于活動狀態的證書計數,然后加入人員證書表來更好地為您服務,因為人員證書檢查適用于 cert_change_type >= 0 的所有地方,這可能意味著全部。什么條件下 Cert_Change_Type 會小于零,如果永遠不會,那么 where 子句毫無意義。
接下來,您的 SELECT DISTINCT 查詢需要進行一些調整。您的基于列的選擇與外部人員 ID 沒有背景關系,只是匯總了總證書。個人 ID 與所計算的證書沒有關聯。我只能猜測存在某種關系,例如
RPD_Persons.Person_id = LDD_Pers_Certs.Person_UID
說了這么多,我將有以下表格/索引
table index
LDD_PERS_CERTS ( CERT_CHANGE_TYPE, PERSON_UID, CERT_ID )
LDD_CERTS ( valid_to, cert_id )
RPD_PERSONS ( partic_id, person_id, surn_txt, name_txt )
ADD_ROLE_PERS ( person_id, role_code )
我會嘗試類似的東西
Select
lpc.PERSON_UID,
ValCerts.CertCount
From
( select
Cert_id,
count(*) CertCounts
from
LDD_CERTS
where
Valid_To > sysDate
group by
Cert_id ) ValCerts
JOIN LDD_PERS_CERTS lpc
on ValCerts.Cert_id = lpc.cert_id
Where
lpc.CERT_CHANGE_TYPE >= 0
現在,如果您只關心給定的人是否是經理,我會預先詢問,因為您實際上并沒有回傳一個人的特定角色,只是他們是否是經理的事實。我的最終查詢可能看起來像'
select
p.PERSON_ID id,
max( p.SURN_TXT || ' ' || p.NAME_TXT ) Name,
max( Case when arp.Person_id IS NULL
then 'no' else 'yes' end ) Manager,
max( coalesce( certs.CertCount, 0 )) ActiveCertsForUser
from
RPD_PERSONS p
LEFT Join ADD_ROLE_PERS arp
On p.Person_ID = arp.Person_ID
AND arp.role_code = 'Manager'
LEFT JOIN
( Select
lpc.PERSON_UID,
ValCerts.CertCount
From
( select
Cert_id,
count(*) CertCounts
from
LDD_CERTS
where
Valid_To > sysDate
group by
Cert_id ) ValCerts
JOIN LDD_PERS_CERTS lpc
on ValCerts.Cert_id = lpc.cert_id
AND lpc.CERT_CHANGE_TYPE >= 0 )
) Certs
on p.Person_id = Certs.Person_uid
Where
p.Partic_ID = 1
GROUP BY
p.PERSON_ID
現在,如果 p.partic_id = 1 僅代表 1 個人,那么查詢具有給定證書狀態的所有人等將沒有多大意義。但是如果 Partic_id = 1 代表一組人,例如在給定的關聯中/分公司的話應該沒問題。
有任何問題,請告訴我,我可以修改/更新答案
uj5u.com熱心網友回復:
- CASE 問題:據推測,每個人的 ADD_ROLE_PERS 中可能有多個記錄。如果一個人可以同時運行兩個或多個角色,那么您需要確定您需要使用什么業務邏輯來處理這個問題。如果一個人一次只能擁有一個活動角色,大概有一個“活動/禁用”列或生效日期列,您應該使用它來識別活動記錄(或者,可能存在資料問題)。
- 子查詢應該為結果集中的每一行回傳相同的值,因為它與主查詢完全隔離/獨立。如果您希望它產生與每一行相關的計數,那么您需要將其連接到主表中的表(如果您不知道如何這樣做,請查找相關的子查詢)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/474679.html
上一篇:熊貓對面帶功能
