Sql 交叉应用用法

Sql 交叉应用用法,sql,sql-server-2008,cross-apply,Sql,Sql Server 2008,Cross Apply,我可能不理解交叉应用的全部用法,所以我希望有人能帮助我解决这个问题 这些表如下所示: MARK STAFF_RESOURCE PLACING ---- -------------- ------- ACCOUNT_DAY EMPLOYNO RES_ID MARK_TIME RES_ID PLAC_ID MARK_TYPE PL

我可能不理解交叉应用的全部用法,所以我希望有人能帮助我解决这个问题

这些表如下所示:

MARK                  STAFF_RESOURCE     PLACING
----                  --------------     -------
ACCOUNT_DAY           EMPLOYNO           RES_ID
MARK_TIME             RES_ID             PLAC_ID
MARK_TYPE
PLAC_ID
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
标记表包含如下数据:

MARK                  STAFF_RESOURCE     PLACING
----                  --------------     -------
ACCOUNT_DAY           EMPLOYNO           RES_ID
MARK_TIME             RES_ID             PLAC_ID
MARK_TYPE
PLAC_ID
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连接表:

使用MARK_下方的代码时,时间字段显示错误数据。我必须在某个地方使用连接才能正确吗

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 

我对交叉应用不是很熟悉,但我认为它的用途是相反的。如果交叉应用不是一项要求,您可以这样做:

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

谢谢你,伦纳德!我想你的解决方案对我来说很好。我做了一些调整,看起来很有希望这可能会引起您的兴趣: