2012-08-30 50 views
2

我有一個查詢,我認爲應該很難做到,但是,現在我花了很多時間,仍然無法按照我想要的方式獲取它,所以我希望這裏有人能幫助我。SQL Server查詢連接多個表

基本上,我需要創建一個報告,爲每個區域提供每個月的價值。但是,並非所有地區每個月都會提供數據;在這種情況下,該視圖應該在該月份和區域返回NULL。因此,認爲需要看是這樣的:

Month  Area Value 
2012-08-01 Area1 2 
2012-08-01 Area2 3 
2012-09-01 Area1 3 
2012-09-01 Area2 NULL 

我的數據表看起來像這樣

Date  Area Value 
2012-08-01 Area1 2 
2012-08-01 Area2 3 
2012-09-01 Area1 3 -- Notice that Area2 is not present for September here 

我有一個表的所有可用區域 此外,我創建了一個表 - 該函數返回從給定日期到現在的所有日期。

例如本聲明

SELECT * FROM Periods_Months('2012-01-01') 

將返回8條記錄,如:

DateValue   Year Month YearMonth 
2012-01-01 00:00:00.000 2012 1 20121 
2012-02-01 00:00:00.000 2012 2 20122 
2012-03-01 00:00:00.000 2012 3 2
2012-04-01 00:00:00.000 2012 4 20124 
2012-05-01 00:00:00.000 2012 5 20125 
2012-06-01 00:00:00.000 2012 6 20126 
2012-07-01 00:00:00.000 2012 7 20127 
2012-08-01 00:00:00.000 2012 8 20128 

基礎上提出的建議,我的查詢現在看起來是這樣的:

WITH months AS (
    SELECT DateValue, YearMonth FROM Periods_Months('2011-01-01') 
) 
select m.DateValue 
     ,CAST(DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,m.DateValue)+1,0)) AS Date) AS DateReported -- Get last day in month 
     ,ResponseTime AS Value 
     ,g.ExternalId 
from GISDB.dbo.GisObjects g 
CROSS JOIN months m 
LEFT OUTER JOIN 
(-- SELECT data from data table, grouped by area and month 
SELECT dbo.YearMonth(CloseDate) AS YearMonth 
     ,MAX(CloseDate) AS LastDate 
     ,GisObjectId 
     ,SUM(DATEDIFF(HH,RegDate,CloseDate)) AS ResponseTime -- calculate response time between start and end data (the value we need) 
FROM DataTable 
WHERE CloseDate IS NOT NULL 
AND  GisObjectId IS NOT NULL 
GROUP BY GisObjectId, dbo.YearMonth(CloseDate) -- group by area and month 
) c 
ON g.ObjectId = c.GisObjectId AND c.YearMonth = m.YearMonth 
WHERE g.CompanyId = 3 AND g.ObjectTypeId = 1 -- reduce the GIS objects that we compare to 
ORDER BY m.DateValue, g.ObjectId 

但結果是(值始終爲空):

DateValue     DateReported Value ExternalId 
2011-01-01 00:00:00.000 31-01-2011 NULL 9994 
2011-01-01 00:00:00.000 31-01-2011 NULL 9993 
2011-01-01 00:00:00.000 31-01-2011 NULL 9992 
2011-01-01 00:00:00.000 31-01-2011 NULL 9991 
2011-01-01 00:00:00.000 31-01-2011 NULL 2339 
2011-01-01 00:00:00.000 31-01-2011 NULL 2338 
2011-01-01 00:00:00.000 31-01-2011 NULL 2337 
2011-01-01 00:00:00.000 31-01-2011 NULL 2336 
2011-01-01 00:00:00.000 31-01-2011 NULL 2335 
2011-01-01 00:00:00.000 31-01-2011 NULL 2334 
2011-01-01 00:00:00.000 31-01-2011 NULL 2327 
2011-01-01 00:00:00.000 31-01-2011 NULL 2326 
2011-01-01 00:00:00.000 31-01-2011 NULL 2325 
2011-01-01 00:00:00.000 31-01-2011 NULL 2324 
2011-01-01 00:00:00.000 31-01-2011 NULL 2323 
2011-01-01 00:00:00.000 31-01-2011 NULL 2322 

+2

哎呀,格式化瘋了。希望它仍然是可以理解的... – user1632306

+4

歡迎來到StackOverflow:如果您發佈代碼,XML或數據樣本,請**在文本編輯器中突出顯示這些行,然後單擊「代碼示例」按鈕(「{}」)編輯器工具欄可以很好地格式化和語法突出顯示它! –

+0

請參閱[編輯幫助](http://stackoverflow.com/editing-help)。 – hims056

回答

2

我想你有你所有的領域,我稱之爲area_table表。

WITH month_table AS (
    SELECT dateValue FROM Periods_Months('2012-01-01') 
) 
select * from area_table 
CROSS JOIN month_table 
LEFT OUTER JOIN myValueTable 
ON area_table.name = myValueTable.area 
AND myValueTable.date = left(convert(varchar(30),month_table.dateValue,120),10) 
ORDER BY myValueTable.Month, myValueTable.area 
+0

該查詢列出了所有區域的數據,但僅列出了每個月有數據的區域。它還需要爲給定月份沒有數據的區域顯示一行 – user1632306

+0

@ user1632306然後您用CROSS JOIN與period_month SELECT爲每個區域的每個行創建每個月份,然後在值表上爲LEFT OUTER JOIN。編輯我的帖子。 – LaGrandMere

+0

@ user1632306您可能需要格式化month_table.dateValue – LaGrandMere

1

假設Areas是你的所有可用區域表,t - 是您的數據表:

SELECT pm.dateValue,Ar.Area, t.value 
FROM Periods_Months('2012-01-01') pm, Areas ar 
    left join t on (pm.dateValue=t.Date) and (ar.Area=t.Area) 
order by pm.DateValue,ar.Area 
+0

那個給我一個「多部分標識符」pm.DateValue「無法綁定」。錯誤 – user1632306