2014-03-28 75 views
0

我是相當新的SQL(大約9個月左右),所以我很難試圖找出這個問題,使用SQL Server 2012的需要匹配兩個基於日期的SQL表,但我需要檢查日期+ 1

我想看起來像這樣的兩個表匹配:

Shift

Date  | Name | Shift 
    01-01-2013 | Dan Smith | Night 
    01-02-2013 |John Johnson| Night 
    01-03-2013 |John Johnson| Night 

Sales

Date  | Name | Sales 
    01-01-2013 | Dan Smith | 3 
    01-02-2013 | Dan Smith | 5 
    01-02-2013 |John Johnson| 4 
    01-03-2013 |John Johnson| 7 
    01-04-2013 |John Johnson| 2 

問題是,班次表只包括班次的開始日期,這對於兩天以上的夜班來說是有問題的。夜班的銷售顯示爲兩天發生,因爲它們在發生時被加蓋時間戳。這意味着,如果我只是試圖根據姓名和班次日期鏈接表格,並且該人員第二天沒有換班,我將錯過從上午12:00起的任何銷售數據。我正在尋找一種方法來檢查該人是否在第二天換班,如果不是,則將第二天的銷售數據添加到前一天的銷售。

現在我的代碼如下所示:

Select 
    st.Name, 
    st.Date, 
    st.Shift, 
    sl.Sales 
From 
    Shift st 
right join 
    Sales as sl on sl.Name = st.Name 
       and sl.Date = Case 
           When sl.Date = DATEADD(DD, 1, st.Date) 
           Then DATEADD(DD,1, st.Date) 
           Else st.Date 
          End 

,其拾取從當我只是用sales.date = shift.date丟失的數據,但它也有很多重複數據的結束。如果這很簡單,我很抱歉,但我還沒有找到一個簡單的方法來檢查銷售人員是否在第二天沒有換班,然後將該人的下一天銷售數據添加到他們以前的日子。

編輯:期望的結果會是這個樣子:

ShiftDate | Name | Shift | Sales 
01-01-2013 | Dan Smith | Night | 8 
01-02-2013 |John Johnson| Night | 4 
01-03-2013 |John Johnson| Night | 9 

我真的不介意精確的每移的銷售數字不是100%準確,但我確實需要拿起第二天的銷售數據,如果他們第二天沒有換班的話。

我會喜歡模型的改變,因爲它會絕對解決這個問題,並一直在努力獲得一個現在。不幸的是,銷售數據來自外部來源,然後我將其導入到我們的數據庫中,並且他們迄今爲止不願/不能提供準確的時間戳。

+0

Yakshemash!你不再是新人了。我只做3個月的SQL :)你的數據庫需要包含所有的時間戳。 –

+1

你可以發佈想要的結果嗎? – Lamak

+1

我們如何知道如何分配約翰約翰遜'01-03-2013'的銷售額?,您將它展示給'01-03-2013'班,但它也可能是'01-02- 2013'由你自己的規則 – Lamak

回答

0

好吧,這可以作爲你想要的結果:

;WITH Sales2 AS 
(
    SELECT A.*, CASE WHEN B.[Date] IS NULL THEN 1 ELSE 0 END LastShift 
    FROM Sales A 
    LEFT JOIN Sales B 
     ON A.Name = B.Name 
     AND A.[Date] = DATEADD(DAY,-1,B.[Date]) 
) 
SELECT A.[Date], 
     A.Name, 
     A.Shift, 
     SUM(B.Sales) Sales 
FROM Shift A 
LEFT JOIN Sales2 B 
    ON A.Name = B.Name 
    AND CASE 
     WHEN A.Shift <> 'Night' AND A.[Date] = B.[Date] 
      THEN 1 
     WHEN A.Shift = 'Night' AND B.LastShift = 0 AND A.[Date] = B.[Date] 
      THEN 1 
     WHEN A.Shift = 'Night' AND B.LastShift = 1 AND A.[Date] = DATEADD(DAY,-1,B.[Date]) 
      THEN 1 
     ELSE 0 
     END = 1 
GROUP BY A.[Date], 
     A.Name, 
     A.Shift 

Here is a sqlfiddle與此解決方案的演示。

而且resuls是:

╔═════════════════════════╦══════════════╦═══════╦═══════╗ 
║   Date   ║  Name  ║ Shift ║ Sales ║ 
╠═════════════════════════╬══════════════╬═══════╬═══════╣ 
║ 2013-01-01 00:00:00.000 ║ Dan Smith ║ Night ║  8 ║ 
║ 2013-01-02 00:00:00.000 ║ John Johnson ║ Night ║  4 ║ 
║ 2013-01-03 00:00:00.000 ║ John Johnson ║ Night ║  9 ║ 
╚═════════════════════════╩══════════════╩═══════╩═══════╝ 
0

您有模特兒問題。我建議你定義另一個表格來定義實際的開始和結束日期。 YOu將能夠使用該表格將銷售安排在正確的日期和相應的班次中。

+0

只要!銷售數據來自外部來源(不問),然後我將其導入到我們的數據庫中,他們沒有/不願意/沒有能力提供精確的時間戳。這是我一直試圖修復幾個月的問題,但可能不會發生。 –

0

我想你可能需要一個更好的模型。看看這是否有效?

SELECT 
    sft.Name, 
    sft.Date, 
    sft.Shift, 
    sum(sls.Sales)  
FROM Sales sls 
LEFT JOIN Shift sft 
    ON sls.Date >= sft.Date 
WHERE (sls.Date = sft.Date OR sls.Date NOT IN 
     (SELECT Date FROM Shift WHERE Date = sls.Date AND Name = sls.Name)) 
GROUP BY 
    sft.Name, 
    sft.Date, 
    sft.Shift 
+0

列名稱'Sales'無效。無法對包含聚合或子查詢的表達式執行聚合函數。 –

+0

@BoratSagdiyev謝謝我做了一些改變。 – NaNey

+0

ON sls.Date> = sft.Sales - 無效的列名稱'Sales'。 –