<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlserver.ro/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>T-SQL</title><link>http://sqlserver.ro/forums/15/ShowForum.aspx</link><description /><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>Re: pivot on sql</title><link>http://sqlserver.ro/forums/thread/3632.aspx</link><pubDate>Wed, 19 Dec 2007 16:53:28 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:3632</guid><dc:creator>B_gd_n[ ]Sahlean</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/3632.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=15&amp;PostID=3632</wfw:commentRss><description>&lt;P align=justify&gt;Interogarile crosstab / pivot table (tabel pivot)&amp;nbsp;pot fi clasificate SIMPLIST&amp;nbsp;în:&lt;BR&gt;a) interogari cu un numar fix variabil de coloane si&lt;BR&gt;b) interogari un un numar variabil de coloane. &lt;/P&gt;
&lt;P align=justify&gt;Pentru a fi clar modul de crearea a interogarilor crosstab se va utiliza urmatoarea tabela cu încasari:&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;CREATE TABLE Incasari(IDIncasare INT, Data DATETIME , Suma MONEY)&lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;În aceasta tabela se adauga urmatoarele înregistrari de test pentru anul 2004: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (1 ,'2004-01-10',100000)&lt;BR&gt;INSERT INTO Incasari VALUES (2 ,'2004-01-15',50000)&lt;BR&gt;INSERT INTO Incasari VALUES (3 ,'2004-01-20',60000) &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (5 ,'2004-02-10',110000)&lt;BR&gt;INSERT INTO Incasari VALUES (6 ,'2004-02-15',40000)&lt;BR&gt;INSERT INTO Incasari VALUES (7 ,'2004-02-20',45000) &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (9 ,'2004-03-10',55000)&lt;BR&gt;INSERT INTO Incasari VALUES (10,'2004-03-15',65000)&lt;BR&gt;INSERT INTO Incasari VALUES (12,'2004-03-20',75000) &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;si pentru anul 2005: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (1 ,'2005-01-10',110000)&lt;BR&gt;INSERT INTO Incasari VALUES (2 ,'2005-01-15',51000)&lt;BR&gt;INSERT INTO Incasari VALUES (3 ,'2005-01-20',61000) &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (5 ,'2005-02-10',111000)&lt;BR&gt;INSERT INTO Incasari VALUES (6 ,'2005-02-15',41000)&lt;BR&gt;INSERT INTO Incasari VALUES (7 ,'2005-02-20',45100) &lt;/FONT&gt;&lt;/P&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;INSERT INTO Incasari VALUES (9 ,'2005-03-10',55100)&lt;BR&gt;INSERT INTO Incasari VALUES (10,'2005-03-15',65100)&lt;BR&gt;INSERT INTO Incasari VALUES (12,'2005-03-20',75100) &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Se doreste afisarea încasarilor totale din fiecare an pe fiecare luna. &lt;/P&gt;
&lt;P&gt;În cazul crearii unei interogari cu un numar fix de coloane (trei coloane) se va utiliza urmatoarea interogare SQL: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;SELECT YEAR(Data) AS An, &lt;BR&gt;SUM(CASE WHEN MONTH(Data)=1 THEN Suma ELSE 0 END) AS 'Col1',&lt;BR&gt;SUM(CASE WHEN MONTH(Data)=2 THEN Suma ELSE 0 END) AS 'Col2',&lt;BR&gt;SUM(CASE WHEN MONTH(Data)=3 THEN Suma ELSE 0 END) AS 'Col3'&lt;BR&gt;FROM Incasari&lt;BR&gt;GROUP BY YEAR(Data) &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P align=justify&gt;În acesta situatie se afiseaza pentru fiecare an pentru care s-au înregistrat încasari YEAR(Data) suma totala a încasarilor din primele trei luni (MONTH(Data)=1,2 sau 3) adica:&lt;FONT face="Courier New" size=2&gt;&lt;BR&gt;&amp;nbsp;&lt;/FONT&gt;&lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;SUM(CASE WHEN MONTH(Data)=1 THEN Suma ELSE 0 END) samd. &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Astfel, indiferent daca în baza de date sunt încasari din lunile 1,2,3,...12 interogarea va afisa totalul încasarilor din primele trei luni: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;&lt;PRE&gt;An          Col1                  Col2                  Col3	                   
----------- --------------------- --------------------- ----------- 
2004        210000.0000           195000.0000           195000.0000
2005        222000.0000           197100.0000           195300.0000&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Pentru&amp;nbsp;obtinerea unei tabele pivot cu un numar variabil de coloane&amp;nbsp;trebuie sa&amp;nbsp;se genereze dinamic o interogare SQL. Procedura urmatoare genereaza o astfel de interogare SQL.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;De asemenea, solutia propusa în acest articol se poate folosi pentru cazurile în care valorile tip „Row Heading” (în acest caz anii: 2004, 2005) si cele de tip „Column Heading” (lunile din exemplul nostru: 1,2,3) sunt de tip INT (numere întregi). &lt;/P&gt;
&lt;P&gt;Procedura stocata are urmatoarea structura (binenteles ca acesta procedura stocata poate fi modificata pentru a prelucra si alte tipuri de date): &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;CREATE PROCEDURE spCrossTab &lt;BR&gt;@tabel AS NVARCHAR(255),&lt;BR&gt;@linie AS NVARCHAR(255),&lt;BR&gt;@coloana AS NVARCHAR(255),&lt;BR&gt;@functie AS NVARCHAR(255),&lt;BR&gt;@valoare AS NVARCHAR(255)&lt;BR&gt;AS&lt;BR&gt;CREATE TABLE #aux(Camp INT)&lt;BR&gt;DECLARE @sql AS NVARCHAR(500), @camp AS INT, @sir_coloane AS NVARCHAR(500)&lt;BR&gt;SET @sql = 'SELECT DISTINCT '+@coloana+' FROM '+@tabel+' ORDER BY '+@coloana&lt;BR&gt;INSERT INTO #aux EXEC sp_executesql @sql&lt;BR&gt;SET @sir_coloane = ''&lt;BR&gt;DECLARE crs CURSOR FAST_FORWARD FOR SELECT Camp FROM #aux&lt;BR&gt;OPEN crs&lt;BR&gt;FETCH NEXT FROM crs INTO @camp&lt;/FONT&gt;&lt;BR&gt;&lt;FONT face="Courier New" size=2&gt;WHILE @@FETCH_STATUS = 0&lt;BR&gt;BEGIN&lt;BR&gt;SET @sir_coloane = @sir_coloane + ',' + @functie+'(CASE WHEN '+@coloana+'='+CAST(@camp AS NVARCHAR(25))+' THEN '+@valoare+' ELSE 0 END) AS [Col'+CAST(@camp AS NVARCHAR(25))+']'&lt;BR&gt;FETCH NEXT FROM crs INTO @Camp&lt;BR&gt;END&lt;BR&gt;CLOSE crs&lt;BR&gt;DEALLOCATE crs&lt;BR&gt;SET @sql = 'SELECT '+@linie+' AS [Linie]'+@sir_coloane+' FROM '+@tabel+' GROUP BY '+@linie+' ORDER BY '+@linie&lt;BR&gt;EXEC sp_executesql @sql&lt;BR&gt;DROP TABLE #aux &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Apelul procedurii astfel definite se poate realiza astfel: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;
&lt;P align=justify&gt;&lt;FONT face="Courier New" size=2&gt;EXEC spCrossTab 'Incasari','YEAR(Data)','MONTH(Data)','SUM','Suma' &lt;/FONT&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;rezultatele fiind aceleasi: &lt;/P&gt;
&lt;DIV style="BACKGROUND-COLOR:#c0c0c0;"&gt;&lt;PRE&gt;Linie       Col1                  Col2                  Col3                  
----------- --------------------- --------------------- --------------- 
2004        210000.0000           195000.0000           195000.0000
2005        222000.0000           197100.0000           195300.0000&lt;/PRE&gt;&lt;/DIV&gt;
&lt;P&gt;Parametrii procedurii stocate au urmatoarele semnificatii:&lt;BR&gt;- ‘Incasari’ : tabela sursa, poate fi si o lista de tabele conectate folosind operatorii JOIN,&lt;BR&gt;- ‘YEAR(Data)’ : valorile care vor fi afisate în antetul fiecarei linii,&lt;BR&gt;- ‘MONTH(Data)’ : valorile care vor constitui antetul fiecarei coloane,&lt;BR&gt;- ‘SUM’ : functia folosita pentru agregarea datelor din urmatoarea coloana,&lt;BR&gt;- ‘Suma’ : coloana folosita pentru agregarea datelor. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item><item><title>pivot on sql</title><link>http://sqlserver.ro/forums/thread/3631.aspx</link><pubDate>Wed, 19 Dec 2007 15:37:57 GMT</pubDate><guid isPermaLink="false">963f3a18-65dd-4aad-905c-b785cfe1d7c7:3631</guid><dc:creator>neo</dc:creator><slash:comments>0</slash:comments><comments>http://sqlserver.ro/forums/thread/3631.aspx</comments><wfw:commentRss>http://sqlserver.ro/forums/commentrss.aspx?SectionID=15&amp;PostID=3631</wfw:commentRss><description>&lt;P&gt;salut &lt;/P&gt;
&lt;P&gt;daca am nivelul de compatibilitate pe sql 2005 (80 in loc de 90 si nu il schimb ca nu trebuie)&amp;nbsp; cum pot face sa lucrez cu pivot pe sql 2005 avand in vedere ca pivotul pe 2005 are ca cerinte nivel de compatibilitate :90?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;merci&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description></item></channel></rss>