|
Ajutor optimizare interogare
Last post 02-02-2008, 2:23 PM by ThePuiu. 8 replies.
-
02-01-2008, 1:24 AM |
-
ThePuiu
-
-
-
Joined on 02-14-2007
-
Oradea
-
db_owner
-
-
|
Ajutor optimizare interogare
Se dau 3 tabele:
[FACTURI]( [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [NUMAR] [numeric](18, 0) NULL, [DATA] [datetime] NULL)
[DETAIL] ( [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [ID_FACTURA] [numeric](18, 0) NULL, [ID_PRODUS] [numeric](18, 0) NULL)
[PRODUSE] ( [ID] [numeric](18, 0) IDENTITY(1,1) NOT NULL, [PRODUS] [nvarchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL)
DETAIL.ID_FACTURA = FACTURI.ID DETAIL.ID_PRODUS = PRODUSE.ID
In tabela FACTURI se gasesc antetele facturii (numar factura si data emitere), in DETAIL sint produsele vindute sub forma de coduri care se regasesc in tabela PRODUSE. In tabela produse se gasesc un numar mare (mii de produse). Ce as vrea sa fac intr-un mod cit mai elegant: un tabel care sa aiba ca si capete de coloana: 1. Cod produs 2. Ziua 1 a lunii 3. Ziua 2 a lunii ------------------- 32. Ziua 31 a lunii 33. Total per produs
Ca si linii in tabel vor fi: Coloana 1: produsele in ordine alfabetica Coloana 2: numarul de aparitii [count(PRODUS1)] din ziua 1 a lunii Coloana 3: numarul de aparitii [count(PRODUS1)] din ziua 2 a lunii etc Coloana 33: suma aparitiilor pt cele 31 zile pt produsul PRODUS1
Numarul de coloane trebuie determinat automat (nu toate lunile au 31 de zile!), chiar daca tabela care va contine rezultatul va avea un nr fix de coloane, zilele lipsa din luna vor contine 0 sau null. Se poate face chestia asta fara a face select count(P1), count(P2), etc de 31 de ori? As dori ceva cit de cit rapid, iar pe mine ma cam depaseste!
Multumesc anticipat!
|
|
-
02-01-2008, 8:52 AM |
-
rsocol
-
-
-
Joined on 10-03-2006
-
Bucuresti
-
sysadmin
-
-
|
Re: Ajutor optimizare interogare
Dacă te interesează o soluţie pentru SQL 2000, atunci poţi să faci ceva de genul: SELECT Produs, SUM(CASE WHEN DAY(Data)=1 THEN 1 ELSE 0 END) AS [1], SUM(CASE WHEN DAY(Data)=2 THEN 1 ELSE 0 END) AS [2], SUM(CASE WHEN DAY(Data)=3 THEN 1 ELSE 0 END) AS [3], SUM(CASE WHEN DAY(Data)=4 THEN 1 ELSE 0 END) AS [4], SUM(CASE WHEN DAY(Data)=5 THEN 1 ELSE 0 END) AS [5], SUM(CASE WHEN DAY(Data)=6 THEN 1 ELSE 0 END) AS , SUM(CASE WHEN DAY(Data)=7 THEN 1 ELSE 0 END) AS [7], SUM(CASE WHEN DAY(Data)=8 THEN 1 ELSE 0 END) AS , SUM(CASE WHEN DAY(Data)=9 THEN 1 ELSE 0 END) AS [9], SUM(CASE WHEN DAY(Data)=10 THEN 1 ELSE 0 END) AS [10], SUM(CASE WHEN DAY(Data)=11 THEN 1 ELSE 0 END) AS [11], SUM(CASE WHEN DAY(Data)=12 THEN 1 ELSE 0 END) AS [12], SUM(CASE WHEN DAY(Data)=13 THEN 1 ELSE 0 END) AS [13], SUM(CASE WHEN DAY(Data)=14 THEN 1 ELSE 0 END) AS [14], SUM(CASE WHEN DAY(Data)=15 THEN 1 ELSE 0 END) AS [15], SUM(CASE WHEN DAY(Data)=16 THEN 1 ELSE 0 END) AS [16], SUM(CASE WHEN DAY(Data)=17 THEN 1 ELSE 0 END) AS [17], SUM(CASE WHEN DAY(Data)=18 THEN 1 ELSE 0 END) AS [18], SUM(CASE WHEN DAY(Data)=19 THEN 1 ELSE 0 END) AS [19], SUM(CASE WHEN DAY(Data)=20 THEN 1 ELSE 0 END) AS [20], SUM(CASE WHEN DAY(Data)=21 THEN 1 ELSE 0 END) AS [21], SUM(CASE WHEN DAY(Data)=22 THEN 1 ELSE 0 END) AS [22], SUM(CASE WHEN DAY(Data)=23 THEN 1 ELSE 0 END) AS [23], SUM(CASE WHEN DAY(Data)=24 THEN 1 ELSE 0 END) AS [24], SUM(CASE WHEN DAY(Data)=25 THEN 1 ELSE 0 END) AS [25], SUM(CASE WHEN DAY(Data)=26 THEN 1 ELSE 0 END) AS [26], SUM(CASE WHEN DAY(Data)=27 THEN 1 ELSE 0 END) AS [27], SUM(CASE WHEN DAY(Data)=28 THEN 1 ELSE 0 END) AS [28], SUM(CASE WHEN DAY(Data)=29 THEN 1 ELSE 0 END) AS [29], SUM(CASE WHEN DAY(Data)=30 THEN 1 ELSE 0 END) AS [30], SUM(CASE WHEN DAY(Data)=31 THEN 1 ELSE 0 END) AS [31], COUNT(*) AS Total FROM Facturi f INNER JOIN Detail m ON f.ID=m.ID_Factura INNER JOIN Produse p ON p.ID=m.ID_Produs WHERE Data BETWEEN '20060801' AND '20060831' GROUP BY Produs ORDER BY ProdusDacă ai SQL Server 2005, atunci poţi să foloseşti PIVOT: SELECT Produs, [1],[2],[3],[4],[5],,[7],,[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31], [1]+[2]+[3]+[4]+[5]++[7]++[9]+[10]+[11]+[12]+[13]+[14]+[15]+[16]+[17]+[18]+[19]+[20]+[21]+[22]+[23]+[24]+[25]+[26]+[27]+[28]+[29]+[30]+[31] as Total FROM ( SELECT Produs, DAY(Data) AS Ziua FROM Facturi f INNER JOIN Detail m ON f.ID=m.ID_Factura INNER JOIN Produse p ON p.ID=m.ID_Produs WHERE Data BETWEEN '20060801' AND '20060831' ) AS X PIVOT (COUNT(Ziua) FOR Ziua IN ( [1],[2],[3],[4],[5],,[7],,[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20],[21],[22],[23],[24],[25],[26],[27],[28],[29],[30],[31] )) AS P ORDER BY ProdusRăzvan PS. Evident, semnele alea stupide reprezintă numerele care ar trebui să fie acolo. Nu ştiu cum fac ca să scriu un 6 între paranteze pătrate fără să apară drăcuşorul respectiv...
|
|
-
02-01-2008, 10:04 AM |
-
ignatandrei
-
-
-
Joined on 11-17-2006
-
Bucuresti
-
sysadmin
-
-
|
Re: Ajutor optimizare interogare - off topic
rsocol: PS. Evident, semnele alea stupide reprezintă numerele care ar trebui să fie acolo. Nu ştiu cum fac ca să scriu un 6 între paranteze pătrate fără să apară drăcuşorul respectiv...
[<spatiu>6<spatiu>] [ 6 ]
Ignat Andrei http://serviciipeweb.ro/iafblog
|
|
-
02-01-2008, 12:58 PM |
-
ThePuiu
-
-
-
Joined on 02-14-2007
-
Oradea
-
db_owner
-
-
|
Re: Ajutor optimizare interogare - off topic
am uitat sa precizez...imi trebuie in Access....din pacate si codul de mai sus nu merge.... Daca nu stii access sa ma luminezi si pe mine (nici eu nu am mai lucrat cu el) o sa incerc sa vad cum pot sa-l retranscriu.....
Multumesc pt raspuns!
|
|
-
02-01-2008, 4:35 PM |
-
rsocol
-
-
-
Joined on 10-03-2006
-
Bucuresti
-
sysadmin
-
-
|
Re: Ajutor optimizare interogare - off topic
În Access există un Crosstab Query Wizard care te poate ajuta, însă ar trebui să faci un alt query înainte ca să poţi să-l foloseşti.
Iar rezultatul ar trebui să fie ceva de genul:
TRANSFORM COUNT(Produse.ID) SELECT Produse.Produs, COUNT(Produse.ID) AS Total FROM (Detail INNER JOIN Facturi ON Detail.ID=Facturi.ID) INNER JOIN Produse ON Detail.ID=Produse.ID GROUP BY Produse.Produs PIVOT DAY(Facturi.Data);
Răzvan
|
|
-
02-01-2008, 5:43 PM |
-
B_gd_n[ ]Sahlean
-
-
-
Joined on 07-17-2007
-
Bucuresti
-
sysadmin
-
-
|
Re: Ajutor optimizare interogare - off topic
rsocol: În Access există un Crosstab Query Wizard care te poate ajuta, însă ar trebui să faci un alt query înainte ca să poţi să-l foloseşti.
Iar rezultatul ar trebui să fie ceva de genul:
TRANSFORM COUNT(Produse.ID) SELECT Produse.Produs, COUNT(Produse.ID) AS Total FROM (Detail INNER JOIN Facturi ON Detail.ID=Facturi.ID) INNER JOIN Produse ON Detail.ID=Produse.ID GROUP BY Produse.Produs PIVOT DAY(Facturi.Data);
Răzvan
COUNT din clauza SELECT poate fi eliminat
|
|
-
02-01-2008, 9:40 PM |
-
ThePuiu
-
-
-
Joined on 02-14-2007
-
Oradea
-
db_owner
-
-
|
Re: Ajutor optimizare interogare - off topic
huh! da, face exact ce vreau eu! stii doar ce problema mai este? trebuie sa generez un raport in crystal cu datele obtinute din query. Ma gindeam sa creez un table cu 31 coloane pt zile in care sa copiez rezultatul si din acesta sa afisez raportul. Cum se poate face un insert into cu rezultatele din acest query in tabela de care ziceam mai sus?
Multumesc!
|
|
-
02-02-2008, 8:42 AM |
-
rsocol
-
-
-
Joined on 10-03-2006
-
Bucuresti
-
sysadmin
-
-
|
Re: Ajutor optimizare interogare - off topic
Dar nu poţi să bazezi raportul direct pe query-ul de mai sus ? Dacă nu se poate, atunci mai faci un alt query care să adauge datele în tabel: INSERT INTO rezultat SELECT TheQuery.* FROM TheQuery;
(vezi că în query designer-ul din Acces ai nişte tipuri de query-uri care de ajută la treburile astea: Make-Table Query şi Append Query)
Răzvan
|
|
-
02-02-2008, 2:23 PM |
-
ThePuiu
-
-
-
Joined on 02-14-2007
-
Oradea
-
db_owner
-
-
|
Re: Ajutor optimizare interogare - off topic
da, merge, dar as vrea sa stiu daca nu se pot comasa cumva cele 2 query-uri in unul singur si sintaxa sa o pot folosi intr-o interogare direct in program. As vrea asta pt ca eu vreau sa schimb programatic un interval de timp care l-am adaugat primului query si nu stiu cum sa fac asta fara sa folosesc DAO. (lucrez in C# cu OLE DB).
|
|
|
|
|