SQL SERVER JOIN ID строки от одного запроса SELECT до второго запроса SELECT - PullRequest
0 голосов
/ 21 марта 2020

Наши водители флота накапливают часы на каждом типе буровой установки, с которой мы работаем.

Этот первый запрос возвращает список идентификаторов водителя для данного маршрута.

declare @day int = 14689; -- Today's "day" (# of days from 1/1/1980)
declare @dep varchar(3) = 'BXBU';
declare @carrier int = 1;
declare @flt int = 703;
declare @legcd char(1) = '';

SELECT  r.DRIVER_ID

FROM ROSTER r

JOIN CRROUTE cr ON (cr.CDATE = r.DUTYDAY 
                and cr.CROUTE = r.DUTYNO)

JOIN CrewLeg cl on (cl.CDATE = cr.CDATE 
                and cl.croute = cr.CROUTE 
                and cl.DAY = r.LEG_DAY 
                and cl.DEP = r.LEG_DEP 
                and cl.CARRIER = r.LEG_CARRIER 
                and cl.flt = r.LEG_FLT 
                and cl.LEGCD = r.LEG_LEGCD)

WHERE   r.leg_day = @day
AND     r.leg_dep = @dep
AND     r.leg_CARRIER = @carrier
AND     r.leg_flt = @flt
AND     r.leg_legcd = @legcd
AND     r.POS <= 2

GROUP BY r.ID,r.leg_day, r.leg_carrier, r.leg_flt, r.leg_legcd

Результат:

1109
1209
1310

Мне нужно передать эти идентификаторы во второй запрос, который возвращает количество накопленных часов для данного идентификатора водителя.

SELECT SUM(LT.BLON - LT.BLOF) as 'HOURSINTYPE'
FROM ROSTER R
INNER JOIN CREWLEG CL on R.LEG_DAY = CL.DAY AND R.LEG_CARRIER = CL.CARRIER AND R.LEG_FLT = CL.FLT AND R.LEG_DEP = CL.DEP AND R.LEG_LEGCD = CL.LEGCD AND R.DUTYDAY = CL.CDATE AND R.DUTYNO = CL.CROUTE
INNER JOIN LEGMAIN LM on R.LEG_DAY = LM.DAY AND R.LEG_CARRIER = LM.CARRIER AND R.LEG_FLT = LM.FLT AND R.LEG_DEP = LM.DEP AND R.LEG_LEGCD = LM.LEGCD
INNER JOIN LEGTIMES LT on R.LEG_DAY = LT.DAY AND R.LEG_CARRIER = LT.CARRIER AND R.LEG_FLT = LT.FLT AND R.LEG_DEP = LT.DEP AND R.LEG_LEGCD = LT.LEGCD
WHERE R.Driver_ID = {{Each_ID_From_1st_Query}} AND LEG_DAY <= @day AND PAX = 0 AND R.LEG_FLT > 0 AND LT.BLON != 0 AND LM.AC IN(8,10)

Я пытаюсь достичь:

ID      Hours
-----   -----
1109    109
1209    530
1310    76

РЕДАКТИРОВАТЬ : Для пояснения, если это поможет, оба запроса соединяют таблицу ROSTER с другим набором объединяемых таблиц. Идентификатор находится в таблице ROSTER в обоих запросах. Первый запрос выбирает идентификаторы, но во втором запросе необходимо использовать эти идентификаторы.

Оба запроса работают нормально независимо друг от друга, если я вручную задаю указанный c идентификатор, который я хочу для второго запроса .

Я знаю, как сделать это с помощью курсора, но я знаю, что должен быть какой-то способ сделать это в JOIN.

Я пробовал несколько подходов:

WITH cte1 AS (
    FIRST QUERY
), cte2 AS (
    SECOND QUERY
) SELECT -- uhm.... what? I can't get the ID from cte1 into cte2.

И я пробовал различные варианты воплощения:

(FIRST QUERY) a
JOIN 
(SECOND QUERY) b
WHERE a.Driver_ID = b.Driver_ID

Но так и не смог заставить работать синтаксис.

У меня нет доступа для изменения базы данных каким-либо образом, поэтому я не могу создать VIEWs для этого.

Этот вопрос очень похож на то, что я пытаюсь сделать, но он не получил ответа:

SQL Сервер - Результаты присоединения одного запроса к первому соответствию результата второго запроса

Ответы [ 2 ]

2 голосов
/ 21 марта 2020

Вы должны иметь возможность использовать выражение IN, чтобы использовать результаты первого запроса во втором. Например, используя CTE:

declare @day int = 14689; -- Today's "day" (# of days from 1/1/1980)
declare @dep varchar(3) = 'BXBU';
declare @carrier int = 1;
declare @flt int = 703;
declare @legcd char(1) = '';

WITH CTE AS (
    SELECT  r.DRIVER_ID
    FROM ROSTER r
    JOIN CRROUTE cr ON (cr.CDATE = r.DUTYDAY 
                    and cr.CROUTE = r.DUTYNO)
    JOIN CrewLeg cl on (cl.CDATE = cr.CDATE 
                    and cl.croute = cr.CROUTE 
                    and cl.DAY = r.LEG_DAY 
                    and cl.DEP = r.LEG_DEP 
                    and cl.CARRIER = r.LEG_CARRIER 
                    and cl.flt = r.LEG_FLT 
                    and cl.LEGCD = r.LEG_LEGCD)
    WHERE   r.leg_day = @day
    AND     r.leg_dep = @dep
    AND     r.leg_CARRIER = @carrier
    AND     r.leg_flt = @flt
    AND     r.leg_legcd = @legcd
    AND     r.POS <= 2
    GROUP BY r.ID,r.leg_day, r.leg_carrier, r.leg_flt, r.leg_legcd
)
SELECT R.Driver_ID, SUM(LT.BLON - LT.BLOF) as 'HOURSINTYPE'
FROM ROSTER R
INNER JOIN CREWLEG CL on R.LEG_DAY = CL.DAY AND R.LEG_CARRIER = CL.CARRIER AND R.LEG_FLT = CL.FLT AND R.LEG_DEP = CL.DEP AND R.LEG_LEGCD = CL.LEGCD AND R.DUTYDAY = CL.CDATE AND R.DUTYNO = CL.CROUTE
INNER JOIN LEGMAIN LM on R.LEG_DAY = LM.DAY AND R.LEG_CARRIER = LM.CARRIER AND R.LEG_FLT = LM.FLT AND R.LEG_DEP = LM.DEP AND R.LEG_LEGCD = LM.LEGCD
INNER JOIN LEGTIMES LT on R.LEG_DAY = LT.DAY AND R.LEG_CARRIER = LT.CARRIER AND R.LEG_FLT = LT.FLT AND R.LEG_DEP = LT.DEP AND R.LEG_LEGCD = LT.LEGCD
WHERE R.Driver_ID IN (SELECT DRIVER_ID FROM CTE)
  AND LEG_DAY <= @day
  AND PAX = 0
  AND R.LEG_FLT > 0
  AND LT.BLON != 0
  AND LM.AC IN(8,10)
GROUP BY R.Driver_ID
0 голосов
/ 21 марта 2020

Я наконец-то добрался и нашел решение. Это помогло и указало в правильном направлении Ником (выше), и с небольшой модификацией я придумал:

declare @day int = 14689; -- Today's "day" (# of days from 1/1/1980)
declare @dep varchar(3) = 'BXBU';
declare @carrier int = 1;
declare @flt int = 703;
declare @legcd char(1) = '';


WITH cte AS (
    SELECT  r.DRIVER_ID
    FROM ROSTER r
    JOIN CRROUTE cr ON (cr.CDATE = r.DUTYDAY and cr.CROUTE = r.DUTYNO)
    JOIN CrewLeg cl ON (cl.CDATE = cr.CDATE and cl.croute = cr.CROUTE and cl.DAY = r.LEG_DAY and cl.DEP = r.LEG_DEP and cl.CARRIER = r.LEG_CARRIER and cl.flt = r.LEG_FLT and cl.LEGCD = r.LEG_LEGCD)
    WHERE   r.leg_day = @day
    AND     r.leg_dep = @dep
    AND     r.leg_CARRIER = @carrier
    AND     r.leg_flt = @flt
    AND     r.leg_legcd = @legcd
    AND     r.POS <= 2
    GROUP BY r.ID,r.leg_day, r.leg_carrier, r.leg_flt, r.leg_legcd
)
SELECT cte.*, hours.*
FROM cte
JOIN (
    SELECT SUM(LT.BLON - LT.BLOF) as 'HOURSINTYPE'
    FROM ROSTER R
    INNER JOIN CREWLEG CL on R.LEG_DAY = CL.DAY AND R.LEG_CARRIER = CL.CARRIER AND R.LEG_FLT = CL.FLT AND R.LEG_DEP = CL.DEP AND R.LEG_LEGCD = CL.LEGCD AND R.DUTYDAY = CL.CDATE AND R.DUTYNO = CL.CROUTE
    INNER JOIN LEGMAIN LM on R.LEG_DAY = LM.DAY AND R.LEG_CARRIER = LM.CARRIER AND R.LEG_FLT = LM.FLT AND R.LEG_DEP = LM.DEP AND R.LEG_LEGCD = LM.LEGCD
    INNER JOIN LEGTIMES LT on R.LEG_DAY = LT.DAY AND R.LEG_CARRIER = LT.CARRIER AND R.LEG_FLT = LT.FLT AND R.LEG_DEP = LT.DEP AND R.LEG_LEGCD = LT.LEGCD
    WHERE LEG_DAY <= @day AND PAX = 0 AND R.LEG_FLT > 0 AND LT.BLON != 0 AND LM.AC IN(8,10)
    GROUP BY r.DRIVER_ID
) hours ON cte.DRIVER_ID = hours.DRIVER_ID

По сути, я переместил DRIVER_ID из предложения WHERE в состояние JOIN

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...