2017-09-22 2 views
0

Utilisation de Microsoft SQL Server Management Studio - base de données SQL Server.Retourne uniquement la première ligne datée du tableau joint

J'ai deux tables - la première est une table avec tous nos clients. La deuxième table, celle que j'essaie de rejoindre, est une table avec toutes les modifications apportées aux profils des clients.

Ce que je veux, c'est le plus tôt date_changed, et les informations associées à cet enregistrement, pour chaque client.

Le tableau client, pour un client spécifique, contient:

client_code | first_name | last_name | zip_postal_code 
------------|------------|-----------|---------------- 
168187  | Trees  | Karoline | n 

Le tableau change pour ce client a plusieurs enregistrements:

client_code | clerk_changed | date_changed 
------------|---------------|------------------------ 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | taranab  | 2017-03-18 10:37:00.000 
168187  | saml   | 2017-04-21 09:36:00.000 
168187  | matijay  | 2017-04-22 06:22:00.000 

exécution de la requête:

SELECT client.client_code, client.first_name, client.last_name, client.zip_postal_code, clerk.clerk_changed, clerk.date_changed 
FROM maclient client 
LEFT JOIN (
    SELECT MIN(date_changed) AS 'date_changed', client_code, clerk_changed 
    FROM maclntchg 
    GROUP BY client_code, clerk_changed 
) AS clerk ON client.client_code = clerk.client_code 
WHERE client.client_code > '104' AND ((client.country_code = 'ca' AND LEN(client.zip_postal_code) <> 7) OR (client.country_code = 'us' AND LEN(client.zip_postal_code) <> 5)) AND client.zip_postal_code <> 'N/A' AND client.client_code = '168187' 
ORDER BY clerk.clerk_changed, clerk.date_changed, client.last_name 

Renvoie:

client_code | first_name | last_name | zip_postal_code | clerk_changed | date_changed 
------------|------------|-----------|-----------------|---------------|------------------------ 
168187  | Trees  | Karoline | n    | matijay  | 2017-04-22 06:22:00.000 
168187  | Trees  | Karoline | n    | saml   | 2017-04-21 09:36:00.000 
168187  | Trees  | Karoline | n    | taranab  | 2017-03-18 10:37:00.000 

Au lieu du résultat attendu:

client_code | first_name | last_name | zip_postal_code | clerk_changed | date_changed 
------------|------------|-----------|-----------------|---------------|------------------------ 
168187  | Trees  | Karoline | n    | taranab  | 2017-03-18 10:37:00.000 
+1

étiquette toujours la version SQL. il sera utile de vous fournir la meilleure réponse – FLICKER

+1

Qui est 'Thompson'? –

+0

11.0.2100.60/SQL Server 2016. Et typo, corrigé. – WolfieeifloW

Répondre

2
SELECT client.client_code, client.first_name, client.last_name, client.zip_postal_code, clerk.clerk_changed, clerk.date_changed 
FROM maclient client 
OUTER APPLY (
    SELECT TOP 1 date_changed AS 'date_changed', client_code, clerk_changed 
    FROM maclntchg clerk 
    WHERE client.client_code = clerk.client_code 
    ORDER BY date_changed ASC 
) 
WHERE client.client_code > '104' AND ((client.country_code = 'ca' AND LEN(client.zip_postal_code) <> 7) OR (client.country_code = 'us' AND LEN(client.zip_postal_code) <> 5)) AND client.zip_postal_code <> 'N/A' AND client.client_code = '168187' 
ORDER BY clerk.clerk_changed, clerk.date_changed, client.last_name 

Un autre:

SELECT client.client_code, client.first_name, client.last_name, client.zip_postal_code, clerk.clerk_changed, clerk.date_changed 
FROM maclient client 
LEFT JOIN (
    SELECT ROW_NUMBER() OVER(PARTITION BY client_code ORDER BY date_changed ASC) row_num, date_changed AS 'date_changed', client_code, clerk_changed 
    FROM maclntchg 
) clerk ON client.client_code = clerk.client_code AND clerk.row_num = 1 
WHERE client.client_code > '104' AND ((client.country_code = 'ca' AND LEN(client.zip_postal_code) <> 7) OR (client.country_code = 'us' AND LEN(client.zip_postal_code) <> 5)) AND client.zip_postal_code <> 'N/A' AND client.client_code = '168187' 
ORDER BY clerk.clerk_changed, clerk.date_changed, client.last_name 
+0

J'aime la seconde. Est-ce que le regroupement par date a changé, alors il suffit de sélectionner la date la plus proche? – WolfieeifloW

+1

Oui. Il donne row_number pour chaque groupe de client_code à partir de min date (date ORDER BY). Ces fonctions sont appelées en tant que fonctions WINDOW elles sont similaires aux fonctions d'agrégat, mais elles ne regroupent pas les enregistrements. Vous pouvez utiliser MIN, MAX et d'autres comme ça. –

+0

Merci pour votre réponse et votre explication. Fonctionne comme un charme! – WolfieeifloW