交叉申请使用

时间:2015-03-26 09:14:33

标签: sql sql-server-2008 cross-apply

我可能不了解 CROSS APPLY 的完整用法,所以我希望有人可以帮我解决这个问题。

表格如下:

MARK                  STAFF_RESOURCE     PLACING
----                  --------------     -------
ACCOUNT_DAY           EMPLOYNO           RES_ID
MARK_TIME             RES_ID             PLAC_ID
MARK_TYPE
PLAC_ID

MARK -table包含以下数据:

ACCOUNT_DAY  MARK_TIME                  MARK_TYPE   PLAC_ID
-----------------------------------------------------------
2015-02-05   2015-02-05 13:02:01.029    1           5
2015-02-05   2015-02-05 18:32:21:744    2           5
2015-02-06   2015-02-06 09:02:01.029    1           5
2015-02-06   2015-02-06 14:32:21:744    2           5

如果在 ACCOUNT_DAY (例如2月)上进行范围选择,我想要的结果如下所示 - 这是通过 ID 加入表:

EMPLOYNO   ACCOUNT_DAY   MARK_TIME (1)              MARK_TIME (2)
----------------------------------------------------------------------------
03064      2015-02-05    2015-02-05 13:02:01.029    2015-02-05 18:32:21:744
03064      2015-02-06    2015-02-06 09:02:01.029    2015-02-06 14:32:21:744

使用下面的代码时, MARK_TIME -fields会显示错误的数据。我必须在某处使用 JOIN 来做对吗?

SELECT  DISTINCT stf.EMPLOYNO, A.ACCOUNT_DAY, sta.MARK_TIME, stp.MARK_TIME
FROM SYSADM.STAFF_RESOURCE AS stf  
CROSS APPLY
(
SELECT PLAC_ID
FROM SYSADM.PLACING AS plc
WHERE stf.RES_ID = plc.RES_ID
)C
CROSS APPLY
(
    SELECT mrk.ACCOUNT_DAY, mrk.PLAC_ID
    FROM SYSADM.MARK AS mrk
    WHERE mrk.PLAC_ID = C.PLAC_ID AND (mrk.ACCOUNT_DAY >= CONVERT(DATETIME, '2015-02-01', 102)) AND (mrk.ACCOUNT_DAY < CONVERT(DATETIME, '2015-02-28', 102))
) A
CROSS APPLY
(
    SELECT MARK_TIME
    FROM SYSADM.MARK AS sta 
    WHERE (MARKTYPE = '1') AND (sta.PLAC_ID = C.PLAC_ID) AND (A.ACCOUNT_DAY >= '2015-02-01 00:00:00.000') AND (A.ACCOUNT_DAY <= '2015-02-01 23:59:59.999')
) sta 
CROSS APPLY
(
    SELECT MARK_TIME
    FROM SYSADM.MARK AS stp 
    WHERE (MARKTYPE = '2') AND (stp.PLAC_ID = C.PLAC_ID) AND (stp.MARK_TIME >= '2015-02-01 00:00:00.000') AND (stp.MARK_TIME <= '2015-02-01 23:59:59.999')
) stp 

1 个答案:

答案 0 :(得分:0)

我对CROSS APPLY不是很熟悉,但我想它可以反过来使用它。如果CROSS APPLY不是必需的,您可以这样做:

select EMPLOYNO
     , ACCOUNT_DAY
     , MAX(case when MARK_TYPE = 1 
                then MARK_TIME 
           end) as MARK1
     , MAX(case when MARK_TYPE = 2 
                then MARK_TIME 
           end) as MARK2
from MARK m
join PLACING as p
    on m.PLAC_ID = p.PLAC_ID
join STAFF_RESOURCE s
    on p.RES_ID = s.RES_ID
group by EMPLOYNO
       , ACCOUNT_DAY