none
query su più record RRS feed

  • Domanda

  • ciao a tutti,

    devo eseguire una query su un db ma non riesco proprio a capire come approcciare il problema:

    nel mio db ci sono documenti che hanno una data di arrivo, e alcuni documenti possono far capo allo stesso utente. Io devo estrarre tutti gli utenti che hanno inviato documenti nel 2012 e prima del 2010 (a) ma non nel 2010/2011(b).

    Nella query che ho approntato riesco ad estrapolare i record dei documenti degli utenti che sono nella condizione a e non visualizzare quelli che sono nella condizione b, ma il problema è che se un utente ha la condizione b non lo devo proprio inserire nella lista, e questa cosa non mi riesce di fare. mi potete indicare qual'è il ragionamento che devo seguire?

    Devo inserire una seconda select nel where della prima?

    grazie per le risposte

    nervo

    lunedì 8 ottobre 2012 10:08

Risposte

  • salve,

    puoi affrontare il problema considerando un'operazione di EXCEPT...

    proietta quindi le righe dei documenti.utenti che NON siano del 2010/2011 eccetto gli documenti.utenti che abbiano righe nel 2010/2011, quindi la relativa DIFFERENCE..

    trivialmente potrebbe assomigliare a

    SET NOCOUNT ON;
    USE tempdb;
    GO
    CREATE TABLE dbo.Utenti (
    	Id int,
    	Nome varchar(10)
    	);
    CREATE TABLE dbo.Documenti (
    	Id int,
    	IdUtente int,
    	Data date
    	);
    INSERT INTO dbo.Utenti 
    	VALUES (1, 'a'),  (2, 'b'), (3, 'c'), (4, 'd'), (5, 'e');
    INSERT INTO dbo.Documenti
    	VALUES
    		  (1, 1, '20120101') -- valido
    		, (2, 2, '20110101') -- non valido
    		, (3, 3, '20120101'), (4, 3, '20100101') -- valido + valido = valido
    		, (5, 4, '20120101'), (6, 4, '20110101') -- valido + non valido =  non valido
    GO
    WITH cte AS (
    	SELECT u.Id
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON d.IdUtente = u.Id
    			WHERE DATEPART(YEAR, d.Data) NOT IN (2011)
    	EXCEPT
    	SELECT u.Id
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON d.IdUtente = u.Id
    			WHERE DATEPART(YEAR, d.Data) IN (2011)
    	)
    	SELECT *
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON u.Id = d.IdUtente
    			JOIN cte c ON u.Id = c.Id;
    GO
    WITH cte AS (
    	SELECT u.Id
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON d.IdUtente = u.Id
    			WHERE DATEPART(YEAR, d.Data) NOT IN (2011)
    	EXCEPT
    	SELECT u.Id
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON d.IdUtente = u.Id
    			WHERE DATEPART(YEAR, d.Data) IN (2011)
    	)
    	SELECT DISTINCT u.Id, u.Nome
    		FROM dbo.Documenti d
    			JOIN dbo.Utenti u ON u.Id = d.IdUtente
    			JOIN cte c ON u.Id = c.Id;
    
    GO
    DROP TABLE dbo.Utenti, dbo.Documenti;
    --<------
    Id          IdUtente    Data       Id          Nome       Id
    ----------- ----------- ---------- ----------- ---------- -----------
    1           1           2012-01-01 1           a          1
    3           3           2012-01-01 3           c          3
    4           3           2010-01-01 3           c          3
    
    Id          Nome
    ----------- ----------
    1           a
    3           c
    

    saluti


    ottenuto questo risultato, potrai poi ottenere tramite DISTINCT gli unici ID degli utenti che soddisfino l'esigenza, e relazionarne il risultato con la tabella utenti al fine di ottenere le informazioni complete interessanti...

    http://www.asql.biz - DbaMgr2k - DbaMgr and further SQL Tools http://www.hotelsole.com/


    giovedì 11 ottobre 2012 21:19
    Moderatore