2009-11-13 7 views
68

Devo dichiarare 12 variabili decimali, corrispondenti all'anno di ogni mese, con un cursore somma i valori a queste variabili, quindi in seguito aggiorno alcune informazioni di vendita.Come dichiarare la matrice all'interno della stored procedure del server Sql?

non so se il server di SQL hanno questa sintassi

Declare MonthsSale(1 to 12) as decimal(18,2) 

Questo codice funziona bene. !

CREATE PROCEDURE [dbo].[proc_test] 
AS 
BEGIN 

--SET NOCOUNT ON; 

DECLARE @monthsales TABLE (monthnr int, amount decimal(18,2) ) 


-- PUT YOUR OWN CODE HERE 


-- THIS IS TEST CODE 
-- 1 REPRESENTS JANUARY, ... 
INSERT @monthsales (monthnr, amount) VALUES (1, 100) 
INSERT @monthsales (monthnr, amount) VALUES (1, 100) 

INSERT @monthsales (monthnr, amount) VALUES (2, 200) 
INSERT @monthsales (monthnr, amount) VALUES (3, 300) 
INSERT @monthsales (monthnr, amount) VALUES (4, 400) 
INSERT @monthsales (monthnr, amount) VALUES (5, 500) 
INSERT @monthsales (monthnr, amount) VALUES (6, 600) 
INSERT @monthsales (monthnr, amount) VALUES (7, 700) 
INSERT @monthsales (monthnr, amount) VALUES (8, 800) 
INSERT @monthsales (monthnr, amount) VALUES (9, 900) 
INSERT @monthsales (monthnr, amount) VALUES (10, 1000) 
INSERT @monthsales (monthnr, amount) VALUES (11, 1100) 
INSERT @monthsales (monthnr, amount) VALUES (12, 1200) 


SELECT monthnr, SUM(amount) AS SUM_MONTH_1 FROM @monthsales WHERE monthnr = 1 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_2 FROM @monthsales WHERE monthnr = 2 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_3 FROM @monthsales WHERE monthnr = 3 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_4 FROM @monthsales WHERE monthnr = 4 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_5 FROM @monthsales WHERE monthnr = 5 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_6 FROM @monthsales WHERE monthnr = 6 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_7 FROM @monthsales WHERE monthnr = 7 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_8 FROM @monthsales WHERE monthnr = 8 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_9 FROM @monthsales WHERE monthnr = 9 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_10 FROM @monthsales WHERE monthnr = 10 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_11 FROM @monthsales WHERE monthnr = 11 GROUP BY monthnr 
SELECT monthnr, SUM(amount) AS SUM_MONTH_12 FROM @monthsales WHERE monthnr = 12 GROUP BY monthnr 

-- END TEST CODE 
END 

risposta

123

Si potrebbe dichiarare una variabile di tabella (Dichiarazione di variabile di tipo tabella):

declare @MonthsSale table(monthnr int) 
insert into @MonthsSale (monthnr) values (1) 
insert into @MonthsSale (monthnr) values (2) 
.... 

È possibile aggiungere colonne aggiuntive come ti piace:

declare @MonthsSale table(monthnr int, totalsales tinyint) 

È possibile aggiornare la variabile di tabella come qualsiasi altra tabella:

update m 
set m.TotalSales = sum(s.SalesValue) 
from @MonthsSale m 
left join Sales s on month(s.SalesDt) = m.MonthNr 
7

T-SQL non supporta matrici di cui sono a conoscenza.

Qual è la struttura del tuo tavolo? Si potrebbe probabilmente progettare una query che fa questo, invece:

select 
month, 
sum(sales) 
from sales_table 
group by month 
order by month 
+0

Solo come commento laterale, noterei che la sintassi T [n] .v è un po 'più concisa di (selezionare v da T dove T.i = n). In realtà, è un _lot_ più conciso. Mi piacerebbe molto vedere T-SQL aggiungerlo. – debater

22

C'è un motivo per cui non si sta utilizzando una variabile di tabella e l'operatore aggregato SUM, anziché un cursore? SQL eccelle nelle operazioni orientate al set. 99,87% del tempo che ti ritrovi utilizzando un cursore, c'è un set-oriented alternativa che è più efficiente:

declare @MonthsSale table 
(
MonthNumber int, 
MonthName varchar(9), 
MonthSale decimal(18,2) 
) 

insert into @MonthsSale 
select 
    1, 'January', 100.00 
union select  
    2, 'February', 200.00 
union select  
    3, 'March', 300.00 
union select  
    4, 'April', 400.00 
union select  
    5, 'May', 500.00 
union select  
    6, 'June', 600.00 
union select  
    7, 'July', 700.00 
union select  
    8, 'August', 800.00 
union select  
    9, 'September', 900.00 
union select  
    10, 'October', 1000.00 
union select  
    11, 'November', 1100.00 
union select  
    12, 'December', 1200.00 

select * from @MonthsSale 
select SUM(MonthSale) as [TotalSales] from @MonthsSale 
+8

Apparentemente in MSSQL2012 è ora possibile inserire in questo formato: VALORI (1, 'Gennaio', 100,00), (2, 'Febbraio', 200,00) - fonte: http://blog.sqlauthority.com/2012/10/ 27/sql-server-storing-variable-values-in-temporary-array-or-temporary-list/ – andrewb

+2

Questa funzione è sfuggita completamente alla mia notifica; apparentemente funziona anche in SQL 2008. –

1

grande domanda e grande idea, ma in SQL avrete bisogno di fare questo:

Per il tipo di dati datetime, qualcosa come questo-

declare @BeginDate datetime = '1/1/2016', 
     @EndDate  datetime = '12/1/2016' 
create table #months (dates datetime) 
declare @var datetime = @BeginDate 
    while @var < dateadd(MONTH, +1, @EndDate) 
    Begin 
      insert into #months Values(@var) 
      set @var = Dateadd(MONTH, +1, @var) 
    end 

Se tutto quello che vuole veramente è numeri, fare questo-

create table #numbas (digit int) 
declare @var int = 1  --your starting digit 
    while @var <= 12  --your ending digit 
    begin 
     insert into #numbas Values(@var) 
     set @var = @var +1 
    end 
Problemi correlati