我正在使用此脚本尝试从下表中检索符合此条件的行,但我认为它不能正常工作。 例如对于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
答案 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。