2014-04-09 3 views
0

SQL Server 2012에서 3 개의 열이있는 테이블이 있습니다. 열 중 하나가 날짜 열입니다. 내가 뭘하고 싶은지 두 개의 지정된 날짜에 대한 테이블을 분할하고 여분의 필드와 함께 하나의 테이블로 병합합니다. 바라건대 아래의 예가 설명됩니다.두 테이블을 만들고 비교하는 SQL Server

내가 현재 가지고있는 것의 예. 나는 (그 수 있는지 확실하지 않습니다) 나를 위해 반환하는 쿼리를 원하는 무엇

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 

답변

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 
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 
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 

이렇게하면 특정 시작일과 종료일에 대해 쉽게 매개 변수화 할 수 있습니다.

또한 PIVOT에 집계가 있어야하기 때문에 현재로서는 MAX을 사용하고 있습니다. 여기에 샘플 데이터에는 최대 한 행이 포함되어 있습니다. 시작일 또는 종료일에 행이 여러 개있을 수있는 경우 처리 방법을 알아야합니다.

+0

오직 날짜별로 하나 개의 회사의 최대 그렇게 MAX 괜찮을한다고 생각이있을 것이다. 그냥하려고합니다. – mHelpMe

+0

+1 다른 제안의 대부분은 공통점이 하나 있습니다. 전체 참여가 누락되었습니다. 피벗은 그 한계를 겪지 않습니다. –

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 
+1

'MIN'과'MAX'를 사용하는 것만으로는'GHI' 행의 값이'70,65'이므로 그 값이 정확하지 않을 수 있습니다. 또한 'cNT' 열은 최대 값과 같지 않은 음수가 아닌 값을 생성하는 데 어려움을 겪고있는 것처럼 보입니다. 원하는 결과를 생성 할 수있는 행이 두 개뿐입니다. –

0

회사를 선택하십시오. 외부 시작 날짜 레코드를 조인하십시오. 외부는 종료 날짜 레코드를 결합합니다. 병합을 사용하여 null 대신 0을 표시하십시오.

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; 
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 
관련 문제