Avatar billede bobber Nybegynder
08. februar 2006 - 14:15 Der er 16 kommentarer og
2 løsninger

Hjælp til select query

Hej Eksperter,

Jeg har en select som volder mig lidt problemer.

Det jeg får ud nu fra følgende select er:

SELECT  Id,
    ItemId,
    ItemName,
FROM    HentFraHis
    INNER JOIN
        Getdate ON HentFraHis.Id = Getdate.Id

Det giver mig følgende:

Id ,    ItemId,     ItemName
15      101        Blomster
18    101        Blomster
19    101        Blomster
5    101        Blomster
16    101        Blomster
20    132        Cykel
21    212503001    Kasse


Det jeg gerne vil frem til er følgende:


Id ,    ItemId,     ItemName
19    101        Blomster
20    132        Cykel
21    212503001    Kasse

Det vil sige at jeg vil have er at der kun vises en linie per ItemId og det skal være det højeste ID...

Håber det er forståeligt nok
Avatar billede ldanielsen Nybegynder
08. februar 2006 - 14:24 #1
SELECT MAX(Id), ItemID, ItemName FROM
FROM    HentFraHis
    INNER JOIN
        Getdate ON HentFraHis.Id = Getdate.Id
GROUP BY ItemID, ItemName
Avatar billede bobber Nybegynder
08. februar 2006 - 14:51 #2
Okey, ovenstående vil virke, men jeg har nogle flere rækker som jeg ikke troede var et problem, men det er vidst her det rigtige problem ligger.
Hvis jeg har 2 kolonner mere, quantity og head type som også er forskelligt, så kan jeg ikke nøjes med MAX på ID, kan du mon hjælpe

SELECT  Id,
    ItemId,
    ItemName,
    Quantity,
    HeadType
FROM    HentFraHis
    INNER JOIN
        Getdate ON HentFraHis.Id = Getdate.Id

Det giver mig følgende:

Id ,    ItemId,    ItemName, Quantity, HeadType
15      101        Blomster     2    w
18        101        Blomster    7    sms
19        101        Blomster    5    sms
5        101        Blomster    6    sms
16        101        Blomster    100      sms
20        132        Cykel    1        sms
21    212503001    Kasse    10      sms


Det jeg gerne vil frem til er følgende:

Id ,    ItemId,  ItemName, Quantity, HeadType
19    101        Blomster        5      sms
20    132        Cykel        1      sms
21    212503001    Kasse    10      sms

****
ud for linie 19 er det underordnet om det er w eller sms, bare det er det sidste id inden for det samme item id
Avatar billede ldanielsen Nybegynder
08. februar 2006 - 20:11 #3
OK, så du vil have HeadType med, men du er ligeglad med hvilken du får?

SELECT MAX(Id) AS Id, ItemID, ItemName, MIN(HeadType) AS HeadType FROM
FROM    HentFraHis
    INNER JOIN
        Getdate ON HentFraHis.Id = Getdate.Id
GROUP BY ItemID, ItemName

MIN (minimum) giver den mindste af værdierne, og anvendt på en tekst giver det den først alfabetisk. I dette tilfælde ville det altså være sms der kom ud.

Reglen for GROUP BY er at alle kolonner du SELECT'er skal være med i GROUP BY, eller hentes med en Aggregate Function, dvs MIN, MAX, SUM, AVG eller COUNT.

Jeg har tilføjet AS for de to værdier, så de får et navn i din query
Avatar billede bobber Nybegynder
08. februar 2006 - 20:32 #4
Ja, vi kommer tættere på, men ved ikke om du så at jeg havde tilføjet en kolonne som hed Quantity og den giver mig også problemer, da de også varierer. og derfor vil den vise flere linier og jeg kan ikke bruge min eller max på quantity og quantity skal vises i min query, nogen forslag
Avatar billede ldanielsen Nybegynder
08. februar 2006 - 21:43 #5
Hvis der findes forskellige quantity for en række, og du skal bruge dem alle, så kan det i sagens natur ikke samles til én række. Med mindre du kan bruge det kommasepareret (dårlig løsning, tung at trække for databasen).

Min anbefaling er at lade din application loop'e gennem rækkerne, i stedet for at insistere på at det skal samles fra databasens side.
Avatar billede bobber Nybegynder
09. februar 2006 - 08:45 #6
Jeg skal ikke bruge alle quantity, jeg skal kun bruge den sidste som ville være id 19 med 5 stk i quantity.
Grunden til at jeg vil have databasen til at gøre det, er at det bruges i et view.
Er anbefaling stadig at loope gennem rækkkerne, eller er der en mulighed
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 09:16 #7
Når du kun skal have quantity for den sidste forekomst af et itemid, så kan man sagtens lave det.

Jeg ville starte med at lave et view der giver ItemID med tilhørende MAX id, of jeg tror også jeg vil have ItemName med. Det jeg vil have ud er altså:

Id,    ItemId,    ItemName
19        101        Blomster
20        132        Cykel
21    212503001    Kasse

Det vil jeg lave til et view, og når jeg så vil have resten af data med, vil jeg lave et view der joiner dette view med de relevante tabeller. Et view i et view, så at sige.

Jeg er lige nødt til at få overblik over hvilke kolonner der er i de forskellige tabeller, ellers kan jeg ikke lave det. Kan du give mig strukturen for de to tabeller?
Avatar billede bobber Nybegynder
09. februar 2006 - 10:37 #8
Okey jeg bruger faktisk 3 tabeller, men troede løsningen var mere simpel end det, så derfor oplyste jeg mit eksempel i en simpel udgave, me
her kommer de komplette tabeller og mit view, som det er nu giver det samme udgangspunkt som oplyst tidligere at itemid 101 kommer ud flere gange og jeg
er kun interesseret i det sidste, håber nedenstående kan hjælpe

Tbpurchaseline Indeholder

PurLineId,
PurLineItemId,
PurLineItemName,
PurLineItemUnit,
PurLineUpdated,
PurCartHeadType,
PurLineQuantity,
PurLineQuantityShipped

dbo.TbVendor indeholder
Vendorid
VendorName

dbo.TbItem indeholder
ItemId
ItemPacking,
ItemQtyPacking,

Og her er mit nuværende view:


VIEW dbo.QySpGetItemToHis
AS
SELECT DISTINCT
                      TOP 100 PERCENT MAX(dbo.TbPurchaseLine.PurLineId) AS PurLineId,
              dbo.TbPurchaseLine.PurLineItemId,
              dbo.TbPurchaseLine.PurLineItemName,
                      dbo.TbPurchaseLine.PurLineItemUnit,
              dbo.TbPurchaseLine.PurLineDepId,
                      dbo.TbPurchaseLine.PurLineUpdated,
              dbo.TbPurchaseLine.PurCartHeadType,
              dbo.TbPurchaseLine.PurLineQuantity,
              dbo.TbPurchaseLine.PurLineQuantityShipped
              dbo.TbVendor.VendorName,
              dbo.TbItem.ItemId,
              dbo.TbItem.ItemPacking,
              dbo.TbItem.ItemQtyPacking,              
FROM        dbo.TbPurchaseLine
        LEFT OUTER JOIN
                      dbo.TbItem ON dbo.TbPurchaseLine.PurLineItemId = dbo.TbItem.ItemId
        LEFT OUTER JOIN   
                      dbo.TbVendor ON dbo.TbPurchaseLine.PurLineVendorId = dbo.TbVendor.VendorId

GROUP BY         dbo.TbPurchaseLine.PurLineItemId,
                dbo.TbPurchaseLine.PurLineItemName,
                    dbo.TbPurchaseLine.PurLineItemUnit,
            dbo.TbVendor.VendorName,
            dbo.TbItem.ItemId,
            dbo.TbItem.ItemPacking,
            dbo.TbItem.ItemQtyPacking,
            dbo.TbPurchaseLine.PurLineDepId,
                    dbo.TbPurchaseLine.PurLineUpdated,
            dbo.TbPurchaseLine.PurCartHeadType,
            dbo.TbPurchaseLine.PurLineQuantity,
            dbo.TbPurchaseLine.PurLineQuantityShipped
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 12:41 #9
OK, så har jeg en anden løsning. Jeg laver en subquery i stedet for GROUP BY


VIEW dbo.QySpGetItemToHis
AS
SELECT DISTINCT
                      TOP 100 PERCENT dbo.TbPurchaseLine.PurLineId,
              dbo.TbPurchaseLine.PurLineItemId,
              dbo.TbPurchaseLine.PurLineItemName,
                      dbo.TbPurchaseLine.PurLineItemUnit,
              dbo.TbPurchaseLine.PurLineDepId,
                      dbo.TbPurchaseLine.PurLineUpdated,
              dbo.TbPurchaseLine.PurCartHeadType,
              dbo.TbPurchaseLine.PurLineQuantity,
              dbo.TbPurchaseLine.PurLineQuantityShipped
              dbo.TbVendor.VendorName,
              dbo.TbItem.ItemId,
              dbo.TbItem.ItemPacking,
              dbo.TbItem.ItemQtyPacking,             
FROM        dbo.TbPurchaseLine
        LEFT OUTER JOIN
                      dbo.TbItem ON dbo.TbPurchaseLine.PurLineItemId = dbo.TbItem.ItemId
        LEFT OUTER JOIN   
                      dbo.TbVendor ON dbo.TbPurchaseLine.PurLineVendorId = dbo.TbVendor.VendorId

WHERE dbo.TbPurchaseLine.PurLineId =
  (SELECT MAX(dbo.TPL2.PurLineId) FROM dbo.TbPurchaseLine TPL2 WHERE TPL2.PurLineItemId = dbo.TbPurchaseLine.PurLineItemId)
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 12:42 #10
Dette virker hvis du for alle kolonner i TbPurchaseLine er tilfreds med at få de data der kommer fra rækken med det højeste PurLineId for pågældende PurLineItemId
Avatar billede bobber Nybegynder
09. februar 2006 - 13:01 #11
Okey hvor er TPL2 defineret henne..
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 13:17 #12
WHERE dbo.TbPurchaseLine.PurLineId =
  (SELECT MAX(dbo.TPL2.PurLineId) FROM dbo.TbPurchaseLine TPL2 WHERE TPL2.PurLineItemId = dbo.TbPurchaseLine.PurLineItemId)

TPL2 er et alias for TbPurchaseLine, der jo nu findes i to forekomster i queryen
Avatar billede bobber Nybegynder
09. februar 2006 - 13:29 #13
okey, men det vil give denne fejl..
The column prefix 'dbo.TPL2' does not match with a table name or alias name used in the query
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 14:01 #14
Åh ja, klart. Det skal være uden dbo

WHERE dbo.TbPurchaseLine.PurLineId =
  (SELECT MAX(TPL2.PurLineId) FROM dbo.TbPurchaseLine TPL2 WHERE TPL2.PurLineItemId = dbo.TbPurchaseLine.PurLineItemId)
Avatar billede bobber Nybegynder
09. februar 2006 - 14:19 #15
Du skal have super mange gange tak det virkede
Avatar billede bobber Nybegynder
09. februar 2006 - 14:21 #16
Hvordan får jeg givet dig points, skal du sende svar
Avatar billede ldanielsen Nybegynder
09. februar 2006 - 14:40 #17
Ja, det er hermed gjort, tak for kampen :o)
Avatar billede bobber Nybegynder
09. februar 2006 - 15:28 #18
selv tak :-)
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