Sottoquery di SQL Server
Voglio combinare 2 query SQL, la prima query che voglio estrarre i record dei dipendenti per l'ultimo mese e la seconda query, tirare indietro i record per gli ultimi 3 mesi.
C'è un metodo per la follia, i dipendenti possono cambiare manager ogni mese, ma il manager degli ultimi mesi deve vedere i record dei 3 mesi precedenti per il proprio dipendente, anche se quel dipendente aveva un manager diverso per quei mesi.
Questa è la prima selezione da inserire nell'ultimo mese
/******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])
questa è la selezione da inserire negli ultimi 3 mesi
/*********last 3 months*******************/
SELECT [REPORT_DT]
,[EMPLOYEE_ID]
,[EMPLOYEE_NAME]
,[LOCATION]
,[JOB_DESCRIPTION]
,[MANAGER_ID]
FROM [EMPLOYEE]
where [REPORT_DT]>=
( DATEADD(M, -3, GETDATE()))
Mi unirei alle 2 selezioni su [EMPLOYEE_ID]. Delle idee su come posso combinare queste 2 domande? Grazie!
Risposte
Se vuoi unirti ai due tavoli, dovresti usare:
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;
Aggiungerò che questo risultato non ha un senso particolare per me. Ma questa è la domanda che hai fatto espressamente.
Io userei:
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;
La WHEREclausola precedente corrisponde alla tua seconda query e utilizziamo un TOP 1 WITH TIESapproccio per ottenere i record con i REPORT_DTvalori massimi nella tabella.
Puoi anche usare 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())))
Per quanto riguarda il commento, questa query dovrebbe risolvere il problema:
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())))
Pensavo volessi ottenere l'elenco [EMPLOYEE_ID] per l'ultimo mese. E ottieni la loro storia lavorativa di 3 mesi. In base ai tuoi script di selezione correnti (non ho capito il tuo primo script di selezione se fornisce o meno un elenco di dipendenti) puoi fare così. Ma non è una soluzione efficace. Puoi anche aggiungere una selezione secondaria nella sezione Partecipa. Per prima cosa prova questo per favore.
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]))
Ho creato una vista utilizzando la query seguente, quindi l'ho combinata con una richiesta di data di 3 mesi (che viene utilizzata in un report Business Objects) e questo ha funzionato.
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)