11. november 2003 - 21:34Der er
12 kommentarer og 1 løsning
Mange queries eller een stor ?
Jeg har behov for at udfylde en tabel med data fra min db Tabellen indeholder rækker svarende til valgt måned (max 31 )og har 12 kolonner. Til hver felt har jeg pt een query. Men det bliver jo til rigtig mange (372) kald til db'en og jeg synes ligesom at det må kunne optimeres. Enten ved at lave en query der returnerer alle data og så senere splitte den op i rækker/kolonner eller få en hel kolonne i hvert kald.....
Ligenu har jeg denne query: exec usp_count_parcels @time = '2003-09-02 00:00:00', @description = 'afhenter' min sp ser sådan ud: CREATE PROCEDURE usp_count_parcels @time datetime, @description varchar(100) AS
SELECT count(*) as number FROM TransFleet.dbo.CargoLine b, TransFleet.dbo.OrderParcelNumbers a, TransFleet.dbo.OrderStatus c WHERE b.OrderId = c.OrderId AND a.OrderId = c.OrderId AND c.TimeStatus>@time AND c.TimeStatus<@time+1 AND b.GoodsDescription = @description GROUP BY a.ParcelNumber, b.GoodsDescription, c.TimeStatus
Jeg har 3 tabeller som ser sådan ud (kun de væsentlige felter er vist)
[Cargoline] GoodsDescription
[OrderParcelNumbers] ParcelNumber OrderId
[OrderStatus] TimeStatus OrderId
Den tabel jeg skal lave som indeholder informationen som hentes med sql, ser sådan ud www.jgdata.dk/oversigt.jpg
Den er forkortet lidt over viser kun data for 10 dage. For hver dag skal der findes ud af hvor mange pakker der er sendt for hver forsendelsesmetode. Der er pt 17 og ikke 12 som jeg skrev før.
Essensen er jo så at minimere presset på sql serveren, da den lige nu udfører een query pr felt i min tabel som kan ses på ovennævnte url.
Ok, det du forsøger virker som om det er en pivot-tabel du har gang i. Der er ikke rigtig nogen køn - eller dynamisk - måde at gøre det på i SQL Server, men nedenstående kan nok hjælpe.
Du skal lige rette lidt til - jeg har bl.a. ikke fanget hvorfor din OrderParcelNumbers indgår.
Sørg også for at alle OrderID og Goodsdescription kolonner er understøttet af index.
select goodsdescription, (select count(*) from orderparcelnumbers opn inner join orderstatus os on os.orderid = opn.orderid inner join cargoline cl on opn.orderid = cl.orderid and cl.goodsdescription = x.goodsdescription and day(os.timestatus)=1) as day1, .... (select count(*) from orderparcelnumbers opn inner join orderstatus os on os.orderid = opn.orderid inner join cargoline cl on opn.orderid = cl.orderid and cl.goodsdescription = x.goodsdescription and day(os.timestatus)=1) as day1, (select count(*) from orderparcelnumbers opn inner join orderstatus os on os.orderid = opn.orderid inner join cargoline cl on opn.orderid = cl.orderid and cl.goodsdescription = x.goodsdescription and day(os.timestatus)=10) as day10, (select count(*) from orderparcelnumbers opn inner join orderstatus os on os.orderid = opn.orderid inner join cargoline cl on opn.orderid = cl.orderid and cl.goodsdescription = x.goodsdescription and day(os.timestatus)=11) as day11, (select count(*) from orderparcelnumbers opn inner join orderstatus os on os.orderid = opn.orderid inner join cargoline cl on opn.orderid = cl.orderid and cl.goodsdescription = x.goodsdescription and day(os.timestatus)=12) as day12 .... from (select distinct goodsdescription from cargoline) x
"ps, jeg har to logins...... jangravgaard = mungojerrie :-)" Og du har naturligvis læst sitets regler da du oprettede dem begge, og dermed opdaget at det ikke er tilladt? Afmelder du selv den ene bruger, eller skal jeg deaktivere dem begge?
okay, jeg har siddet og kodet lidt idet og er kommet frem til en anden mulighed, som jeg tror er lidt bedre. Men jeg har dog lidt problemer med den, måske kan du hjælpe ?
For hver af mine goodsdescriptions vil jeg lave een stor query som i princippet først kontrollere om min temporære tabel eksisterer og sletter den hvis den gør. Herefter skaber jeg tabellen og indsætter en record for hver dag i måneden. Altså vil tabellen indeholde 31 entries for januar måned. Tabellen ser således ud:
Fejlen er at jeg må ikke benytte en SP som en subquery og ej heller SELECT statement, som denne der gør det samme som min SP :
SELECT Count(Distinct parcelnumber) AS antalpakker FROM TransFleet.dbo.CargoLine b, TransFleet.dbo.OrderParcelNumbers a, TransFleet.dbo.OrderStatus c WHERE b.OrderId = c.OrderId AND a.OrderId = c.OrderId AND c.TimeStatus>'2003-09-10 00:00:00' AND c.TimeStatus<'2003-09-11 00:00:00' AND b.GoodsDescription='$Afhenter' )
Fejlen hedder : Subqueries are not allowed in this context. Only scalar expressions are allowed.
Okay, jeg har fundet mig en anden løsning dog som er delvis php og sql
Jeg laver så en query for hver item i min array på denne select sætning
select distinct description from customergoods where description in ( 'Afhenter', 'GLS-Ekspres', 'GLS-Ekspres/efterkrav', GLS-Ekspres/opbæring', 'GLS-Normal', 'GLS-Normal/efterkrav', 'GLS-Opbæring', 'GLS-Palle/ekspress', 'GLS-Palle/normal', 'GLS-Palle/opbæring', 'Intern', 'Kurer', 'Mahè Freight', 'Post', 'Posten Ekspr', 'Udland', 'Unicef') order by description
for hver item kalder jeg denne SP:
CREATE PROCEDURE usp_get_data_per_MOT @time datetime, @description varchar(100), @dayofmonth int AS
DECLARE @counter int
WHILE @dayofmonth > 0 BEGIN
SET @counter = ( SELECT Count(Distinct parcelnumber) FROM TransFleet.dbo.CargoLine b, TransFleet.dbo.OrderParcelNumbers a, TransFleet.dbo.OrderStatus c WHERE b.OrderId = c.OrderId AND a.OrderId = c.OrderId AND c.TimeStatus>@time AND c.TimeStatus<@time+1 AND b.GoodsDescription=@description )
SET @dayofmonth = @dayofmonth - 1 SET @time = @time + 1
END
Til sidst trækker jeg data ud for hver item med :
select * from TempForsendelsesOversigt where goodsdescription = '$description'
Det ser dog ikke ud til at gå væsentlig stærkere som jeg havde håbet på, men jeg har da fået lært noget mere om SQL, så helt skidt er det jo ikke. Jeg takker for hjælpen :-)
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.