Permalänk

Sql Group By

Hej!

Läser en första kurs i databasmetodologi och har gjort en databas i MS Access. Har fått i uppgift att visa en rad olika saker med hjälp av SQL-queries och sitter just nu fast på en som jag trodde funkade - men efter att ha matat in lite annan data så visade det sig inte stämma.

Det är en databas för en Livsmedelsbutikskedja. Och jag vill "ta fram information om den största förpackningen inom varje måttenhet". Dvs jag vill veta vilken produkt som har det största måttet för sin måttenhet, som är liter, kg, g etc. T ex Ris 1kg, Cola 2l, Ost, 800g, Saft 80cl.

I min databas har jag bara kg, g, l och cl. Och jag får i resultatet med alla produkter som har talet "1" som mått. T ex har jag både yoghurt och mjölk i 1 litersförpackningar, men det största litermåttet är Cola som är 1,5. Sätter jag något annat till 1 kommer det också med. Min SQL-stats ser ut som följer:

SELECT mått, indelning, namn, storlek FROM Produkttyp, Produktförpackning, Produkt WHERE produkt=benämning AND namn=produkttyp AND storlek IN (SELECT MAX (storlek) FROM Produkttyp, Produktförpackning, Produkt WHERE produkt=benämning AND namn=produkttyp GROUP BY mått);

Jag tror att det är nåt jag har missat med GROUP BY, men borde inte den sortera ut på det sätter jag vill?!

Jag hoppas ni förstår vad jag menar? Fråga om det nåt jag vart oklar med.

Tack!
/Snorkelfarsan

Permalänk
Medlem

Tror du måste ange vilken tabell som en kolumn tillhör så att databasen vet var den ska leta. Så din fråga borde bli nåt i stil med följande:

SELECT Produktförpackning.mått, Produkttyp.indelning, Produkt.namn, Produktförpackning.storlek FROM Produkttyp, Produktförpackning, Produkt WHERE Produkttyp.produkt=Produkt.benämning AND Produkttyp.namn=Produkt.produkttyp AND storlek IN (SELECT MAX (Produktförpackning.storlek) FROM Produkttyp, Produktförpackning, Produkt WHERE Produkttyp.produkt=Produkt.benämning AND Produkttyp.namn=Produkt.produkttyp GROUP BY Produktförpackning.mått);

Nu gissade jag bara vilka kolumner som tillhör vilken tabell men jag hoppas att poängen är tydlig.

Permalänk

varför har du samma enhet flera gånger med med olika prefix? Cl och l, och kg och g är ju samma enheter? De borde väl tillhöra samma kategori.. Ursäkta om jag är snurrig.. hur trött som helst:(

Visa signatur

Asus Striker II Extreme / XFX Geforce GTX 280 / Q9450 @ 3.6GHz/ TRUE Noctua 120/ 4x1GB Corsair TWIN3X2048-1333C9DHX / X25-M G2 80gb Velociraptor / Win 7 Ultimate x64/ Antec P190

MovieDatabase

Permalänk
Medlem

Tror du ska ha GROUP BY utanför parenteserna helt enkelt.

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Problemet är att ni bara plockat ut storlek, trots att det kan finnas både 10kg och 10g och att dessa inte är samma sak. Typ såhär kan man göra istället:

select p.* from Produkt p , (select max(storlek) storlek, mått from Produkt group by mått) x where x.storlek = p.storlek and x.mått = p.mått

För enkelhetens skull antog jag att det i Produkt finns kolumnerna storlek, mått + all annan info du behöver, men det är ju lätt o hämta in den övriga infon. Om jag nu förstod frågan rätt...

Permalänk
Citat:

Ursprungligen inskrivet av Packe
Tror du måste ange vilken tabell som en kolumn tillhör så att databasen vet var den ska leta. Så din fråga borde bli nåt i stil med följande:

SELECT Produktförpackning.mått, Produkttyp.indelning, Produkt.namn, Produktförpackning.storlek FROM Produkttyp, Produktförpackning, Produkt WHERE Produkttyp.produkt=Produkt.benämning AND Produkttyp.namn=Produkt.produkttyp AND storlek IN (SELECT MAX (Produktförpackning.storlek) FROM Produkttyp, Produktförpackning, Produkt WHERE Produkttyp.produkt=Produkt.benämning AND Produkttyp.namn=Produkt.produkttyp GROUP BY Produktförpackning.mått);

Nu gissade jag bara vilka kolumner som tillhör vilken tabell men jag hoppas att poängen är tydlig.

Det behövs inte, eftersom kolumnnamnen är specifika så access vet vad jag menar, annars hade den ju sagt ifrån dessutom.

Citat:

Ursprungligen inskrivet av KurreKula
varför har du samma enhet flera gånger med med olika prefix? Cl och l, och kg och g är ju samma enheter? De borde väl tillhöra samma kategori.. Ursäkta om jag är snurrig.. hur trött som helst:(

Det har jag iofs inte tänkt på, ska kanske ändra. Tänkte att man vill kunna ange typ colaburkar i cl och flaskor i l men det är ju nånting som står på förpackningarna i sig och inte i databasen.

Citat:

Ursprungligen inskrivet av Teknocide
Tror du ska ha GROUP BY utanför parenteserna helt enkelt.

Det gick inte att göra. Fick felmeddelandet: "You tried to execute a query that does not include the specified "indelning" expresson as part of an aggregate function."

Citat:

Ursprungligen inskrivet av vb
Problemet är att ni bara plockat ut storlek, trots att det kan finnas både 10kg och 10g och att dessa inte är samma sak.

Men det verkar inte som om det är problemet, och dessutom har jag ju "gjort" en tabell i den första SELECT-satsen där enheten (dvs g, kg, l, cl) står bredvid respektive produkt och dess storlek. Och sen har jag grupperat efter måtten. Det konstiga är bara att det verkar funka förutom när det finns flera produkter med storleken "1", oavsett om det är l eller kg.

Så här ser resultatet ut just nu, som ni ser finns det flera rader med dem produkter som har 1 som storlek:

Det är ju bara mellanmjölk 1,5l som ska finnas med.

Permalänk
Medlem

problemet är ju att du tar ut storlken och använder den som nyckel... alltså i den inre select får du värderna (1.5, 750, 1, 50) Vilket betyder att den kommer hämta alla som har storlek 1 oavsett vilken måttenhet den har, därav att du får ut coca cola och lättyoughurt också... använd dig av nycklar så ska det lösa sig

EDIT: precis som vb redan påpekat

Permalänk
Medlem

SELECT mått, indelning, namn, storlek FROM Produkttyp, Produktförpackning, Produkt, (SELECT MAX (storlek) max_storlek, max_mått FROM Produkttyp, Produktförpackning, Produkt WHERE produkt=benämning AND namn=produkttyp GROUP BY mått) temptable WHERE produkt=benämning AND namn=produkttyp AND storlek = max_storlek AND mått = max_mått;

Den här borde funka, om du absolut inte vill använda dig av unika nycklar

Permalänk

Ok, då förstår jag! Men vad menar du med att jag tar ut storleken och använder den som nyckel? Och vad menar du med unika nycklar överhuvudtaget? Jag har skrivit frågor i SQL i några dagar och haft ett par föreläsningar så jag är riktigt färsk när det kommer till det här - förlåt för alla "korkade" frågor!

Jag har nog inget att skriva SQL satsen på ett annat sätt så länge jag förstår vad det är jag har gjort.

tack!

EDIT: Jag försökte köra SQL-satsen som du postade men Access klagar på att: "Missing operator in query expression 'MAX (storlek) max_storlek'". Vad innebär det?

Och vad gör "temptable"?

Permalänk
Medlem

ok, har aldrig jobbat mot access så det är antagligen någon annan syntax än jag är van vid, men jag skulle tippa att det saknas AS då... har lagt till det nedanför. Det jag gör är att jag låter en sql sats vara en egen tabell (förenklat) och då namnger jag den, jag namngav den temptable.

SELECT mått, indelning, namn, storlek FROM Produkttyp, Produktförpackning, Produkt, (SELECT MAX (storlek) AS max_storlek, mått AS max_mått FROM Produkttyp, Produktförpackning, Produkt WHERE produkt=benämning AND namn=produkttyp GROUP BY mått) AS temptable WHERE produkt=benämning AND namn=produkttyp AND storlek = max_storlek AND mått = max_mått;

Generellt sätt om man ska jobba enligt 3NF så ska man bryta ut alla värden i tabell som kan förekomma flera gånger till en egen tabell. Ditt mått är ett klockrent exempel.

såhär skulle jag göra...

Först en måttabell
[code]
ID | Namn
----------------------------
1 | Kg
2 | g
3 | cl
----------------------------
[code]

sen anger du en referens till rätt nyckel (ID) istället.

Det betyder att ditt fält "mått" istället hänvisar till 1 i mått tabellen för Kg istället för att du skriver Kg där.

Det finns många fördelar varför man ska göra såhär, jag orkar inte gå in på det, men det är någonting som din lärare bör ta upp...

jag kanske rörde till det ännumer för dig nu, om jag gjorde det så ignorera det jag skrev tills din lärare tar upp det på en föreläsning. Det är lättare att förklara med lite mer tid och inte via ett forum

Permalänk
Citat:

Ursprungligen inskrivet av thrawn
ok, har aldrig jobbat mot access så det är antagligen någon annan syntax än jag är van vid, men jag skulle tippa att det saknas AS då... har lagt till det nedanför. Det jag gör är att jag låter en sql sats vara en egen tabell (förenklat) och då namnger jag den, jag namngav den temptable.

Då är jag med, jag har blivit lärd att använda AS eftersom access använder det. Men jag misstänkte att du gjorde nåt liknande.

Citat:

Generellt sätt om man ska jobba enligt 3NF så ska man bryta ut alla värden i tabell som kan förekomma flera gånger till en egen tabell. Ditt mått är ett klockrent exempel.

såhär skulle jag göra...

Först en måttabell
[code]
ID | Namn
----------------------------
1 | Kg
2 | g
3 | cl
----------------------------
[code]

sen anger du en referens till rätt nyckel (ID) istället.

Det betyder att ditt fält "mått" istället hänvisar till 1 i mått tabellen för Kg istället för att du skriver Kg där.

Det finns många fördelar varför man ska göra såhär, jag orkar inte gå in på det, men det är någonting som din lärare bör ta upp...

jag kanske rörde till det ännumer för dig nu, om jag gjorde det så ignorera det jag skrev tills din lärare tar upp det på en föreläsning. Det är lättare att förklara med lite mer tid och inte via ett forum

Min modell är i princip helt i 3NF och faktum är att jag redan ha en tabell för alla mått, dock utan "ID" som surrogatnyckel, utan primärnyckeln är helt enkelt benämningen i sig, dvs kg, l osv. Jag valde dock att använda den refererade främmande nyckeln i tabellen Produkt eftersom jag tänkte att alla dom relevanta värdena redan står där och dessutom är kopplade till en viss produktindelning som i sin tur är kopplad till Produktförpackning där jag anger storlek. Hur ska jag annars kunna veta vilket typ av mått(kg,l) som en produkt har?

Permalänk

Nu har jag fixat det, tack för hjälpen!!!!

SELECT Mått.enhet, indelning, namn, storlek FROM Produkttyp, Produktförpackning, Produkt, Mått, (SELECT MAX (storlek) AS max_storlek, enhet FROM Produkttyp, Produktförpackning, Produkt, Mått WHERE produkt=benämning AND namn=produkttyp AND Mått.enhet=Produkt.mått GROUP BY enhet) AS X WHERE produkt=benämning AND namn=produkttyp AND Mått.enhet=Produkt.mått AND X.enhet=Mått.enhet AND max_storlek=storlek;

enhet är samma sak som mått. Alltså kolumnen i tabellen Mått och mått är kolumnen i tabellen Produkt.

Permalänk
Medlem

Men varför använder du inte samma namn på kolumner som innehåller samma data? Så att t.ex tabellen heter mått i både Mått- och Produkt-tabellen. Blir ju mycket enklare att hålla reda på vad det är för data som finns i den tabellen och hur olika tabeller kan hänga ihop.

Permalänk

hmm, kanske det. Men då blir det också lättare konflikt där programmet inte vet vilket mått det är jag syftar på. Det är iaf inget problem så jag låter det vara så for now. Om man dessutom ser själva modellen framför sig med alla relationer är det mycket enklare att förstå så klart