2014-10-27 41 views
1

請這個SQL表查詢幫助,我有一個表像SQL多個日期列,價值桶

+---------------------------------------------+ 
| DateCol1 DateCol2 DateCol3 DateCol4 | 
+---------------------------------------------+ 
| 2014-10-01 null  null 2014_10_04 | 
| 2014_10_02 2014_10_01 null 2014_10_04 | 
| 2014_10_02 null 2014_10_01 2014_10_04 | 
| 2014_10_02 null 2014_10_01 null | 
+---------------------------------------------+ 

如果用戶被賦予輸入像沒有fromdate =「2014-10-01」和todate =' 2014-10 = 05' 我必須表現出像

+------------------------------------------------------------------+ 
| ActivityDate DateCol1_Cnt DateCol2_Cnt DateCol3_Cnt DateCol4_Cnt | 
+------------------------------------------------------------------+ 
| 2014-10-01   1   1    2   0  | 
| 2014-10-02   3   0    0   0  | 
| 2014-10-03   0   0    0   0  | 
| 2014-10-04   0   0    0   3  | 
+------------------------------------------------------------------+ 

我要表明的是活動的Particluar日期

我做了什麼至今數

Select 'Date1_ACty' Activity ,dateColumn1 Activity_Date, Count(1) Activity_count 
From MyTable where dateColumn1 between @FromDate and @ToDate 

union all 

Select 'Date2_ACty' Activity ,dateColumn2 Activity_Date, Count(1) Activity_count 
From MyTable where dateColumn2 between @FromDate and @ToDate 

union all ..... 

迄今剩餘列

請幫我很好地解決

問題是我得到DateCol_ActyDateCo2_Acty等作爲列值不是列本身:(

+0

在您展示的模擬結果中,爲什麼2014-10-02會出現兩次?它應該是2014-10-04,對吧?您還在模擬結果中顯示了日期'2014-10-03',但您沒有任何記錄,這意味着您需要有某種日期表,您可以通過左連接對齊該日期表。 .. – 2014-10-27 17:10:58

+0

是的,對不起,2014-10-04。 – Nishanth 2014-10-27 17:17:03

回答

1

是一樣的東西這是你在找什麼?

declare @table table(id int, date1 date, date2 date, date3 date, date4 date) 

declare @min date = '2014-10-01', @max date = '2014-10-04'; 

insert into @table 
values 
(1, '2014-10-01', null, null, '2014-10-04'), 
(2, '2014-10-02', '2014-10-01', null, '2014-10-04'), 
(3, '2014-10-02', null, '2014-10-01', '2014-10-04'), 
(4, '2014-10-02', null, '2014-10-01', null); 

with date1 
as (
    select date1 date_, 
     count(*) count_ 
    from @table 
    where date1 between @min 
      and @max 
    group by date1 
    ), 
date2 
as (
    select date2 date_, 
     count(*) count_ 
    from @table 
    where date2 between @min 
      and @max 
    group by date2 
    ), 
date3 
as (
    select date3 date_, 
     count(*) count_ 
    from @table 
    where date3 between @min 
      and @max 
    group by date3 
    ), 
date4 
as (
    select date4 date_, 
     count(*) count_ 
    from @table 
    where date4 between @min 
      and @max 
    group by date4 
    ), 
dates 
as (
    select @min date_ 
    union all 
    select dateadd(day, 1, date_) 
    from dates 
    where dateadd(day, 1, date_) <= @max 
    ) 
select d.date_, 
    ISNULL(d1.count_, 0) DateCol1_Cnt, 
    ISNULL(d2.count_, 0) DateCol2_Cnt, 
    ISNULL(d3.count_, 0) DateCol3_Cnt, 
    ISNULL(d4.count_, 0) DateCol4_Cnt 
from dates d 
left join date1 d1 on d1.date_ = d.date_ 
left join date2 d2 on d2.date_ = d.date_ 
left join date3 d3 on d3.date_ = d.date_ 
left join date4 d4 on d4.date_ = d.date_; 
+0

注意:連續日期遞歸子查詢在超過100天的範圍內將失敗。爲了解決這個問題,你需要構建一個函數來執行一個循環來創建連續的日期範圍表。 – Will 2014-10-27 17:46:40

1

也許做一個UNPIVOT下一個新的PIVOT將工作?這並不美麗,但它似乎得到了我認爲正確的結果,除了缺少空日期,但可以通過將列中的所有日期加入範圍來解決。

SQL Fiddle

MS SQL Server 2012的架構設置

create table t (id int, DateCol1 date, DateCol2 date, DateCol3 date, DateCol4 date); 
insert t values 
(1, '2014-10-01', null, null, '2014-10-04'), 
(2, '2014-10-02', '2014-10-01', null, '2014-10-04'), 
(3, '2014-10-02', null, '2014-10-01', '2014-10-04'), 
(4, '2014-10-02', null, '2014-10-01', null); 

查詢1

DECLARE @FromDate date = '2014-10-01', @ToDate date = '2014-10-05' 

SELECT 
    ActivityDate, 
    DateCol1 AS DateCol1_Cnt, 
    DateCol2 AS DateCol2_Cnt, 
    DateCol3 AS DateCol3_Cnt, 
    DateCol4 AS DateCol4_Cnt  
FROM (
SELECT d, Dates AS ActivityDate, dates as d2 
FROM (SELECT DateCol1, DateCol2, DateCol3, DateCol4 FROM t) AS p 
UNPIVOT (Dates FOR d IN (DateCol1, DateCol2, DateCol3, DateCol4)) AS unpvt 
) derived 
PIVOT (COUNT(d2) FOR d IN (DateCol1, DateCol2, DateCol3, DateCol4)) pvt 
WHERE ActivityDate BETWEEN @FromDate AND @ToDate 

Results

| ACTIVITYDATE | DATECOL1_CNT | DATECOL2_CNT | DATECOL3_CNT | DATECOL4_CNT | 
|--------------|--------------|--------------|--------------|--------------| 
| 2014-10-01 |   1 |   1 |   2 |   0 | 
| 2014-10-02 |   3 |   0 |   0 |   0 | 
| 2014-10-04 |   0 |   0 |   0 |   3 | 
+0

表現明智的做支點,是否可以接受?對錶包含缺少記錄。 – Nishanth 2014-10-27 17:49:41

+0

@Nishanth我不能說真的;我想做unpivot/pivot可能會很昂貴,但我沒有測試性能。嘗試一下,看看它在你的環境中是否可以接受。 – jpw 2014-10-27 17:52:08