已存在這樣的數據庫架構SQL問題: alt text http://img156.imageshack.us/img156/9017/2706.png有12子查詢
我需要編寫查詢。
對於每位醫生,我需要2009年平均月訪問費用。 結果是(name_of_doctor,january,febriary,...,12月)
我知道如何做到這一點與12子查詢。存在另一種更方便的方式?
已存在這樣的數據庫架構SQL問題: alt text http://img156.imageshack.us/img156/9017/2706.png有12子查詢
我需要編寫查詢。
對於每位醫生,我需要2009年平均月訪問費用。 結果是(name_of_doctor,january,febriary,...,12月)
我知道如何做到這一點與12子查詢。存在另一種更方便的方式?
我只是做了正常使用GROUP BY選擇在本月,有你的UI手柄顯示它爲12列橫跨。如果你真的需要這樣做,那麼這應該工作:
SELECT
D.name,
AVG(CASE WHEN MONTH(V.visit_date) = 1 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 2 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 3 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 4 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 5 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 6 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 7 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 8 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 9 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 10 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 11 THEN V.cost ELSE NULL END),
AVG(CASE WHEN MONTH(V.visit_date) = 12 THEN V.cost ELSE NULL END)
FROM
Doctors D
INNER JOIN Visits V ON
V.id_doc = D.id AND
V.visit_date BETWEEN '2009-01-01' AND '2009-12-31'
GROUP BY
D.name
ORDER BY
D.name
您可能需要根據您的RDBMS更改日期函數。此外,你可能需要擺弄邊緣情況 - 如果你的日期有一個時間組件,它不會在12/31捕捉到行。
最後,我不知道這個RDBMS之間是否有變化,我現在無法測試,但如果AVG以0代價計算NULL而不是對它們進行折扣,那麼您可能需要自己做averag - SUM( CASE ...成本... 0)/ SUM(CASE ... 1 ... 0)。我希望這是有道理的。
我在postgresql中檢查。看起來不錯。 – 2010-06-27 08:42:47
謝謝。你回答是我需要。 – 2010-06-27 08:54:41
請嘗試以下操作。您可能需要根據您的RDBMS修改日期函數。我假設MySQL,但其餘的應該是通用SQL。
SELECT doctors.name, monthly.average, monthly.month
FROM doctors JOIN (
SELECT AVG(cost), MONTH(visit_date) AS month FROM visits
WHERE YEAR(visit_date) GROUP BY MONTH(visit_date)
) AS monthly ON doctors.id = visits.id_doc
注意,這可能只包括訪問醫生的月份。因此,您可能需要使用IFNULL
或COALESCE
清理輸出。
你可以很容易地做到這一點 - 但它會在一個單獨的行中列出每個月的費用。如果你想在同一行的成本,你可以使用一個樞軸語句。這是SQL 2008如果你需要樞軸我們可以做的吧。如果有一個性能問題使用範圍掃描的日期,而不是使用日期部分
select d.name,datepart(month,v.visit_date) as month,
avg(v.cost) as avgcost
from visits as v inner join
doctors as d on v.id_doc=d.id
and datepart(year,v.visit_date)=2010
group by d.name,datepart(month,v.visit_date)
您使用的是rdbms(sql server,oracle,mysql)嗎? – RRUZ 2010-06-27 00:01:16
我需要可以在大多數rdbms中工作的解決方案。但主要是我們公司使用oracle。 – 2010-06-27 08:40:34