Avatar billede sbjerre Nybegynder
20. februar 2003 - 08:49 Der er 7 kommentarer og
2 løsninger

Hjælp til SQL Query!

Hej

Jeg har følgende tabeller i en database

foodprices:
-id      (primærnøgle)
-price
-fromdate
-foodid  (fremmednøgle til table foods)

foods
-id
-name

foodorders
-id
-foodid
-number
-bookingid


bookings
-id
-med mere!


SELECT
foodprices.foodprices_price AS FoodPrice,
foods.food_name AS FoodName,
foodorders.foodorder_pcs AS FoodPcs
FROM
foodorders
INNER JOIN
bookings ON foodorders.booking_id = bookings.booking_id INNER JOIN
foods ON foodorders.food_id = foods.food_id
INNER JOIN
foodprices ON foodprices.food_id = foods.food_id
WHERE (foodorders.booking_id = 9999)
ORDER BY foodprices.foodprices_fromdate


Her er så problemet:

madvare kan have flere priser, der hver især dækker forskellige tidsrum. Når en vare får en ny pris indsættes en ny række i tabellen 'foodprices' som så er den nye foodorders skal bruge

Udfra et booking_id skal det være muligt at udtrække de vareliner der måtte være med antallet af bestilte vare samt den nyeste pris, dvs. hvor foodprices_fromdate er størst!

Derfor skal jeg kun have udtrukket een vareline pr bestilt vare og ikke som resultatet bliver af ovenstående SQL query hvor jeg får ligeså mange vareliner som der er priser for den enkelte vare.

Hvis jeg f.eks har to vare:
vareA
vareB

hvor vareA har priserne:
10
12
15 (nyeste pris)
og vareB har prisen
25
og en bestilling har bestilt 5 stk af hver vare giver den viste SQL query resultatet:

price:    foodname:          foodno (antal):
10          vareA            5
12          vareA            5
15          vareA            5
25          vareB            5


hvor det skulle lyde (det ønskede udtræk)

price:    foodname:          foodno (antal):
15          vareA            5
25          vareB            5


Dvs. kun en linie for den nyeste varepris


Nogen der ved hvad der skal rettes i den viste SQL Query for at det ønskede resultat returneres??

skriv gerne hvis der ønskes flere informationer!

vh sbjerre
Avatar billede cooljay2000 Nybegynder
20. februar 2003 - 08:57 #1
hvad med:
SELECT
max(foodprices.foodid),
foodprices.foodprices_price AS FoodPrice,
foods.food_name AS FoodName,
foodorders.foodorder_pcs AS FoodPcs
FROM
foodorders
INNER JOIN
bookings ON foodorders.booking_id = bookings.booking_id INNER JOIN
foods ON foodorders.food_id = foods.food_id
INNER JOIN
foodprices ON foodprices.food_id = foods.food_id
WHERE (foodorders.booking_id = 9999)
group by
foodprices.foodprices_price AS FoodPrice,
foods.food_name AS FoodName,
foodorders.foodorder_pcs AS FoodPcs
ORDER BY foodprices.foodprices_fromdate

Det er muligt at syntax ikke er 100% korrekt, men ideen er at vælge den 'foodprice' med det højeste id. Og med 'group by' så får du det pr. vare.
Avatar billede sbjerre Nybegynder
20. februar 2003 - 09:58 #2
Ideen er nok god nok,men det fungerer ikke helt efter hensigten.
Den udtrækker stadig et antal rækker svarende til varer x priser

Det virker som om at max() ikke rigtigt kommer igennem.

Jeg har prøvet med følgende hvor der udtrækkes efter højeste fromdate:

SELECT MAX(foodprices.foodprices_fromdate) AS FromDate, foodprices.foodprices_price AS FoodPrice,
foods.food_name AS FoodName,
foodorders.foodorder_pcs AS FoodPcs
FROM foodorders
INNER JOIN bookings ON foodorders.booking_id = bookings.booking_id
INNER JOIN foods ON foodorders.food_id = foods.food_id
INNER JOIN foodprices ON foodprices.food_id = foods.food_id
WHERE    (foodorders.booking_id = 9999)
GROUP BY foodprices.foodprices_price, foods.food_name, foodorders.foodorder_pcs


hvilket giver samme resultat som før...
Avatar billede sbjerre Nybegynder
20. februar 2003 - 11:13 #3
Man kan f.eks. gøre således, hvilket dog desværre kun returnere den første vareline:

SELECT DISTINCT foods.food_name, foodprices.foodprices_price, foodorders.foodorder_pcs
FROM foodprices
INNER JOIN foods ON foodprices.food_id = foods.food_id
INNER JOIN foodorders ON foodorders.food_id = foods.food_id
INNER JOIN bookings ON bookings.booking_id = foodorders.booking_id
WHERE   
(foodprices.foodprices_fromdate =
  (SELECT MAX(foodprices_fromdate) AS Expr1 FROM foodprices
    WHERE (food_id = SOME
        (SELECT foodorders.food_id                                                          FROM foodorders WHERE foodorders.booking_id = 71)))) AND (bookings.booking_id = 71)
Avatar billede cooljay2000 Nybegynder
20. februar 2003 - 14:04 #4
SELECT
max(foodprices.foodid),
foodprices.foodprices_price AS FoodPrice,
foods.food_name AS FoodName,
foodorders.foodorder_pcs AS FoodPcs
FROM
foodorders
INNER JOIN
bookings ON foodorders.booking_id = bookings.booking_id INNER JOIN
foods ON foodorders.food_id = foods.food_id
INNER JOIN
foodprices ON foodprices.food_id = foods.food_id
WHERE (foodorders.booking_id = 9999)
group by
foodprices.foodprices_price,
foods.food_name,
foodorders.foodorder_pcs
ORDER BY foodprices.foodprices_fromdate
burde gøre jobbet - bemærk jeg har fjernet 'AS ....' under 'Group by'!
Avatar billede cooljay2000 Nybegynder
20. februar 2003 - 14:07 #5
det skal være max(foodprices.id) og ikke max(foodprices.foodid) - bekalger!
Avatar billede arnvig Nybegynder
20. februar 2003 - 15:05 #6
Duer ikke, cooljay, hvis den nyeste pris er lavere end den foregående !
Avatar billede arnvig Nybegynder
20. februar 2003 - 15:06 #7
Du skal bruge datoen til at finde den nyeste pris.
Avatar billede cooljay2000 Nybegynder
20. februar 2003 - 15:33 #8
Hvis du vil hænge dig i petitesser - så gør det ;-)

..men så burde max(foodprices.fromdate) også virke!

I øvrigt så vil max(foodprices.fromdate) og max(foodprices.id) i dit tilfælde give det samme med følgende forudsætninger:
1. Man bruger autoincrement på foodprices.id
2. Man ikke opretter en foodprices der har en ældre fromdate end en af de foregående foodprices med samme foodid.

Og med din datamodel giver det ikke mening at oprette en foodprices der har en ældre fromdate end en af de foregående foodprices med samme foodid.
Hvis du vil have en sådan fleksibilitet så bør du angive en periode på dine foodprices og sikre at der ikke er overlap på dine perioder!
Avatar billede sbjerre Nybegynder
21. februar 2003 - 10:10 #9
Så fandt jeg ud af det, med lidt hjælp fra cooljay2000 så vi deler poitene makker! For ikke at få flere rækker returneret, skulle jeg bruge limit X,X hvilket iøvrigt ikke eksistere i MS SQL, så i stedet brugte jeg SET ROWCOUNT.

Det gav følgende resultat der virker !!

SELECT
foods.food_id AS FoodID,
foods.food_name AS FoodName,
MAX(foodprices.foodprices_fromdate) AS FromDate,
foods.food_available AS FoodAvailable,
foodprices.foodprices_price AS FoodPrice
FROM foods
INNER JOIN foodrelationship ON foods.food_id = foodrelationship.food_id
INNER JOIN foodprices ON foodprices.food_id = foods.food_id
WHERE (foods.food_id = 9999)
GROUP BY foods.food_id, foods.food_name, foodprices.foodprices_price,
foods.food_available
ORDER BY foodprices.foodprices_price DESC
SET ROWCOUNT 1

Thats it, men så blev jeg også meget klogere på brugen af Group BY og SET ROWCOUNT :O)
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

IT-JOB