2011-09-28 14 views
25

Ho la seguente query:Come avere SQL INNER JOIN accettare i risultati nulli

SELECT TOP 25 CLIENT_ID_MD5, COUNT(CLIENT_ID_MD5) TOTAL 
FROM dbo.amazonlogs 
GROUP BY CLIENT_ID_MD5 
ORDER BY COUNT(*) DESC; 

che restituisce:

283fe255cbc25c804eb0c05f84ee5d52 864458 
879100cf8aa8b993a8c53f0137a3a176 126122 
06c181de7f35ee039fec84579e82883d 88719 
69ffb6c6fd5f52de0d5535ce56286671 68863 
703441aa63c0ac1f39fe9e4a4cc8239a 47434 
3fd023e7b2047e78c6742e2fc5b66fce 45350 
a8b72ca65ba2440e8e4028a832ec2160 39524 
... 

voglio recuperare il nome del client corrispondente (FIRM) utilizzando il MD5 restituita da questa query, in modo da una fila potrebbe essere simile:

879100cf8aa8b993a8c53f0137a3a176 126122 Burger King 

così ho fatto questa domanda:

SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, c.FIRM 
FROM dbo.amazonlogs a 
    INNER JOIN dbo.customers c 
    ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
GROUP BY a.CLIENT_ID_MD5, c.FIRM 
ORDER BY COUNT(*) DESC; 

restituisce qualcosa di simile:

879100cf8aa8b993a8c53f0137a3a176 126122 Burger King 
06c181de7f35ee039fec84579e82883d 88719  McDonalds 
703441aa63c0ac1f39fe9e4a4cc8239a 47434  Wendy's 
3fd023e7b2047e78c6742e2fc5b66fce 45350  Tim Horton's 

Quali opere, tranne che ho bisogno di restituire un valore vuoto per c.FIRM se non v'è nessuna impresa corrispondente per un dato MD5. Ad esempio:

879100cf8aa8b993a8c53f0137a3a176 126122 Burger King 
06c181de7f35ee039fec84579e82883d 88719  McDonalds 
69ffb6c6fd5f52de0d5535ce56286671 68863 
703441aa63c0ac1f39fe9e4a4cc8239a 47434  Wendy's 
3fd023e7b2047e78c6742e2fc5b66fce 45350  Tim Horton's 

Come dovrei modificare la query per restituire ancora una riga anche se non c'è un corrispondente c.FIRM?

+10

È nero come la pece. Probabilmente sarai mangiato da un grumo. – SQLMason

risposta

81

Sostituire INNER JOIN con LEFT JOIN

+6

LEFT JOIN restituisce righe anche quando non vi è alcuna corrispondenza in un'altra tabella a cui si sta partecipando. INNER JOIN non lo farà, restituisce solo le righe se c'è una corrispondenza in un'altra tabella – evilone

+0

Quindi * questa * la differenza ... – Jackson

2

un inner join esclude valori null; vuoi un join LEFT OUTER.

1
SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, IsNull(c.FIRM, 'Unknown') as Firm 
FROM dbo.amazonlogs a 
    LEFT JOIN dbo.customers c ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
GROUP BY a.CLIENT_ID_MD5, c.FIRM ORDER BY COUNT(*) DESC; 

Questo darà un valore di "Sconosciuto" quando i record nella tabella clienti non esistono. Ovviamente potresti abbandonare quella parte e tornare a c.FIRM se invece vuoi avere dei null reali.

2

Invece di fare un INNER join, si dovrebbe fare un join esterno sinistro:

SELECT 
    a.CLIENT_ID_MD5, 
    COUNT(a.CLIENT_ID_MD5) TOTAL, 
    ISNULL(c.FIRM,'') 
FROM 
    dbo.amazonlogs a LEFT OUTER JOIN 
    dbo.customers c ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
GROUP BY 
    a.CLIENT_ID_MD5, 
    c.FIRM 
ORDER BY COUNT(0) DESC 

http://www.w3schools.com/sql/sql_join.asp

+0

Hai un errore nella tua query - LEFT OURER JOIN – evilone

+0

Cheers evilone .. –

9

uso LEFT JOIN invece di INNER JOIN

1

Cambia la tua INNER JOIN ad un outer join ..

SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL, c.FIRM 
FROM dbo.amazonlogs a 
LEFT OUTER JOIN dbo.customers c 
    ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
GROUP BY a.CLIENT_ID_MD5, c.FIRM 
ORDER BY COUNT(*) DESC; 
1
WITH amazonlogs_Tallies 
    AS 
    (
     SELECT a.CLIENT_ID_MD5, COUNT(a.CLIENT_ID_MD5) TOTAL 
     FROM dbo.amazonlogs a 
     GROUP 
      BY a.CLIENT_ID_MD5 
    ), 
    amazonlogs_Tallies_Firms 
    AS 
    (
     SELECT a.CLIENT_ID_MD5, a.TOTAL, c.FIRM 
     FROM amazonlogs_Tallies a 
      INNER JOIN dbo.customers c 
       ON c.CLIENT_ID_MD5 = a.CLIENT_ID_MD5 
    ) 
SELECT CLIENT_ID_MD5, TOTAL, FIRM 
    FROM amazonlogs_Tallies_Firms 
UNION 
SELECT CLIENT_ID_MD5, TOTAL, '{{NOT_KNOWN}}' 
    FROM amazonlogs_Tallies 
EXCEPT 
SELECT CLIENT_ID_MD5, TOTAL, '{{NOT_KNOWN}}' 
    FROM amazonlogs_Tallies_Firms;