SQL Server创建两个表并进行比较

时间:2014-04-09 10:39:07

标签: sql sql-server

我有一个包含3列的表(在SQL Server 2012中)。其中一列是日期列。我想要做的是将表拆分两个指定的日期,并将它们合并到一个带有额外字段的表中。希望下面的例子能够解释。

我目前拥有的例子。

Company   date         no_employees
ABC       2014-05-30   35
DEF       2014-05-30   322
GHI       2014-05-30   65
JKL       2014-05-30   8
MNO       2014-05-30   30
ABC       2014-01-01   33
DEF       2014-01-01   301
GHI       2014-01-01   70
MNO       2014-01-01   30

我想要一个查询返回给我(不确定是否可能),

Company   start date no_employees   end date no_employees  diff
ABC       33                        35                       2
DEF       301                       322                      21
GHI       70                        65                       -5
JKL       0                         8                        8
MNO       30                        30                       0

6 个答案:

答案 0 :(得分:1)

PIVOT(和COALESCE生成0)似乎是这样做的:

declare @t table (Company char(3),[date] date,no_employees int)
insert into @t(Company,[date],no_employees) values
('ABC','2014-05-30',35  ),
('DEF','2014-05-30',322 ),
('GHI','2014-05-30',65  ),
('JKL','2014-05-30',8   ),
('MNO','2014-05-30',30  ),
('ABC','2014-01-01',33  ),
('DEF','2014-01-01',301 ),
('GHI','2014-01-01',70  ),
('MNO','2014-01-01',30  )

select Company,
       COALESCE(start,0) as start,
       COALESCE([end],0) as [end],
       COALESCE([end],0)-COALESCE(start,0) as diff
from
    (select
        Company,
        CASE WHEN [date]='20140530' THEN 'end'
            ELSE 'start' END as period,
        no_employees
    from @t
    where [date] in ('20140101','20140530')
    ) t
    pivot (MAX(no_employees) for period in ([start],[end])) u

结果:

Company start       end         diff
------- ----------- ----------- -----------
ABC     33          35          2
DEF     301         322         21
GHI     70          65          -5
JKL     0           8           8
MNO     30          30          0

这可以很容易地参数化,以便使用特定的开始和结束日期。

此外,目前我正在使用MAX因为我们必须在PIVOT中有一个聚合,即使这里示例数据最多包含一行。如果开始或结束日期可能存在多行,我们需要知道您希望如何处理。

答案 1 :(得分:0)

Create Table #temp(Company varchar(10), CDate date,emp int)      

Select T1.Company,T1.emp,T2.emp,(T1.emp-T2.emp) Diff
from #temp T1
    inner join #temp T2 On T1.Company=T2.Company and T1.CDate<T2.CDate
Order by T1.Company,T1.CDate

答案 2 :(得分:0)

declare @t table (Company char(3),[date] date,no_employees int)
insert into @t(Company,[date],no_employees) values
('ABC','2014-05-30',35  ),
('DEF','2014-05-30',322 ),
('GHI','2014-05-30',65  ),
('JKL','2014-05-30',8   ),
('MNO','2014-05-30',30  ),
('ABC','2014-01-01',33  ),
('DEF','2014-01-01',301 ),
('GHI','2014-01-01',70  ),
('MNO','2014-01-01',30  )

select Company,MIN(no_employees),MAX(no_employees),CASE WHEN MIN(no_employees) = MAX(no_employees) then  MAX(no_employees) else
MIN(no_employees) - MAX(no_employees) end as cNT  from @t
GROUP BY Company

答案 3 :(得分:0)

选择公司。外部加入开始日期记录。外部加入结束日期记录。使用coalesce显示0而不是null。

select 
  company, 
  coalesce(rec20140101.no_employees, 0) as empno_start,
  coalesce(rec20140530.no_employees, 0) as empno_end
from 
(
  select distinct company
  from records
) companies -- or use a company table if you have one
left join
(
  select company, no_employees 
  from records 
  where recorddate = '2014-01-01'
) rec20140101
  on rec20140101.company = companies.companyrec
left join
(
  select company, no_employees 
  from records 
  where recorddate = '2014-05-30'
) rec20140530
  on rec20140530.company = companies.company);

编辑:这是一种只扫描一次表格的方法。它甚至更短一些; - )

select
  company,
  coalesce(min( case when recorddate = '2014-05-30' then no_employees end ), 0) as empno_start,
  coalesce(min( case when recorddate = '2014-01-01' then no_employees end ), 0) as empno_end
from records
group by company;

答案 4 :(得分:0)

试试这个:

;with cte as
(select 
 COALESCE(src.company, tgt.company) company 
 isnull(tgt.no_employees,0) 'start date no_employees', 
 isnull(src.no_employees , 0) 'end date no_employees'
 from
 tbl src 
 full outer join tbl tgt on src.company = tgt.company and src.date <> tgt.date
 where (src.date = (select max(date) from tbl) or src.date is null)
 and (tgt.date = (select min(date) from tbl) or tgt.date is null)
)
select *, [end date no_employees] - [start date no_employees] diff
from cte

答案 5 :(得分:0)

declare @lowdate date = '2014-01-01'
declare @highdate date = '2014-05-30'

;with x as
(
  select company, min(no_employees) no_employees
  from @t records 
  where recorddate =  @lowdate
  group by company
), y as
(
  select company, max(no_employees)  no_employees
  from @t records 
  where recorddate = @highdate
  group by company
)
select coalesce(x.company, y.company) company, 
coalesce(x.no_employees, 0) start_no_employees, 
coalesce(y.no_employees, 0) end_no_employees, 
coalesce(y.no_employees, 0) - coalesce(x.no_employees, 0) diff
from 
x full outer join y
on
x.company = y.company