Zapytanie podrzędne programu SQL Server
Chcę połączyć 2 zapytania SQL, pierwsze zapytanie, które chcę pobrać rekordy pracowników z ostatniego miesiąca, a drugie zapytanie, wycofać rekordy z ostatnich 3 miesięcy.
Jest metoda na szaleństwo, pracownicy mogą zmieniać menedżera co miesiąc, ale menedżer z ostatnich miesięcy musi zobaczyć zapisy swojego pracownika z poprzednich 3 miesięcy, nawet jeśli ten pracownik miał innego menedżera w tych miesiącach.
To pierwszy wybór do pobrania w ostatnim miesiącu
/******latest month*****************/
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
where [REPORT_DT]=
(select max([REPORT_DT]) from [EMPLOYEE])
to jest wybór do ściągnięcia w ciągu ostatnich 3 miesięcy
/*********last 3 months*******************/
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
where [REPORT_DT]>=
( DATEADD(M, -3, GETDATE()))
dołączyłbym do 2 selekcji na [EMPLOYEE_ID]. Jakieś pomysły, jak połączyć te 2 zapytania? Dzięki!
Odpowiedzi
Jeśli chcesz dołączyć do dwóch stołów, użyj:
select ecurr.*, e.* -- or whatever columns you like
from employee ecurr join
employee e
on ecurr.employee_id = e.employee_id
where ecurr.report_dt = (select max(e2.report_dt) from employee e2) and
e.report_dt >= dateadd(month, 3, getdate())
order by ecurr.employee_id, e.report_dt;
Dodam, że ten wynik nie ma dla mnie szczególnego sensu. Ale to jest pytanie, które konkretnie zadałeś.
Użyłbym:
SELECT TOP 1 WITH TIES
[REPORT_DT],
[EMPLOYEE_ID],
[EMPLOYEE_NAME],
[LOCATION],
[JOB_DESCRIPTION],
[MANAGER_ID],
FROM [EMPLOYEE]
WHERE
[REPORT_DT] >= DATEADD(M, -3, GETDATE()
ORDER BY
[REPORT_DT] DESC;
Powyższa WHEREklauzula odpowiada Twojemu drugiemu zapytaniu i używamy TOP 1 WITH TIESmetody, aby uzyskać rekordy mające maksymalne REPORT_DTwartości w tabeli.
Możesz również użyć EXISTS:
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
WHERE [REPORT_DT] = (SELECT MAX([REPORT_DT]) FROM [EMPLOYEE]) AND
EXISTS( SELECT 1 FROM [EMPLOYEE]
WHERE [EMPLOYEE_ID] == t.[EMPLOYEE_ID] AND
[REPORT_DT] >= (DATEADD(M, -3, GETDATE())))
Jeśli chodzi o komentarz, to zapytanie powinno rozwiązać problem:
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
WHERE [REPORT_DT] >= (DATEADD(M, -3, GETDATE())) AND
EXISTS( SELECT 1 FROM [EMPLOYEE]
WHERE [EMPLOYEE_ID] == t.[EMPLOYEE_ID] AND
[REPORT_DT] >= (DATEADD(M, -1, GETDATE())))
Pomyślałem, że chcesz otrzymać listę [EMPLOYEE_ID] z ostatniego miesiąca. I uzyskaj ich 3-miesięczną historię pracy. Zgodnie z twoimi obecnymi skryptami selekcji (nie rozumiałem twojego pierwszego skryptu selekcji, czy zawiera listę pracowników, czy nie), możesz to zrobić. Ale to nie jest skuteczne rozwiązanie. Możesz również dodać podwybór w sekcji łączenia. Najpierw spróbuj tego.
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
where [REPORT_DT]>=(DATEADD(M, -3, GETDATE()))
AND [EMPLOYEE_ID] IN (SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
where [REPORT_DT]=
(select max([REPORT_DT]) from [EMPLOYEE]))
Utworzyłem Widok za pomocą poniższego zapytania, a następnie połączyłem to z 3-miesięcznym pytaniem o datę (jest to używane w raporcie obiektów biznesowych) i to załatwiło sprawę.
SELECT
b.[MANAGER_ID],
a.[EMPLOYEE_ID],
a.[START_DT],
a.[EMPLOYEE_NAME],
a.[LOCATION],
a.[JOB_DESCRIPTION],
a.[REPORT_DT]
FROM [EMPLOYEE] b INNER JOIN
[EMPLOYEE] a
ON b.[EMPLOYEE_ID] = a.[EMPLOYEE_ID]
WHERE b.[REPORT_DT] = (SELECT MAX(c.[REPORT_DT])
FROM [EMPLOYEE] c)