需要根据日期匹配两个SQL表,但我需要检查日期+ 1

时间:2014-03-28 17:24:32

标签: sql sql-server date

我是SQL的新手(大约9个月左右),所以我很难用SQL Server 2012来解决这个问题。

我试图匹配两个看起来像这样的表:

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%准确,我真的不介意,但如果他们没有转变,我确实需要提取第二天的销售数据第二天。

我会喜欢模型更改,因为它绝对可以解决这个问题并且已经努力争取一段时间了。不幸的是,销售数据来自外部源,然后我将其导入我们的数据库,到目前为止他们一直不愿意/无法提供精确的时间戳。

3 个答案:

答案 0 :(得分:0)

您有模型问题。我建议你定义另一个表来定义实际的开始和结束日期。您可以使用该表将销售额放在正确的日期和相应的班次中。

答案 1 :(得分: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

答案 2 :(得分: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以及此解决方案的演示。

结果是:

╔═════════════════════════╦══════════════╦═══════╦═══════╗
║          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 ║
╚═════════════════════════╩══════════════╩═══════╩═══════╝