什么脚本会返回所需的数据?

时间:2014-05-07 12:13:10

标签: sql sql-server tsql sql-server-2005

我正在使用此脚本尝试从下表中检索符合此条件的行,但我认为它不能正常工作。 例如对于CARE_ID 3907,正在返回EVENT_ID 3593的行,我相信这应该是3591。 该脚本必须与相当老的学校兼容SQL2000。

 SELECT nbe.CARE_ID, nbe.EVENT_DATE, nbe.EVENT_ID, nbe.EVENT_TYPE
   FROM vwNBOCAP_BASE_EVENTS nbe
        JOIN
            (SELECT CARE_ID, EVENT_TYPE, MAX(EVENT_DATE) as maxx
               FROM vwNBOCAP_BASE_EVENTS
              GROUP BY CARE_ID, EVENT_TYPE
             HAVING EVENT_TYPE = 'CP'
            ) tmax
            ON nbe.CARE_ID = tmax.CARE_ID AND nbe.EVENT_DATE = tmax.maxx
  WHERE nbe.EVENT_TYPE = 'CP'
    AND EVENT_DATE <= 
        (SELECT MIN(EVENT_DATE)
           FROM vwNBOCAP_BASE_EVENTS
          WHERE CARE_ID = nbe.CARE_ID
            AND EVENT_TYPE IN ('BR','CH','SU', 'TE'))

UNION ALL

 SELECT t.CARE_ID, t.EVENT_DATE, MAX(t.EVENT_ID) AS EVENT_ID, t.EVENT_TYPE
   FROM vwNBOCAP_BASE_EVENTS t
        JOIN 
            (SELECT CARE_ID, MAX(EVENT_DATE) as maxx, EVENT_TYPE
               FROM vwNBOCAP_BASE_EVENTS
              GROUP BY CARE_ID, EVENT_TYPE
             HAVING EVENT_TYPE = 'CP'
            ) tmax
            ON t.CARE_ID = tmax.CARE_ID AND t.EVENT_DATE = tmax.maxx
  GROUP BY t.CARE_ID, t.EVENT_DATE, t.EVENT_TYPE
 HAVING t.EVENT_TYPE = 'CP'
    AND t.CARE_ID NOT IN
        (SELECT CARE_ID
           FROM
                (SELECT nbe.CARE_ID, nbe.EVENT_DATE, MAX(nbe.EVENT_ID) AS EVENT_ID,
                        nbe.EVENT_TYPE
                   FROM vwNBOCAP_BASE_EVENTS nbe
                        JOIN
                            (SELECT CARE_ID, EVENT_TYPE, MAX(EVENT_DATE) as maxx
                               FROM vwNBOCAP_BASE_EVENTS
                              GROUP BY CARE_ID, EVENT_TYPE
                             HAVING EVENT_TYPE = 'CP') tmax
                            ON nbe.CARE_ID = tmax.CARE_ID AND nbe.EVENT_DATE = tmax.maxx
                  GROUP BY nbe.CARE_ID, nbe.EVENT_DATE, nbe.EVENT_TYPE
                 HAVING nbe.EVENT_TYPE = 'CP'
                    AND EVENT_DATE <=
                        (SELECT MIN(EVENT_DATE)
                           FROM vwNBOCAP_BASE_EVENTS
                          WHERE CARE_ID = nbe.CARE_ID
                            AND EVENT_TYPE IN ('BR','CH','SU','TE'))
                )a
        )

评论

--For each CARE_ID with at least one EVENT_TYPE of 'CP' before an 
--EVENT_TYPE of 'BR', 'CH', 'SU', 'TE' return the most recent instance 
--of 'CP' - i.e. the last CP before the first 'BR', 'CH', 'SU' or 'TE' 
--(the tie breaker for 'CP' is MAX(EVENT_ID) and MIN(EVENT_ID) 
--for 'BR', 'CH', 'SU' or 'TE')

--For each CARE_ID with at least one EVENT_TYPE of 'CP' 
--that isn't included above return the most recent 'CP' 
--(the tie breaker for 'CP' is MAX(EVENT_ID))

输出

CARE_ID EVENT_ID    EVENT_DATE          EVENT_TYPE
3       117         09/04/2010 00:00    CP
3       104         11/04/2010 00:00    CH
3       190         16/04/2010 00:00    SU
3       16          12/07/2010 00:00    BR
3       17          13/07/2010 00:00    BR
3       18          13/07/2010 00:00    BR
78      11          27/07/2009 00:00    CH
78      9           28/07/2009 00:00    TE
78      706         08/12/2010 00:00    CP
78      707         09/12/2010 00:00    CP
107     93          23/02/2010 00:00    CP
107     1474        21/09/2012 00:00    SU
206     84          28/07/2009 00:00    CP
206     85          21/08/2009 00:00    CP
364     1122        26/01/2011 00:00    CP
364     1136        18/02/2011 00:00    CP
364     569         19/02/2011 00:00    SU
364     774         23/08/2012 00:00    CH
367     151         21/06/2010 00:00    CP
367     247         01/07/2010 00:00    SU
369     248         26/07/2010 00:00    SU
369     152         27/07/2010 00:00    CP
369     117         28/07/2010 00:00    CH
380     277         08/07/2011 00:00    TE
481     63          07/09/2010 00:00    TE
481     194         07/09/2010 00:00    CP
481     289         07/09/2010 00:00    SU
1535    924         11/01/2011 00:00    CP
1536    925         11/01/2011 00:00    CP
1565    979         09/01/2011 00:00    CP
1623    531         27/01/2011 00:00    SU
1661    216         25/01/2011 00:00    CH
1661    217         25/01/2011 00:00    CH
1661    1046        25/01/2011 00:00    CP
1661    95          01/02/2011 00:00    TE
1661    218         01/02/2011 00:00    CH
1662    220         25/01/2011 00:00    CH
1662    1047        25/01/2011 00:00    CP
1662    221         01/02/2011 00:00    CH
1663    97          25/01/2011 00:00    TE
1663    1048        25/01/2011 00:00    CP
1663    98          01/02/2011 00:00    TE
1663    223         01/02/2011 00:00    CH
1665    1049        25/01/2011 00:00    CP
1666    100         23/01/2011 00:00    TE
1666    1050        23/01/2011 00:00    CP
1666    225         01/02/2011 00:00    CH
1781    1868        04/10/2010 00:00    CP
1781    1869        04/10/2010 00:00    CP
1781    1870        04/10/2010 00:00    CP
1781    1052        10/02/2011 00:00    SU
1781    1867        25/03/2011 00:00    CP
1781    2103        20/01/2014 00:00    CP
1903    1551        02/06/2011 00:00    CP
1903    1552        16/07/2011 00:00    CP
2187    1475        20/01/2011 00:00    CP
2187    803         29/01/2011 00:00    SU
2294    66          12/06/2011 00:00    BR
2294    1697        16/07/2011 00:00    CP
2294    1698        17/07/2011 00:00    CP
3907    3591        05/01/2014 00:00    CP
3907    945         09/01/2014 00:00    CH
3907    1821        13/01/2014 00:00    SU
3907    3592        14/01/2014 00:00    CP
3907    3593        14/01/2014 00:00    CP

1 个答案:

答案 0 :(得分:0)

第一条评论下载SQL Server 2000 。 SQL Server 2014的发布是在1个月前发布的。但是,作为一名DBA,我曾与未计划未来的业务部门合作过。他们想要使用该软件,直到它不受支持为止。

我的第二条评论将临时表简单地用于查询。虽然您可能无法将最终结果注入软件,但它会留下可用于调查和调试的跟踪表。

不要忘记此代码可以包装在返回结果集的存储过程中。如果是报告,只需更改主叫代码。

所以这里的重写比上面简单得多。

max和min查询有自己的表。我注意到最小事件类型标准与最大值不同。

我在分组上添加了回事件类型。这可以通过另一个MIN()调用在子查询中消除。但是,为了保持一致性,还有一些事情需要说明。

--
-- Create temp table for max event date
--

SELECT 
    CARE_ID, 
    EVENT_TYPE, 
    MAX(EVENT_DATE) as maxx
INTO
    #tmax
FROM 
    vwNBOCAP_BASE_EVENTS
GROUP BY 
    CARE_ID, EVENT_TYPE
HAVING 
    EVENT_TYPE = 'CP'
GO


--
-- Create temp table for min event date
--

SELECT 
    CARE_ID, 
    EVENT_TYPE, 
    MIN(EVENT_DATE) as minn
INTO
    #tmin
FROM 
    vwNBOCAP_BASE_EVENTS
GROUP BY 
    CARE_ID, EVENT_TYPE
HAVING 
    EVENT_TYPE IN ('BR','CH','SU', 'TE')
GO

实际核心查询现在更清晰了。我从union上的最后一个子查询中删除了分组,因为你只需要CARE ID。

--
-- Actual query
-- 

SELECT  
    nbe.CARE_ID, 
    nbe.EVENT_DATE, 
    nbe.EVENT_ID, 
    nbe.EVENT_TYPE
FROM    
    vwNBOCAP_BASE_EVENTS nbe
JOIN 
    #tmax 
ON 
    nbe.CARE_ID = #tmax.CARE_ID AND 
    nbe.EVENT_DATE = #tmax.maxx
WHERE 
    nbe.EVENT_TYPE = 'CP' AND 
    EVENT_DATE <= 
    (SELECT MIN(#tmin.minn) FROM #tmin WHERE #tmin.CARE_ID = nbe.CARE_ID)


UNION ALL


SELECT  
    t.CARE_ID, 
    t.EVENT_DATE, 
    MAX(t.EVENT_ID) AS EVENT_ID, 
    t.EVENT_TYPE
FROM    
    vwNBOCAP_BASE_EVENTS t 
JOIN 
    #tmax 
ON 
    nbe.CARE_ID = #tmax.CARE_ID AND 
    nbe.EVENT_DATE = #tmax.maxx
GROUP BY 
    t.CARE_ID, 
    t.EVENT_DATE, 
    t.EVENT_TYPE
HAVING
    t.EVENT_TYPE = 'CP' AND
    t.CARE_ID NOT IN
(
SELECT 
    DISTINCT CARE_ID 
FROM    
    vwNBOCAP_BASE_EVENTS nbe
JOIN  
    #tmax
ON 
    nbe.CARE_ID = #tmax.CARE_ID 
    AND nbe.EVENT_DATE = #tmax.maxx
WHERE
    nbe.EVENT_TYPE = 'CP' AND 
    EVENT_DATE <= 
    (SELECT MIN(#tmin.minn) FROM #tmin WHERE #tmin.CARE_ID = nbe.CARE_ID)
)

同样,我对你的业务逻辑一无所知;但是,清理后的版本应该更容易调试。

我选择回答这个问题,因为我今晚在美国缅因州 - 有效使用临时表的PASS SQL Server用户组发言。

这个问题适合我的主题。

祝你好运,狡猾的dba。