Sql Server Count列,右侧的列为空

时间:2014-08-29 09:40:16

标签: sql-server sql-server-2008 tsql count

对于令人困惑的标题感到抱歉,我想不出更清楚的解释方法! 我有一张这样的桌子:

-----------------------------------------------------------------------
| id |  status1   |   status2  |   status3  |   status4  |   status5  | 
-----------------------------------------------------------------------
| 1  | 2012-02-27 | 2012-11-19 |    NULL    |    NULL    |    NULL    |
| 2  | 2012-03-27 | 2012-11-19 |    NULL    |    NULL    |    NULL    |
| 3  | 2013-06-10 | 2013-06-10 | 2013-08-16 |    NULL    |    NULL    |
| 4  | 2013-06-10 | 2013-06-10 |    NULL    | 2013-08-16 |    NULL    |
| 5  | 2013-07-16 | 2013-07-16 | 2013-08-16 |    NULL    |    NULL    |
-----------------------------------------------------------------------

我想要做的是计算每列中值的数量,其中右侧的列中没有更多值。在这种情况下,结果应如下所示:

------------------------------------------------------------------
|  status1   |   status2  |   status3  |   status4  |   status5  | 
------------------------------------------------------------------
|      0     |      2     |      2     |      1     |      0     |
------------------------------------------------------------------

基本上我要做的是跟踪订单的进度并找出它目前处于什么状态。无论要填充的最后一个状态是该行所处的状态。

我的SQL是基本的,任何人都可以帮助我实现这一目标吗?实际上有10种状态,您不能简单地查找每行中的最高日期,因为订单可能会在一天内进入多个状态。

感谢您的帮助!我敢打赌,这是一个相当简单的解决方案,但我不能靠自己去那里!

2 个答案:

答案 0 :(得分:2)

DECLARE @TAB TABLE (ID INT,STATUS1 DATE, STATUS2  DATE,   STATUS3 DATE, STATUS4 DATE, STATUS5 DATE)
INSERT INTO @TAB VALUES 
(1,'2012-02-27','2012-11-19',   NULL     ,   NULL   ,NULL),
(2,'2012-03-27','2012-11-19',   NULL     ,   NULL   ,NULL),
(3,'2013-06-10','2013-06-10','2013-08-16',   NULL   ,NULL),
(4,'2013-06-10','2013-06-10',   NULL     ,'2013-08-16',NULL),
(5,'2013-07-16','2013-07-16','2013-08-16',   NULL   ,NULL)

查询:

SELECT  COUNT([1]) STATUS1,
        COUNT([2]) STATUS2,
        COUNT([3]) STATUS3,
        COUNT([4]) STATUS4,
        COUNT([5]) STATUS5
FROM    
(
SELECT  ID,ISNULL(STATUS5,ISNULL(STATUS4,ISNULL(STATUS3,ISNULL(STATUS2,STATUS1)))) X 
FROM    (
        SELECT  ID,
                CASE WHEN STATUS1 IS NOT NULL THEN 1 ELSE NULL END STATUS1,
                CASE WHEN STATUS2 IS NOT NULL THEN 2 ELSE NULL END STATUS2,
                CASE WHEN STATUS3 IS NOT NULL THEN 3 ELSE NULL END STATUS3,
                CASE WHEN STATUS4 IS NOT NULL THEN 4 ELSE NULL END STATUS4,
                CASE WHEN STATUS5 IS NOT NULL THEN 5 ELSE NULL END STATUS5
        FROM    @TAB
        )LU)LU2 PIVOT (SUM(X) FOR X IN ([1],[2],[3],[4],[5])) PIV

结果:

-------------------------------------------------------------
| status1   | status2   | status3   | status4   | status5   |
+-----------+-----------+-----------+-----------+-----------+
|     0     |    2      |    2      |    1      |    0      |
-------------------------------------------------------------

答案 1 :(得分:1)

;With MyCTE AS
(
SELECT 'Status' + COALESCE 
       (
           CASE WHEN NOT status5 IS NULL THEN '5' ELSE NULL END,
           CASE WHEN NOT status4 IS NULL THEN '4' ELSE NULL END,
           CASE WHEN NOT status3 IS NULL THEN '3' ELSE NULL END,
           CASE WHEN NOT status2 IS NULL THEN '2' ELSE NULL END,
           CASE WHEN NOT status1 IS NULL THEN '1' ELSE NULL END,
           '0'
       ) AS Col
FROM Table1
)
SELECT Col, COUNT(*)
FROM MyCTE
GROUP BY Col

<强> SQL FIDDLE Demo

这将使您的结果成行。之后,您可以PIVOT获得您想要的内容。

;With MyCTE AS
(
SELECT 'Status' + COALESCE 
       (
           CASE WHEN NOT status5 IS NULL THEN '5' ELSE NULL END,
           CASE WHEN NOT status4 IS NULL THEN '4' ELSE NULL END,
           CASE WHEN NOT status3 IS NULL THEN '3' ELSE NULL END,
           CASE WHEN NOT status2 IS NULL THEN '2' ELSE NULL END,
           CASE WHEN NOT status1 IS NULL THEN '1' ELSE NULL END,
           '0'
       ) AS Col
FROM Table1
)
SELECT *
FROM   (
           SELECT Col
           FROM   MyCTE
       ) AS SourceTable
PIVOT  (
           COUNT(Col)
           FOR Col IN ([status1], [status2], [status3], [status4], [status5])
       ) AS PivotTable;

<强> SQL FIDDLE Demo