2015-03-26 3 views
1

Возможно, я не понимаю полного использования CROSS APPLY, поэтому я надеюсь, что кто-то может помочь мне решить эту проблему.Использование CROSS APPLY

таблиц выглядеть следующим образом:

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

MARK -столы имеют данные, как это:

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 (например, февраль), выглядит так: это присоединение к столам по идентификаторам :

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-fieldss показывает неправильные данные. Должен ли я использовать 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

Это может вас заинтересовать: http://explainextended.com/2009/07/16/inner-join-vs-cross-apply/ –

ответ

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 
+0

Спасибо Леннарт! Я думаю, ваше решение будет работать отлично для меня. Я сделал некоторые корректировки, и это выглядит многообещающе! :) – WhoCan