salve Luca,
lucavb wrote:
Salve,
è un po' che non prendo in mano sql e devo finire un progetto per l'uni e (tanto per cambiare ho poco tempo) quindi vi chiedo aiuto: ho una tabella "userrates" formata da: id, userid, idtitle, rate tipo questa creata estraendo i soli utenti che hanno votato i film 10 e 1 (ordinata by userid):
(1, 12, 1, 3)
(2, 20, 1, 1)
(3, 22, 10, 1)
(10, 22, 1, 5)
(5, 166, 10, 1)
(4, 244, 10, 2)
(6, 298, 1, 4)
(7, 298, 10, 3)
il tutto inizia con una funzione che prende in input due idtitle, ho bisogno di una select che mi estragga le sole righe che contengono votazioni ai due film passati alla funzione e le sole righe che si riferiscono agli utenti che hanno votato entrambi i film!
Quindi in questo caso le righe:
(3, 22, 10, 1)
(10, 22, 1, 5)
(6, 298, 1, 4)
(7, 298, 10, 3)
Grazie in anticipo,
Luca
non hai indicato che dbms tu stia utilizzando, quindi indico un procedimento ed una sintassi validi per SQL Server >= 2005..
considerando che hai "un'insieme" di film, possiamo benissimo intendere questo parametro come, appunto, un "insieme" e quindi una tabella, sia essa definita come tabella temporanea o come il risultato di una funzione tabellare che restituisca "n" righe... questo ci permette anche di "generalizzare" il codice di proiezione basandoci su un'apposita join tra le tabelle coinvolte..
ad esempio, quindi, possiamo ottenere la proiezione di tutti gli users che abbiano votato i film indicati raggruppando la join della proiezione relativa e filtrando per ottenere solo le righ che abbiano un conteggio uguale al numero dei film presenti nell'apposita tabella..
con questo risultato possiamo poi filtrare la tabella users mantenendo la condizione di join sia sull'insieme dei film che sulla lista di users riscontrati in precedenza... per fare cio' possiamo utilizzare una banalissima Common Table Expression che ci funga da result temporaneo degli users richiesti, similarmente a:
SET NOCOUNT ON;
USE tempdb;
GO
CREATE TABLE dbo.users (
Id int NOT NULL,
UserId int NOT NULL,
IdTitle int NOT NULL,
Rate int NOT NULL
);
GO
INSERT INTO dbo.users
VALUES (1, 12, 1, 3),
(2, 20, 1, 1),
(3, 22, 10, 1),
(10, 22, 1, 5),
(5, 166, 10, 1),
(4, 244, 10, 2),
(6, 298, 1, 4),
(7, 298, 10, 3),
questa riga rientra solo se vogliamo ottenere anche il film 5 (100, 298, 5, 3),
non rientranti nei film
(100, 298, 9, 3),
(101, 298, 8, 3),
(102, 1, 9, 3);
GO
DECLARE @idTitles table (IdTitle int);
INSERT INTO @idTitles VALUES ( 1 ), ( 10 );
PRINT 'se vogliamo provare un filtro su 3 film possiamo inserire anche la riga di seguito:';
PRINT '--> ' + 'INSERT INTO @idTitles VALUES ( 5 );';
inserire questa riga se vogliamo ottenere anche il film 5, quindi 3 film in totale
--INSERT INTO @idTitles VALUES ( 5 );
PRINT 'i film considerati per la votazione';
SELECT *
FROM @idTitles;
PRINT 'gli utenti che hanno votato tutti i film inlistati';
SELECT MAX(u.UserId) AS [UserId]
FROM dbo.users u
WHERE u.IdTitle IN (
SELECT t.IdTitle
FROM @idTitles t
)
GROUP BY u.UserId
HAVING COUNT(*) = (SELECT COUNT(*) FROM @idTitles);
PRINT 'le righe di users che soddifano entrambe le condizioni relativi ai singoli film ed all''insieme dei film da votare';
WITH cteUsers AS (
SELECT MAX(u.UserId) AS [UserId]
FROM dbo.users u
WHERE u.IdTitle IN (
SELECT t.IdTitle
FROM @idTitles t
)
GROUP BY u.UserId
HAVING COUNT(*) = (SELECT COUNT(*) FROM @idTitles)
)
SELECT *
FROM dbo.users u
JOIN cteUsers c ON c.UserId = u.UserId
JOIN @idTitles t ON t.IdTitle = u.IdTitle
ORDER BY u.UserId, u.IdTitle;
GO
DROP TABLE dbo.users;
--<-------
se vogliamo provare un filtro su 3 film possiamo inserire anche la riga di seguito:
--> INSERT INTO @idTitles VALUES ( 5 );
i film considerati per la votazione
IdTitle
-----------
1
10
gli utenti che hanno votato tutti i film inlistati
UserId
-----------
22
298
le righe di users che soddifano entrambe le condizioni relativi ai singoli film ed all'insieme dei film da votare
Id UserId IdTitle Rate UserId IdTitle ---------
---------
---------
---------
---------
---------
10 22 1 5 22 1 3 22 10 1 22 10 6 298 1 4 298 1 7 298 10 3 298 10
tu pero' non hai presentato alcuna soluzione o tentativo... come avresti fatto, tu?
saluti