代码之家  ›  专栏  ›  技术社区  ›  Vishal

编写SQL查询以替换值并包括所有日期

  •  2
  • Vishal  · 技术社区  · 15 年前

    我有这个-

    Table DimDate- Date 
    Table Employee-  Id,Name,Points,Date
    

    现在Employee表每天都有积分,除非他们不来……所以日期没有所有日期条目……我的意思是,例如,在一周内,他没有来2天,员工表只有5行……所以我有一个dimdate表,它有到2050年的所有日期,我想加入,并为他没有分数的日期加零。所以我写了这个问题,但不起作用-

    Select E.EmployeeId,D.Date,isNull(E.Points,0) from DimDate D left join Employee E on D.Date between '01-01-2009'and '06-01-2009' where E.EmployeeId=1
    

    上面的查询提供了多个日期,我尝试按日期分组,但不起作用。

    2 回复  |  直到 14 年前
        1
  •  3
  •   John Hartsock    15 年前

    您可能不想在一个日期范围内加入这两个表,只想加入一个日期。然后按日期范围筛选记录集。例子

    Select 
      E.EmployeeId,
      D.Date,
      isNull(E.Points,0)  
    from DimDate D 
    left join Employee E on D.Date = E.Date 
    where E.EmployeeId=1 
      AND D.Date Between '01-01-2009'and '06-01-2009'
    

    编辑:

    Select 
      E.EmployeeId,
      D.Date,
      isNull(E.Points,0)  
    from DimDate D 
    left join Employee E on D.Date = E.Date And E.EmployeeId=1
    where D.Date Between '01-01-2009'and '06-01-2009'
    

    Select 
      E.EmployeeId,
      D.Date,
      isNull(E.Points,0)  
    from DimDate D 
    left join Employee E on D.Date = E.Date 
    where (E.EmployeeId = 1 OR E.EmployeeId is NULL) 
      AND D.Date Between '01-01-2009'and '06-01-2009'
    
        2
  •  2
  •   Mark M    15 年前

    我认为在dimdates表和定义员工的表之间需要交叉联接。这将为您提供包含所有员工/日期组合的记录列表。然后,结果需要保持外部连接到具有员工积分记录的表中。

    类似:

    Select CJ.EmployeeId,CJ.Date,isNull(E.Points,0) 
        from (SELECT EmployeeID, D.Date
              from DimDate D CROSS JOIN [EmployeeDefinitionTable] as edt) as CJ
            left outer join Employee E on CJ.Date =E.Date AND CJ.EmployeeId = E.EmployeeId
    where CJ.Date between '01-01-2009'and '06-01-2009'
      and E.EmployeeId = 1
    

    其中employeeDefinitionable是一个唯一列出所有员工的表(或至少列出此问题语句的ID)。

    这也会捕获没有积分条目的员工。

    如果符合您的要求,那么可以将between语句和/或employeeID筛选上移到交叉联接中。这将使交叉联接更有效。