Avatar billede jangravgaard Nybegynder
10. november 2003 - 17:27 Der er 15 kommentarer

query på tværs af 3 tabeller

jeg har 3 tabeller hvor jeg skal trække data ud. Jeg vil selectere på 2 fields fra 2 af tabellerne. Fra den sidste tabel vil jeg bare tælle antal der matcher mine kriterier.

tabel 1 (cargoline)
Orderid
Goodsdescription
.....
....

tabel 2 (orders)
Orderid
registeredtime

tabel 3 (orderparcelnumbers)
Orderid
Parcelnumber

Jeg vil f.eks gerne have antallet af pakker (parcelnumber) fra den 1/9/03 (2003-09-01) hvor goodsdescription er lig med 'afhenter'

Er der nogen der kan lave sådan en fyr bedst mulig ?
Avatar billede jangravgaard Nybegynder
10. november 2003 - 19:32 #1
Jeg har fundet frem til dette her, men det er ikke helt godt nok:

SELECT OrderParcelNumbers.ParcelNumber, CargoLine.GoodsDescription, OrderStatus.TimeStatus
FROM TransFleet.dbo.CargoLine CargoLine, TransFleet.dbo.OrderParcelNumbers OrderParcelNumbers, TransFleet.dbo.OrderStatus OrderStatus
WHERE CargoLine.OrderId = OrderStatus.OrderId AND OrderParcelNumbers.OrderId = OrderStatus.OrderId AND ((OrderStatus.TimeStatus>{ts '2003-09-01 00:00:00'} And OrderStatus.TimeStatus<{ts '2003-09-02 00:00:00'}))
GROUP BY OrderParcelNumbers.ParcelNumber, CargoLine.GoodsDescription, OrderStatus.TimeStatus
HAVING (CargoLine.GoodsDescription='afhenter')

Vil kun have antallet af pakker der har goodsdescription "afhenter"
Avatar billede krasmussen Nybegynder
10. november 2003 - 19:56 #2
Tilføj i din where-clause: AND Cargoline.GoodsDescription = 'afhenter'. HAVING bruges normalt kun til kalkulerede udtryk og den er DYR i hastighed.

Et lille tip for overblikket's skyld: I din SELECT og FROM kan du gøre sådan

SELECT a.ParcelNumber, b.GoodsDescription, c.bla.bla .......
FROM OrderParcelsNumbers a, CargoLine b osv.
WHERE a.OrderId = c.OrderId
  AND .........
Avatar billede jangravgaard Nybegynder
10. november 2003 - 19:59 #3
okay, kan du fortælle mig hvordan jeg får en count på parcelnumber flettet ind ?
Avatar billede krasmussen Nybegynder
11. november 2003 - 07:41 #4
F.eks. SELECT a.ParcelNumber, COUNT(a.ParcelNumber) AS SumPK, b.GoodsDescription osv. osv.
Avatar billede jangravgaard Nybegynder
11. november 2003 - 08:28 #5
Jeg har lavet det om til:

SELECT
a.ParcelNumber,
COUNT(a.ParcelNumber) AS SumPK,
b.GoodsDescription,
c.TimeStatus
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>{ts '2003-09-01 00:00:00'} And c.TimeStatus<{ts '2003-09-02 00:00:00'} AND
b.GoodsDescription='afhenter'
GROUP BY a.ParcelNumber, b.GoodsDescription, c.TimeStatus

men min SumPK bliver kun 1. Resultatet er vist herunder...

ParcelNumber                        SumPK      GoodsDescription                                                                                    TimeStatus ParcelNumber  SumPK      GoodsDescription  TimeStatus                                           
-----------------------------------
109391117136    1          Afhenter 2003-09-01 12:37:59.000
109401517149    1          Afhenter 2003-09-01 16:10:58.000
109401517149    1          Afhenter 2003-09-01 16:11:07.000
109409417150    1          Afhenter 2003-09-01 17:11:08.000
109406617151    1          Afhenter 2003-09-01 17:11:39.000
109401517149    1          Afhenter 2003-09-01 19:22:00.000

(6 row(s) affected)
Avatar billede krasmussen Nybegynder
11. november 2003 - 09:30 #6
Er der fejl i res. eller ?? prøv evt. at angive TimeStatus som #2003-09-01 00:00:00#
Avatar billede jangravgaard Nybegynder
11. november 2003 - 09:34 #7
nej, der er ikke decideret fejl i resultatet, men min sum bliver ikke 6 som jeg gerne vil have det til at blive. Altså at sum indeholder antallet af rows affected.....
Avatar billede krasmussen Nybegynder
11. november 2003 - 09:42 #8
OK, det kan du ikke gøre i samme script uden at bruge UNION - kan ikke uniddelbart huske syntaxen, men det er noget i stil med, at efter dette script skal du skrive a la:

UNION
SELECT count(*)
FROM - og så dine betingelser.

Du kan også prøve, at ændre COUNT(a.ParcelNumber) til COUNT(*)
Avatar billede jangravgaard Nybegynder
11. november 2003 - 10:56 #9
Jeg har ikke det store held med en union, men tænkte på om jeg ikke kunne gøre noget i stil med:

select count(*) from orderparcelnumbers where parcelnumber in (
   
    SELECT
    a.ParcelNumber,
    b.GoodsDescription,
    c.TimeStatus
    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>{ts '2003-09-01 00:00:00'} And c.TimeStatus<{ts '2003-09-02 00:00:00'} AND
    b.GoodsDescription='afhenter'
)

Jeg får dog desværre denne fejl meddelse:
Server: Msg 116, Level 16, State 1, Line 1
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS.

og har ikke kunnet finde ud af hvordan jeg fletter "exists" ind i min query....
Avatar billede krasmussen Nybegynder
11. november 2003 - 11:04 #10
Det siger mig umiddelbart intet, prøv at fjerne nogle af argumenterne (bare for at teste)
Avatar billede jangravgaard Nybegynder
11. november 2003 - 11:06 #11
samme besked, hvis jeg udelader

    WHERE
    b.OrderId = c.OrderId AND
    a.OrderId = c.OrderId AND
    c.TimeStatus>{ts '2003-09-01 00:00:00'} And c.TimeStatus<{ts '2003-09-02 00:00:00'} AND
    b.GoodsDescription='afhenter'
Avatar billede krasmussen Nybegynder
11. november 2003 - 12:42 #12
Så er du nødt til, at tage fat i manualet/guiden - den ligger bla. på CD'en - og se lidt på UNION eller søge efter spm. her på exp.
Avatar billede jangravgaard Nybegynder
11. november 2003 - 12:54 #13
Okay, smid lige et svar for din ulejlighed.......
Avatar billede krasmussen Nybegynder
11. november 2003 - 13:07 #14
Nej det er OK !, jeg gav dig ikke en løsning - men du er velkommen til at maile mig DB, så kan jeg se om jeg hurtigt kan omforme min Oracle/informix SQL til noget du kan bruge.
Avatar billede krasmussen Nybegynder
11. november 2003 - 13:32 #15
Forresten en ide: Du kan evt. starte med et seperat script som COUNT i en temp tabel
SELECT COUNT(a.ParcelNumber), osv osv.
INTO TEMP abc
WHERE bla. bla.;
<dit script her> og med i din select skal du tage værdien fra abc. Prøv først at selecte til temp abc for, at se hvordan kolonnen med resultsettet navngives
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Computerworld tilbyder specialiserede kurser i database-management

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester