Nous avons un tableau qui capturera l'enregistrement de balayage de chaque employee
. J'essaie d'écrire une requête pour récupérer la liste des enregistrements d'employés distincts par le premier balayage pour aujourd'hui.
Nous enregistrons les informations de date de balayage dans la colonne datetime
. Voici ma requête son exception de lancement.
select distinct
[employee number], [Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,[Reader Name]
,[Status]
,[Location]
from
[Interface].[dbo].[VwEmpSwipeDetail]
group by
[employee number]
where
[datetime] = CURDATE();
Obtenir une erreur:
La colonne "Interface.dbo.VwEmpSwipeDetail.Employee First Name" n'est pas valide dans la liste de sélection car elle n'est contenue ni dans une fonction d'agrégation ni dans la clause GROUP BY.
Avez-vous besoin d'aide?
Merci d'avance.
L'erreur dit tout:
... Prénom de l'employé 'n'est pas valide dans la liste de sélection car il n'est contenu ni dans une fonction d'agrégation ni dans la clause GROUP BY
Cela dit, il y a d'autres colonnes qui nécessitent également de l'attention.
Réduisez les colonnes renvoyées à celles nécessaires uniquement ou incluez les colonnes dans votre GROUP BY
clause ou ajouter des fonctions d'agrégation (MIN/MAX). De plus, votre clause WHERE
doit être placée avant le GROUP BY
.
Essayer:
select distinct [employee number]
,[Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,min([Reader Name])
from [Interface].[dbo].[VwEmpSwipeDetail]
where CAST([datetime] AS DATE)=CAST(GETDATE() AS DATE)
group by [employee number], [Employee First Name], [Employee Last Name], [Card Number]
J'ai supprimé status
et location
car cela risque de renvoyer des valeurs non distinctes. Afin de renvoyer ces données, vous pouvez avoir besoin d'une sous-requête (ou CTE) qui obtient d'abord les ID uniques de la table SwipeDetails
, et à partir de cette liste, vous pouvez vous joindre aux autres données, quelque chose comme:
SELECT [employee number],[Employee First Name],[Employee Last Name].. -- other columns
FROM [YOUR_TABLE]
WHERE SwipeDetailID IN (SELECT MIN(SwipeDetailsId) as SwipeId
FROM SwipeDetailTable
WHERE CAST([datetime] AS DATE)=CAST(GETDATE() AS DATE)
GROUP BY [employee number])
Veuillez essayer ci-dessous la requête:
select distinct [employee number],[Employee First Name]
,[Employee Last Name]
,min([DateTime])
,[Card Number]
,[Reader Name]
,[Status]
,[Location] from [Interface].[dbo].[VwEmpSwipeDetail] group by [employee number],[Employee First Name]
,[Employee Last Name]
,[Card Number]
,[Reader Name]
,[Status]
,[Location] having [datetime]=GetDate();
Trouvez d'abord le premier horodatage pour chaque employé le jour donné (CURDATE), puis revenez à la table principale pour obtenir tous les détails:
WITH x AS (
SELECT [employee number], MIN([datetime] AS minDate
FROM [Interface].[dbo].[VwEmpSwipeDetail]
WHERE CAST([datetime] AS DATE) = CURDATE()
GROUP BY [employee number]
)
select [employee number]
,[Employee First Name]
,[Employee Last Name]
,[DateTime]
,[Card Number]
,[Reader Name]
,[Status]
,[Location]
from [Interface].[dbo].[VwEmpSwipeDetail] y
JOIN x ON (x.[employee number] = y.[employee number] AND x.[minDate] =Y.[datetime]
Cela ne devrait pas être marqué comme mysql car cela ne se produirait pas dans mysql.
sql-server ne sait pas laquelle des valeurs groupées [Employee First Name] renvoyer, vous devez donc ajouter un agrégat (même si vous ne vous attendez en fait qu'à un seul résultat). min/max fonctionnera dans ce cas. La même chose s'appliquerait à toutes les autres lignes où elles ne sont pas dans le GROUP BY ou ont une fonction d'agrégation (EG min) autour d'elles.