9 messaggi dal 04 ottobre 2012
Buongiorno,
premetto che sono alle prime armi con SQLServer;
avrei la necessità di fare questa select
SELECT SUM(GIORNI) AS TOTALE FROM dbo.ASSENZA WHERE TIPO_TIPO =' variabile'

dove però variabile è il risultato di una select in un'altra tabella
SELECT DISTINCT TIPO AS T FROM TIPOLOGIE WHERE TIPO !='--'

Questa select restituisce più di 30 tipologie diverse
se unisco le due select ottengo:
SELECT SUM(GIORNI) AS TOTALE FROM dbo.ASSENZA WHERE TIPO_TIPO = (SELECT DISTINCT TIPO AS T FROM TIPOLOGIE WHERE TIPO !='--')

con il seguente errore:

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.

se utilizzo
IN
al posto di
=
ottengo il risultato con tutti i tipi, ma non è quello che voglio.

Mi servirebbe ottenere un valore per ogni tipo diverso.

spero di essermi spiegato

Grazie anticipatamente per l'aiuto

Buon Natale e Felice 2016 a Tutti !!
Modificato da genebulldog73 il 26 dicembre 2015 17.01 -
1.976 messaggi dal 27 luglio 2005
Contributi
salve,
e buon Natale...
potresti per favore definire un miniscenario autonomo, provvisto di CREATE TABLE e INSERT INTO, in modo da non dover provvedere alla nostra generazione ex-novo di una realta' magari alquanto diversa dalle tue esigenze?
saluti

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php
9 messaggi dal 04 ottobre 2012
Hai proprio ragione Andrea, scusami per la superficialità.
queste sono le due tabelle con alcuni valori di esempio.

CREATE TABLE [dbo].[ASSENZA] (
    [ID_ASSENZA]   INT           IDENTITY (1, 1) NOT NULL,
    [MATRICOLA_LAVORO]    VARCHAR (50)  NOT NULL,
    [TIPO_ASSENZA] VARCHAR (MAX) NOT NULL,
    [TIPO_TIPO]    VARCHAR (50)  NOT NULL,
    [GIORNI]       NUMERIC (18)  NULL,
    [DAL]          DATE          NULL,
    [AL]           DATE          NULL,
    [ORE]          NUMERIC (18)  NULL,
    [DA]           DATE          NULL,
    [A]            DATE          NULL,
    [NOTE]         VARCHAR (MAX) NULL,
    PRIMARY KEY CLUSTERED ([ID_ASSENZA] ASC)
  );
GO
INSERT INTO dbo.[ASSENZA] (MATRICOLA_LAVORO,TIPO_ASSENZA,TIPO_TIPO,GIORNI,DAL,AL,ORE,DA,A,NOTE)
  VALUES 
  ('xxxxxx','ferie_retribuite','f_r',8,(CONVERT(DATETIME,10/10/2015,105)),(CONVERT(DATETIME,18/10/2015,105)),0,(CONVERT(DATETIME,01/01/0001,105)),(CONVERT(DATETIME,01/01/0001,105)),'note_varie');
 
 INSERT INTO dbo.[ASSENZA] (MATRICOLA_LAVORO,TIPO_ASSENZA,TIPO_TIPO,GIORNI,DAL,AL,ORE,DA,A,NOTE)
  VALUES 
   ('xxxxxx','ferie_non_retribuite','f_n_r',2,(CONVERT(DATETIME,19/10/2015,105)),(CONVERT(DATETIME,21/10/2015,105)),0,(CONVERT(DATETIME,01/01/0001,105)),(CONVERT(DATETIME,01/01/0001,105)),'note_varie');

CREATE TABLE [dbo].[TIPOLOGIE] (
    [ID_TIPOLOGIE]   INT           IDENTITY (1, 1) NOT NULL,
    [NOME]           VARCHAR (MAX) NOT NULL,
    [TIPO]           VARCHAR (50)  NOT NULL,
    [ABBREVIAZIONE]  VARCHAR (50)  NOT NULL,
    [MASSIMO_GIORNI] NUMERIC (18)  NOT NULL,
    [NOTE]           VARCHAR (MAX) NULL,
    PRIMARY KEY CLUSTERED ([ID_TIPOLOGIE] ASC)
);

GO

INSERT INTO dbo.[TIPOLOGIE] (NOME,TIPO,ABBREVIAZIONE,MASSIMO_GIORNI,NOTE)
 VALUES ('prova_nome','ferie_retribuite','f_r',32,'note_varie');

INSERT INTO dbo.[TIPOLOGIE] (NOME,TIPO,ABBREVIAZIONE,MASSIMO_GIORNI,NOTE)
 VALUES ('prova_nome','ferie_non_retribuite','f_n_r',15,'note_varie')

a questo punto vorrei ottenre il totale dei giornio fatti ad esempio delle ferie retribuite:
SELECT SUM(GIORNI) AS TOTALE FROM dbo.ASSENZA WHERE TIPO_TIPO ='variabile' 

in questo caso variabile andrebbe sostituito con 'f_r'; se invece volessi le ferie non retribuite con 'f_n_r' e così via per altri tipi come permessi ecc.

tutti i tipi da associare alla variabile li vorrei prendere dalla tabella [TIPOLOGIE]
SELECT DISTINCT TIPO AS T FROM TIPOLOGIE WHERE TIPO !='--'

ma come dicevo nel post precedente questa sintassi mi generare ovviamente errore
SELECT SUM(GIORNI) AS TOTALE FROM dbo.ASSENZA WHERE TIPO_TIPO = (SELECT DISTINCT TIPO AS T FROM TIPOLOGIE WHERE TIPO !='--')

Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.


Nel frattempo ho visto una tuo post
http://forum.aspitalia.com/forum/post/411461/Query-Selezione.aspx
di risposta che potrebbe avvicinarsi a quello che ho chiesto. Non so però se riesco ad adattarlo.
Grazie in anticipo.
Buona serata.
Modificato da genebulldog73 il 27 dicembre 2015 19.26 -
Modificato da genebulldog73 il 27 dicembre 2015 19.28 -
Modificato da genebulldog73 il 27 dicembre 2015 19.28 -
1.976 messaggi dal 27 luglio 2005
Contributi
salve,
ora va meglio :)

si, tendenzialmente potresti prendere spunto da http://forum.aspitalia.com/forum/post/411461/Query-Selezione.aspx, ma a mio parere l'espressione va riformulata, in quanto mi pare di capire che il contenuto della tabella TIPOLOGIE ovviamente possa essere "dinamica" e non fissa a 2 righe... cio' comporta una modifica sostanziale, in quanto non sappiamo a priori quante righe essa possa contenere, e quindi dobbiamo appunto sviluppare un comando di selezione dinamico che possa poi essere eseguito tramite EXECUTE @cmd.
di seguito, un esempio in tal senso..
SET NOCOUNT ON;
GO
USE tempdb;
GO
CREATE TABLE [dbo].[ASSENZA] (
    [ID_ASSENZA]   INT           IDENTITY (1, 1) NOT NULL,
    [MATRICOLA_LAVORO]    VARCHAR (50)  NOT NULL,
    [TIPO_ASSENZA] VARCHAR (MAX) NOT NULL,
    [TIPO_TIPO]    VARCHAR (50)  NOT NULL,
    [GIORNI]       NUMERIC (18)  NULL,
    [DAL]          DATE          NULL,
    [AL]           DATE          NULL,
    [ORE]          NUMERIC (18)  NULL,
    [DA]           DATE          NULL,
    [A]            DATE          NULL,
    [NOTE]         VARCHAR (MAX) NULL,
    PRIMARY KEY CLUSTERED ([ID_ASSENZA] ASC)
  );
GO
INSERT INTO dbo.[ASSENZA] (MATRICOLA_LAVORO,TIPO_ASSENZA,TIPO_TIPO,GIORNI,DAL,AL,ORE,DA,A,NOTE)
  VALUES 
  ('xxxxxx','ferie_retribuite','f_r',8,(CONVERT(DATETIME,10/10/2015,105)),(CONVERT(DATETIME,18/10/2015,105)),0,(CONVERT(DATETIME,01/01/0001,105)),(CONVERT(DATETIME,01/01/0001,105)),'note_varie');
 
 INSERT INTO dbo.[ASSENZA] (MATRICOLA_LAVORO,TIPO_ASSENZA,TIPO_TIPO,GIORNI,DAL,AL,ORE,DA,A,NOTE)
  VALUES 
   ('xxxxxx','ferie_non_retribuite','f_n_r',2,(CONVERT(DATETIME,19/10/2015,105)),(CONVERT(DATETIME,21/10/2015,105)),0,(CONVERT(DATETIME,01/01/0001,105)),(CONVERT(DATETIME,01/01/0001,105)),'note_varie');

CREATE TABLE [dbo].[TIPOLOGIE] (
    [ID_TIPOLOGIE]   INT           IDENTITY (1, 1) NOT NULL,
    [NOME]           VARCHAR (MAX) NOT NULL,
    [TIPO]           VARCHAR (50)  NOT NULL,
    [ABBREVIAZIONE]  VARCHAR (50)  NOT NULL,
    [MASSIMO_GIORNI] NUMERIC (18)  NOT NULL,
    [NOTE]           VARCHAR (MAX) NULL,
    PRIMARY KEY CLUSTERED ([ID_TIPOLOGIE] ASC)
);

GO
INSERT INTO dbo.[TIPOLOGIE] (NOME,TIPO,ABBREVIAZIONE,MASSIMO_GIORNI,NOTE)
 VALUES ('prova_nome','ferie_retribuite','f_r',32,'note_varie');

INSERT INTO dbo.[TIPOLOGIE] (NOME,TIPO,ABBREVIAZIONE,MASSIMO_GIORNI,NOTE)
 VALUES ('prova_nome','ferie_non_retribuite','f_n_r',15,'note_varie')

GO
PRINT '----------';
PRINT 'Dobbiamo ruotare questo risultato:';

SELECT t.[ABBREVIAZIONE], t.[TIPO], SUM(a.[GIORNI]) AS [Assenze]
  FROM [dbo].[TIPOLOGIE] t
    JOIN dbo.[ASSENZA] A ON a.[TIPO_TIPO] = t.[ABBREVIAZIONE]
  GROUP BY t.[ABBREVIAZIONE], t.[TIPO];
GO
PRINT '----------';
PRINT 'Se avessimo la conooscenza a priori dei valori di rotazioni,';
PRINT ' nel nostro caso [f_r] e [f_n_r], potremmo anche fare una';
PRINT ' query hard coded definitiva tipo:';
SELECT [f_r] AS [ferie_retribuite], [f_n_r] AS [ferie_non_retribuite]
  FROM 
    (  SELECT t.[ABBREVIAZIONE], a.[GIORNI]
        FROM [dbo].[TIPOLOGIE] t
          JOIN dbo.[ASSENZA] A ON a.[TIPO_TIPO] = t.[ABBREVIAZIONE]
    ) AS SourceTable
    PIVOT 
    (
      SUM([GIORNI])
      FOR [ABBREVIAZIONE] IN ([f_r], [f_n_r])
    ) AS PivotTable;
GO
PRINT '----------';
PRINT 'Ma visto che preleviamo l''asse di rotazione delle righe da';
PRINT ' una tabella separata che potenzialmente contiene valorizzazioni';
PRINT ' molteplici, allora dobbiamo purtroppo passare per una query';
PRINT ' costruita dinamicamente, dove svilupperemo nell''asse delle';
PRINT ' colonne proiettate tutte le valorizzazioni di Tipologia di assenza';
PRINT '';
PRINT 'Costruiamo quindi:';
PRINT '1) un ''comando'' di selezione delle valorizzazioni,';
PRINT '   con apposito RENAME della colonna proiettata ( AS xxx);';
PRINT '2) un ''comando'' di selezione delle valorizzazioni da utilizzare';
PRINT '   nella rotazione di PIVOTing;';
PRINT '3) il comando finale di selezione ottenuto dalla concatenazione';
PRINT '   dei ''comandi'' precedenti con l''ovvia aggiunta della ;';
PRINT '   proiezione di PIVOT;';
PRINT '4) una volta ottenuta la query dinamica possiamo procedere';
PRINT '   alla sua esecuzione tramite EXECUTE @query.';

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
  @colPivot AS NVARCHAR(MAX);



-- la selezione delle colonne con RENAME
SELECT @cols = STUFF(
      (SELECT ',' 
            + QUOTENAME(t.[ABBREVIAZIONE]) + ' AS ' + QUOTENAME(t.[TIPO])
                FROM [dbo].[TIPOLOGIE] t
            FOR XML PATH('')), 1 , 1, '');

-- SELECT @cols;      

-- la selezione delle colonne per il pivoting
SELECT @colPivot = STUFF(
      (SELECT ','
            + QUOTENAME(t.[ABBREVIAZIONE])
                FROM [dbo].[TIPOLOGIE] t
            FOR XML PATH('')), 1 , 1, '');

--SELECT @colPivot;


SELECT @query = 'SELECT ' + @cols + ' 
  FROM 
    (  SELECT t.[ABBREVIAZIONE], a.[GIORNI]
        FROM [dbo].[TIPOLOGIE] t
          JOIN dbo.[ASSENZA] A ON a.[TIPO_TIPO] = t.[ABBREVIAZIONE]
    ) AS SourceTable
    PIVOT 
    (
      SUM([GIORNI])
      FOR [ABBREVIAZIONE] IN ( ' + @colPivot + ' )
    ) AS PivotTable;'

-- l'attuale query da eseguire
SELECT @query;

-- esecuzione della query
EXEC (@query);
GO
PRINT '----------';
PRINT 'clean up';
DROP TABLE dbo.ASSENZA, dbo.TIPOLOGIE;
--<-----------------
----------
Dobbiamo ruotare questo risultato:
ABBREVIAZIONE   TIPO                      Assenze
--------------- ------------------------- --------
f_n_r           ferie_non_retribuite      2
f_r             ferie_retribuite          8

----------
Se avessimo la conooscenza a priori dei valori di rotazioni,
 nel nostro caso [f_r] e [f_n_r], potremmo anche fare una
 query hard coded definitiva tipo:
ferie_retribuite                        ferie_non_retribuite
--------------------------------------- ---------------------------------------
8                                       2

----------
Ma visto che preleviamo l'asse di rotazione delle righe da
 una tabella separata che potenzialmente contiene valorizzazioni
 molteplici, allora dobbiamo purtroppo passare per una query
 costruita dinamicamente, dove svilupperemo nell'asse delle
 colonne proiettate tutte le valorizzazioni di Tipologia di assenza
 
Costruiamo quindi:
1) un 'comando' di selezione delle valorizzazioni,
   con apposito RENAME della colonna proiettata ( AS xxx);
2) un 'comando' di selezione delle valorizzazioni da utilizzare
   nella rotazione di PIVOTing;
3) il comando finale di selezione ottenuto dalla concatenazione
   dei 'comandi' precedenti con l'ovvia aggiunta della ;
   proiezione di PIVOT;
4) una volta ottenuta la query dinamica possiamo procedere
   alla sua esecuzione tramite EXECUTE @query.

--------------------------------------------------------------------------
SELECT [f_r] AS [ferie_retribuite],[f_n_r] AS [ferie_non_retribuite] 
  FROM  etc....

ferie_retribuite                        ferie_non_retribuite
--------------------------------------- ----------------------------------
8                                       2

----------
clean up



salutoni ed auguri di una splendida fine e miglior inizio...
Modificato da Andrea Montanari il 28 dicembre 2015 13.32 - accorciato separazioni, scusate :)

Andrea Montanari
http://www.hotelsole.com - http://www.hotelsole.com/asql/index.php
9 messaggi dal 04 ottobre 2012
GRAZIE per il post di risposta.
Da solo non ci sarei MAI arrivato....
In questi giorni non riuscirò a provarlo, ma passate le feste sicuramente ti farò sapere come è andata.
Grazie Ancora e buona giornata
9 messaggi dal 04 ottobre 2012
PERFETTO!!!!
Funziona alla grande.
Ma soprattutto, con questa procedura mi hai fatto capire, o meglio chiarito, alcune cosette che non avevo ben chiare.
GRAZIE Ancora Andrea!!
Buon 2016!! AUGURI.

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.