2011-09-27 49 views
1

我有一個SQL查詢其通過項目拉動銷量,按周:顯示一行每個日曆周在SQL

SELECT sls_vendor, 
    sls_item, 
    sls_units, 
    DATEPART(week, sls_week) AS sls_date 
FROM mytable 

假設我在看A 8周的時間,但不是每一個項目/供應商組合具有整整8周的銷售額。但是,我需要我的查詢在該實例中顯示空值。因此,查詢將爲每個項目/供應商組合返回8行,而不管是否存在。

我試着創建一個臨時表,它有28到35的數字,並對上面的查詢執行左連接,但是不顯示空值。結果與單獨運行原始查詢沒有區別。

我可以想到如何使用交叉表/數據透視查詢來完成這項工作,但這不是聯接應該做的事情嗎?

編輯:已更新顯示我的連接查詢。 Datetable只有8行,每個日曆周有1個增量編號。

SELECT * FROM @datetable 
    LEFT JOIN 
    (SELECT 
     sls_vendor, 
     sls_item, 
     sls_units, 
     datepart(week,sls_week) AS sls_date 
    FROM mytable) AS QRY 
    ON temp_week = qry.sls_date 
+1

左連接是你想要的,你可以發佈你的左連接嘗試? – OCary

+1

這應該有效。是否有一個where子句會殺死左連接。例如'WHERE sls_vendor ='Initech'' –

回答

0

你的方法應該只是罰款:

;with mytable as (
    select 1 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/7/2011' as sls_week union 
    select 1 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/14/2011' as sls_week union 
    select 1 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/21/2011' as sls_week 
) 
,datetable as (
    select 28 as temp_week union 
    select 29 union 
    select 30 union 
    select 31 union 
    select 32 union 
    select 33 union 
    select 34 union 
    select 35 
) 
SELECT * FROM datetable 

    LEFT JOIN 

    (SELECT 
     sls_vendor, 
     sls_item, 
     sls_units, 
     datepart(week,sls_week) AS sls_date 
    FROM mytable) AS QRY 

    ON temp_week=qry.sls_date 

輸出:

temp_week sls_vendor sls_item sls_units sls_date 
28   NULL  NULL  NULL  NULL 
29   NULL  NULL  NULL  NULL 
30   NULL  NULL  NULL  NULL 
31   NULL  NULL  NULL  NULL 
32   NULL  NULL  NULL  NULL 
33   1   Test  30   33 
34   1   Test  30   34 
35   1   Test  30   35 

編輯:如果要包括每個銷售商都星期值,包括交加入不同的供應商選擇:

;with mytable as (
    select 1 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/7/2011' as sls_week union 
    select 2 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/14/2011' as sls_week union 
    select 3 as sls_vendor, 'Test' as sls_item, 30 as sls_units, '8/21/2011' as sls_week 
) 
,datetable as (
    select 28 as temp_week union 
    select 29 union 
    select 30 union 
    select 31 union 
    select 32 union 
    select 33 union 
    select 34 union 
    select 35 
) 
SELECT * FROM datetable 
cross join (select distinct sls_vendor from mytable) v 

    LEFT JOIN 

    (SELECT 
     sls_vendor, 
     sls_item, 
     sls_units, 
     datepart(week,sls_week) AS sls_date 
    FROM mytable) AS QRY 

    ON temp_week=qry.sls_date and v.sls_vendor=qry.sls_vendor 

輸出:

temp_week sls_vendor sls_vendor sls_item sls_units sls_date 
28   1   NULL  NULL  NULL  NULL 
29   1   NULL  NULL  NULL  NULL 
30   1   NULL  NULL  NULL  NULL 
31   1   NULL  NULL  NULL  NULL 
32   1   NULL  NULL  NULL  NULL 
33   1   1   Test  30   33 
34   1   NULL  NULL  NULL  NULL 
35   1   NULL  NULL  NULL  NULL 
28   2   NULL  NULL  NULL  NULL 
29   2   NULL  NULL  NULL  NULL 
30   2   NULL  NULL  NULL  NULL 
31   2   NULL  NULL  NULL  NULL 
32   2   NULL  NULL  NULL  NULL 
33   2   NULL  NULL  NULL  NULL 
34   2   2   Test  30   34 
35   2   NULL  NULL  NULL  NULL 
28   3   NULL  NULL  NULL  NULL 
29   3   NULL  NULL  NULL  NULL 
30   3   NULL  NULL  NULL  NULL 
31   3   NULL  NULL  NULL  NULL 
32   3   NULL  NULL  NULL  NULL 
33   3   NULL  NULL  NULL  NULL 
34   3   NULL  NULL  NULL  NULL 
35   3   3   Test  30   35 
+0

因此,爲了讓這段代碼能夠正常工作,我試圖讓你的代碼在sls_vendor列中顯示全部1。你(和我的)發生的事情是,當你有多個供應商時,它不會工作。如果您在代碼上添加第二個供應商到第8/1周,則查詢仍然只返回8行。現在應該返回16.如果對這個 – John

+1

沒有明確的答案,我可能必須重新修改我的VBA。因此,您必須使用「不同的供應商」進行外部聯接才能實現此結果 – pkmiec

+0

感謝您的幫助 – John

0

它適合你嗎?

SELECT sls_vendor, 
    sls_item, 
    sls_units, 
    DATEPART(WEEK, sls_week) AS sls_date 
FROM (
    SELECT VALUE = 28 UNION ALL 
    SELECT VALUE = 29 UNION ALL 
    SELECT VALUE = 30 UNION ALL 
    SELECT VALUE = 31 UNION ALL 
    SELECT VALUE = 32 UNION ALL 
    SELECT VALUE = 33 UNION ALL 
    SELECT VALUE = 34 UNION ALL 
    SELECT VALUE = 35 
) dates 
LEFT JOIN mytable m 
ON dates.value = DATEPART(WEEK, m.sls_week) 
0

下面的查詢工作在Data.StackExchange。 See here。它通過分數得到每週最高的帖子。

WITH weeksyears 
    AS (SELECT w.NUMBER AS week, 
       y.NUMBER AS year 
     FROM (SELECT v.NUMBER 
       FROM MASTER..spt_values v 
       WHERE TYPE = 'P' 
         AND v.NUMBER BETWEEN 1 AND 52) w, 
       (SELECT v.NUMBER 
       FROM MASTER..spt_values v 
       WHERE TYPE = 'P' 
         AND v.NUMBER BETWEEN 2008 AND 2012) y), 
    topPostPerWeek 
    AS (SELECT score, 
       Datepart(week, creationdate)  week, 
       Datepart(YEAR, creationdate)  YEAR, 
       Row_number() OVER (PARTITION BY Datepart(wk, creationdate), 
       Datepart( 
        YEAR, 
       creationdate) ORDER BY score DESC) row 
     FROM posts) 
SELECT * 
FROM weeksyears wy 
     LEFT JOIN topPostPerWeekt 
     ON wy.week = t.week 
      AND wy.YEAR = t.YEAR 
WHERE row = 1 
OR row IS NULL 
ORDER BY wy.YEAR, wy.WEEK 
​ 

2008年38周前的每一行都是空的,除了周和年。還有,如果您編輯查詢和刪除OR row IS NULL查詢將採取行動,就好像它是35周後該行於2011年

然而,一個INNER JOIN

我的猜測是,那裏的財產以後你在哪裏這是指的是「RIGHT」表格。只需加上OR [rightTable.field] IS NULL即可,你會沒事的。