Select IN

giovedì 03 febbraio 2011 - 18.07
Tag Elenco Tags  MySQL 5.5  |  MySQL 5.1  |  MySQL 5.0

slackewix Profilo | Newbie

Salve a tutti. Ho un problemino di sql che non riesco a risolvere: ho 2 tabelle con relazione uno a molti. Ora, in una query sola ho bisogno di selezionare tutti i prodotti dalla tabella A che abbiano tutte le caratteristiche indicate e presenti nella tabella B.

La struttura delle tabelle è:

tabella A:
id | campo1 | campo2 ecc

tabella B
idfilter | id (= id in tabella A)

La struttura prevede che per ogni record in tabella A ci possano essere più record in tabella B.

La query più ovvia mi sembrava:

SELECT DISTINCT B.* FROM a
LEFT JOIN B ON a.id = b.id
WHERE idfilter IN (2,9)

Il che però mi ritorna tutti i record che hanno per idfilter 2 OPPURE 9. Invece a me servono solo i record che abbiano 2 E 9.

Grazie dell'aiuto

lbenaglia Profilo | Guru

>Salve a tutti. Ho un problemino di sql che non riesco a risolvere:
>ho 2 tabelle con relazione uno a molti. Ora, in una query sola
>ho bisogno di selezionare tutti i prodotti dalla tabella A che
>abbiano tutte le caratteristiche indicate e presenti nella tabella
>B.
>
>La struttura delle tabelle è:
>
>tabella A:
>id | campo1 | campo2 ecc
>
>tabella B
>idfilter | id (= id in tabella A)
>
>La struttura prevede che per ogni record in tabella A ci possano
>essere più record in tabella B.
>
>La query più ovvia mi sembrava:
>
>SELECT DISTINCT B.* FROM a
>LEFT JOIN B ON a.id = b.id
>WHERE idfilter IN (2,9)
>
>Il che però mi ritorna tutti i record che hanno per idfilter
>2 OPPURE 9. Invece a me servono solo i record che abbiano 2 E
>9.
La query che hai postato recupera informazioni esclusivamente dalla tabella B, quindi non capisco per quale motivo interroghi anche la tabella A.
Il problema può essere risolto con una tabella derivata che restituisca gli id che soddisfano la condizione di ricerca in JOIN con la tabella B per recuperare tutte le colonne.
L'esempio che sto per proporti è per SQL Server 2005 o successivo che fa uso di una Common Table Expression (CTE):

USE tempdb; CREATE TABLE dbo.A( id int NOT NULL PRIMARY KEY ); CREATE TABLE dbo.B( idfilter int NOT NULL, id int NOT NULL, CONSTRAINT PK_B PRIMARY KEY (idfilter, id), CONSTRAINT FK_B_A FOREIGN KEY (id) REFERENCES dbo.A(id) ); INSERT dbo.A VALUES (1), (2), (3), (4); INSERT dbo.B VALUES (1, 1), (2, 1), (3, 1) , (1, 2), (2, 2), (9, 2) , (1, 3), (3, 3), (9, 3) , (2, 4), (8, 4), (9, 4); WITH CTE_GetKey AS ( SELECT id FROM dbo.B WHERE idfilter IN (2, 9) GROUP BY id HAVING COUNT(*) >= 2 ) SELECT B.* FROM dbo.B JOIN CTE_GetKey AS C ON B.id = C.id; /* Output: idfilter id ----------- ----------- 9 2 2 2 1 2 8 4 9 4 2 4 (6 row(s) affected) */ DROP TABLE dbo.B, dbo.A;

>Grazie dell'aiuto
Prego.

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/

slackewix Profilo | Newbie

ho trovato la soluzione (non da solo....con l'aiuto di altri....)

select id_prodotto,group_concat(id_filter order by id_filter)
from tabella_b
where id_filter in (2,9)
group by id_prodotto
having count(distinct(id_filter)) = 2


Il group_concat serve solo da esempio. Ho pensato di postarla casomai servisse a qualcun altro.
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2017
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5