Sous-requête SQL Server

Sep 25 2020

Je veux combiner 2 requêtes SQL, la première requête que je veux récupérer les enregistrements d'employés pour le dernier mois, et la deuxième requête, retirer les enregistrements des 3 derniers mois.

Il y a une méthode à la folie, les employés peuvent changer de manager chaque mois, mais le manager des derniers mois a besoin de voir les enregistrements des 3 mois précédents pour leur employé, même si cet employé avait un manager différent pour ces mois.

C'est la première sélection à tirer le mois dernier

/******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])

c'est le choix pour tirer dans les 3 derniers mois

/*********last 3 months*******************/
SELECT [REPORT_DT]
      ,[EMPLOYEE_ID]
      ,[EMPLOYEE_NAME]
      ,[LOCATION]
      ,[JOB_DESCRIPTION]
      ,[MANAGER_ID]
  FROM [EMPLOYEE]
  where [REPORT_DT]>=
  ( DATEADD(M, -3, GETDATE()))

je rejoindrais les 2 sélections sur [EMPLOYEE_ID]. Des idées sur la façon dont je peux combiner ces 2 requêtes? Merci!

Réponses

1 GordonLinoff Sep 25 2020 at 17:45

Si vous souhaitez joindre les deux tables, vous utiliserez:

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;

J'ajouterai que ce résultat n'a pas de sens pour moi. Mais c'est la question que vous avez spécifiquement posée.

1 TimBiegeleisen Sep 25 2020 at 16:36

J'utiliserais:

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 WHEREclause ci-dessus correspond à votre deuxième requête et nous utilisons une TOP 1 WITH TIESapproche pour obtenir les enregistrements ayant les REPORT_DTvaleurs maximales dans la table.

1 MichałTurczyn Sep 25 2020 at 16:52

Vous pouvez également utiliser 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())))

Concernant les commentaires, cette requête devrait résoudre le problème:

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())))
ORCAs Sep 25 2020 at 16:44

J'ai pensé que vous souhaitiez obtenir la liste [EMPLOYEE_ID] du mois dernier. Et obtenez leur historique de travail de 3 mois. Selon vos scripts de sélection actuels (je n'ai pas compris votre premier script de sélection s'il donne une liste d'employés ou non), vous pouvez faire comme ça. Mais ce n'est pas une solution efficace. Vous pouvez également ajouter une sous-sélection dans la section de jointure. Essayez d'abord ceci s'il vous plaît.

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]))
Blowers Oct 16 2020 at 15:46

J'ai créé une vue à l'aide de la requête ci-dessous, puis l'ai combinée avec une invite de date de 3 mois (elle est utilisée dans un rapport Business Objects) et cela a fait l'affaire.

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)