SQL按不相关的日期加入两个表

时间:2018-06-05 00:32:49

标签: sql sql-server

我正在寻找加入两个没有公共数据点但常见值(日期)的表。我想要一张表格,列出当天雇用/终止雇员的日期和总数。示例如下:

表1

Hire Date   Employee Number   Employee Name
--------------------------------------------
5/5/2018         10078          Joe
5/5/2018         10077          Adam
5/5/2018         10078          Steve
5/8/2018         10079          Jane
5/8/2018         10080          Mary

表2

Termination Date    Employee Number   Employee Name
----------------------------------------------------
  5/5/2018                10010         Tony
  5/6/2018                10025         Jonathan
  5/6/2018                10035         Mark
  5/8/2018                10052         Chris
  5/9/2018                10037         Sam

期望的结果:

Date    Total Hired Total Terminated
--------------------------------------
5/5/2018      3             1
5/6/2018      0             2
5/7/2018      0             0
5/8/2018      2             1
5/9/2018      0             1

从“添加”日期列的角度来看,获取总计数很容易,只是不确定是最好的方法

3 个答案:

答案 0 :(得分:2)

如果您需要在某个窗口中显示所有日期,则需要将数据加入日历。然后,您可以为数据点留下连接和求和标志。

DECLARE @StartDate DATETIME = (SELECT MIN(ActionDate) FROM(SELECT ActionDate = MIN(HireDate) FROM Table1 UNION SELECT ActionDate = MIN(TerminationDate) FROM Table2)AS X) 
DECLARE @EndDate DATETIME = (SELECT MAX(ActionDate) FROM(SELECT ActionDate = MAX(HireDate) FROM Table1 UNION SELECT ActionDate = MAX(TerminationDate) FROM Table2)AS X) 

;WITH AllDates AS
(
    SELECT CalendarDate=@StartDate
    UNION ALL
    SELECT   DATEADD(DAY, 1, CalendarDate) 
    FROM AllDates 
    WHERE DATEADD(DAY, 1, CalendarDate) <= @EndDate
)


SELECT
    CalendarDate,
    TotalHired = SUM(CASE WHEN H.HireDate IS NULL THEN NULL ELSE 1 END),
    TotalTerminated  = SUM(CASE WHEN T.TerminationDate IS NULL THEN NULL ELSE 1 END)
FROM
    AllDates D
    LEFT OUTER JOIN Table1 H ON H.HireDate = D.CalendarDate
    LEFT OUTER JOIN Table2 T ON T.TerminationDate = D.CalendarDate
/* If you only want dates with data points then uncomment out the where clause
 WHERE
    NOT (H.HireDate IS NULL AND T.TerminationDate IS NULL) 
*/
 GROUP BY
    CalendarDate

答案 1 :(得分:1)

我会使用union all和聚合来执行此操作:

select dte, sum(is_hired) as num_hired, sum(is_termed) as num_termed
from (select hiredate as dte, 1 as is_hired, 0 as is_termed from table1
      union all
      select terminationdate, 0 as is_hired, 1 as is_termed from table2
     ) ht
group by dte
order by dte;

这不包括&#34;缺失&#34;日期。如果你想要那些,日历或递归CTE工作。例如:

with ht as (
      select dte, sum(is_hired) as num_hired, sum(is_termed) as num_termed
      from (select hiredate as dte, 1 as is_hired, 0 as is_termed from table1
            union all
            select terminationdate, 0 as is_hired, 1 as is_termed from table2
           ) ht
      group by dte
     ),
     d as (
      select min(dte) as dte, max(dte) as max_dte)
      from ht
      union all
      select dateadd(day, 1, dte), max_dte
      from d
      where dte < max_dte
     )
select d.dte, coalesce(ht.num_hired, 0) as num_hired, coalesce(ht.num_termed) as num_termed
from d left join
     ht
     on d.dte = ht.dte
order by dte;

答案 2 :(得分:0)

试试这个

SELECT ISNULL(a.THE_DATE, b.THE_DATE) as Date, 
    ISNULL(a.Total_Hire,0) as Total_Hire, 
    ISNULL (b.Total_Terminate,0) as Total_terminate
FROM (SELECT Hire_date as the_date, COUNT(1) as Total_Hire 
    FROM TABLE_HIRE GROUP BY HIRE_DATE) a
FULL OUTER JOIN (SELECT Termination_Date as the_date, COUNT(1) as Total_Terminate 
        FROM TABLE_TERMINATE GROUP BY HIRE_DATE) a
    ON a.the_date = b.the_date