2010-01-15 8 views
3

Je voudrais trouver les hits et les échecs dans une table en utilisant seulement une liste d'éléments sans avoir à créer une nouvelle table pour contenir les éléments de la liste et sans utiliser de script. Je fais beaucoup de requêtes ponctuelles tout au long de la journée, ce qui serait utile.OUTER JOIN utilisant la liste IN?

Voici un exemple de ce que j'utilise maintenant:

SELECT custid, name, email 
FROM customers 
WHERE custid IN 
('1111', '2222', '3333', '4444') 

Cela renvoie toutes les entrées dans la table des clients où les ID client correspondent à celui de la liste que je fournis. Je voudrais trouver un moyen de retourner des résultats comme un OUTER JOIN, où je pourrais voir les correspondances ainsi que les échecs.

FYI: J'utilise MS SQL Server mais il serait utile de pouvoir le faire aussi dans mySQL. Merci!

Répondre

2

Utilisez une fonction définie par l'utilisateur pour générer une table à partir d'une liste de valeurs séparées par des virgules. Ensuite, vous pouvez faire une jointure externe à la liste, comme ceci:

select customers.custid, name, email 
    from customers 
    left outer join dbo.get_id_table('1111', '2222', '3333', '4444') as ids 
     on (customers.custid = ids.custid) 

Il existe plusieurs versions d'une fonction de type « get_id_table » posté ici et ailleurs sur le web (désolé - je ne peux pas arriver à un lien maintenant).

2

Cela fonctionnerait probablement. J'utilise la table #test à la place de votre table de clients et le peuplant avec 1, 3 et 5. Ensuite, je cherche 1, 2 et 3.

CREATE TABLE #test 
(
    id int 
) 
GO 

INSERT INTO #test 
SELECT 1 UNION SELECT 3 UNION SELECT 5 
GO 

SELECT * 
FROM (SELECT 1 AS id UNION SELECT 2 UNION SELECT 3) s 
LEFT OUTER JOIN #test t ON s.id=t.id 

Voici un exemple en utilisant votre table de clients :

SELECT s.SearchId, c.custid, c.name, c.email 
FROM (SELECT '1111' AS SearchId UNION SELECT '2222' 
    UNION SELECT '3333' UNION SELECT '4444') s 
LEFT OUTER JOIN customers c ON s.SearchId=c.custid 
3

Il existe plusieurs façons de procéder. Voici deux:

SELECT C1.custid, name, email, C2.CustID As Match FROM customers As C1 left join (SELECT custid FROM customers
WHERE custid IN
('1111', '2222', '3333', '4444')) As C2 on C1.custid=C2.custid

Il y aura un certain nombre (un des 4) dans le match colonne si elle est l'un des numéros. Ou:

SELECT custid, name, email, Case When custid in ('1111', '2222', '3333', '4444') Then 'Match' Else '' End As IsMatch FROM customers

La colonne IsMatch dira « Match » si elle est l'une des quatre valeurs.

La seconde sera généralement plus rapide.

+0

cordes littéraux utilisent des guillemets simples. – Joey

+0

La deuxième option sorte de travaux. Malheureusement, la requête vérifie TOUTES les entrées de la table des clients - pas seulement celles de la liste. Donc, j'obtiens plus de données que j'ai besoin. Dans le cas où je regarde la table de nos clients, il y aurait 200k + enregistrements donc il n'est pas utile de retourner tous ces enregistrements pour trouver 4 correspondances. Merci quand même! – ShinobiDev

+0

Je ne comprends pas, votre question ne dit-elle pas que vous VOULEZ voir tous les enregistrements, correspondant ou non? –

0

Vous voulez vous mettre vos custids que vous une recherche dans une table et à vous joindre comme si ...

CREATE TABLE #temp 
(
    custid varchar(4) 
) 

INSERT INTO #temp(employeeid) VALUES '1111' 
INSERT INTO #temp(employeeid) VALUES '2222' 
INSERT INTO #temp(employeeid) VALUES '3333' 
INSERT INTO #temp(employeeid) VALUES '4444' 

SELECT c.custid, name, email, t.custid 
FROM customers c 
LEFT JOIN #temp t ON c.custid = t.custid 
+0

Je préférerais ne pas avoir à créer de nouveaux ou tables temporaires – ShinobiDev

0

serveur SQL 2005, 2008

DECLARE @tmp TABLE (id varchar(8)) 

INSERT INTO @tmp (id) 
SELECT '1111' UNION 
SELECT '2222' UNION 
SELECT '3333' UNION 
SELECT '4444' ; 

SELECT c.custid, c.name, c.email 
FROM customers AS c 
LEFT JOIN @tmp AS t ON t.id = customers.custid