SQL 級別的計算
我有這個查詢:
SELECT * FROM ( SELECT COUNT(lead_status) as 'Pending files' FROM vw_file_registrationlist WHERE lead_status_id = "1" || lead_status_id="2" || lead_status_id="4" || lead_status_id="5" || lead_status_id="6" )A, ( SELECT COUNT(lead_status) as 'Completed files' FROM vw_file_registrationlist WHERE lead_status_id = "3" )B , ( select DISTINCT employee_name From vw_file_registrationlist where employee_name='anna' )C
我得到的結果是
名稱 待處理文件 已完成文件 ---- ------------- --------------- 安娜 3 2
我需要計算
pending files / total files * 100
. 可能嗎?
這不對,
WHERE lead_status_id = "1" || lead_status_id="2" || lead_status_id="4" || lead_status_id="5" || lead_status_id="6"
你想要的是,
WHERE lead_status_id IN (1,2,4,5,6);
認真地,學習使用空格並為您的程式碼感到自豪。選擇一個約定(將所有 sql 標記大寫,並將所有標識符小寫)即使你沒有得到這樣寫的 sql..
)a )b
你是從哪裡得到的?..
SELECT (...) AS t, (...) AS x
空格和AS
! 說了這麼多,我想你想要這樣的東西,SELECT count(lead_status) FILTER (WHERE lead_status_id IN (1,2,4,5,6)) as 'Pending files', count(lead_status) FILTER (WHERE lead_status_id = 3) AS 'Completed files', any(employee_name = 'anna') AS has_anna FROM vw_file_registrationlist;
您提供了對提供您正在使用的 DBMS 的請求的答复,這使得提供絕對適合您的 SQL 變得困難。
無論 DBMS 是什麼,類似於 Even Carroll 提出的東西應該比您的原始查詢執行得更好,因為它執行的是單個查詢,而不是三個單獨的查詢。
我將把他的查詢改寫成我認為更通用的形式(我通常在 SQL Server 中工作,我不認為他所做的一切都在那里工作)。
SELECT 'anna' as [Name] ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id IN (1,2,4,5,6) THEN 1 ELSE 0 END) AS 'Pending files' ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id = 3 THEN 1 ELSE 0 END) AS 'Completed files' FROM vw_file_registrationlist WHERE EXISTS (SELECT 1 FROM vw_file_registrationlist WHERE employee_name = 'anna') ;
現在,這應該執行以下操作:
如果沒有記錄 where
employee_name
is'anna'
,則不返回任何行。否則,它返回:
'anna'
- 為 1、2、4、5
lead_status_id
或 6lead_status
且不為 NULL的行數- 行數 where
lead_status_id
為 3,且 wherelead_status
不為 NULL該
COUNT()
函式在對單個列(而不是COUNT(*)
)進行操作時,會計算該列的非 NULL 出現次數。由於我正在使用CASE
語句過濾數據並SUM
為應該計算的每一行計算值 1,因此我需要確保我沒有lead_status
手動計算為 NULL 的行。如果您想要所有行,無論是否lead_status
為NULL,或者是否lead_status
為NOT NULL
列,您都可以消除WHEN lead_status IS NULL THEN 0
部分。好的,現在來獲取您的計算值。你有兩個選擇:
使用等式中的聚合函式直接計算值:
SELECT 'anna' as [Name] ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id IN (1,2,4,5,6) THEN 1 ELSE 0 END) AS 'Pending files' ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id = 3 THEN 1 ELSE 0 END) AS 'Completed files' , SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id IN (1,2,4,5,6) THEN 1 ELSE 0 END) /SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id = 3 THEN 1 ELSE 0 END) *100 AS 'Calculated Value' FROM vw_file_registrationlist WHERE EXISTS (SELECT 1 FROM vw_file_registrationlist WHERE employee_name = 'anna') ;
這應該會給你你想要的答案。但是,從維護的角度來看,這並不是很好(如果掛起或已完成文件的定義發生變化,您必須進行兩次更改),並且很難遵循。所以,還有:
將查詢包裝在另一個查詢中以執行最終計算:
SELECT employee_name AS 'Name' ,pending_count AS 'Pending files' ,completed_count AS 'Completed files' ,(pending_count * 100 / completed_count) AS `Calculated value' FROM ( SELECT 'anna' as employee_name ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id IN (1,2,4,5,6) THEN 1 ELSE 0 END) AS pending_count ,SUM(CASE WHEN lead_status IS NULL THEN 0 WHEN lead_status_id = 3 THEN 1 ELSE 0 END) AS completed_count FROM vw_file_registrationlist WHERE EXISTS (SELECT 1 FROM vw_file_registrationlist WHERE employee_name = 'anna') ) t ;
這只是讓您使用子查詢中的列名編寫方程,而不必使用完整的聚合表達式。由於表達式現在只使用一次,潛在的維護問題就消失了。另外,這更具可讀性。
任何一個都應該工作。有可能其中一個會表現得更好;如果要返回大量行(而不是像您的範例中那樣的一行),則第一個選項(直接在計算中使用聚合值)可能會執行得更好。也就是說,即使這樣,差異也可能足夠小,以至於第二種選擇的維護優勢可能會使其在實踐中變得更好。