Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Pomoc w skonstruowaniu zapytania
Forum PHP.pl > Forum > Bazy danych > MySQL
_chris_
Witam wszystkich
Dzisiaj stanąłem przed wyzwaniem, którego nie mogę ni jak pokonać. Do dalszej rozbudowy pewnej aplikacji muszę dodać jedną funkcjonalność. Ogólnie jest tak, że program teraz dobiera ilości produktów żywieniowych wg jakiś tam kryteriów. Tak czy inaczej wypluwa mi idProduktu i ilosc. Baza przedstawia się mniej więcej tak (ująłem tylko istotne właściwości) :

produkty:
idProduktu | nazwa

potrawy:
idPotrway | opis

skladnikiPotraw:
idPotrawy | idProduktu | ilosc

Program wypluwa na przykład: produkty - ilości (id - gram) : 1 - 20, 2 - 30, 3 - 40

Jak teraz mógłbym pobrać wszystkie potrawy spełniające wymagania, że wymagają do przygotowania tylko wybranych produktów, wybrana ilość jest wystarczająca do przygotowania potrawy. Mało tego, potrzebuję jeszcze wybrać takich potraw 21 (3 dziennie x 7 dni).

Z góry dziękuję za jakiekolwiek sugestie, bo stoję w martwym punkcie, a czas goni.
bpskiba
  1. SELECT pr.nazwa,sp.ilosc,pt.opis
  2. FROM produkty pr
  3. JOIN skladnikiPotraw sp USING(id_produktu)
  4. JOIN potrawy pt USING(idPotrawy)
  5. WHERE
  6. ...............
trafas
Mi się wydaje że jest to bardziej złożony problem.

Z tego co zrozumiałem, to kolega chce podawać do zapytania produkty ( id produktów ) i w wyniku mają być zwrócone wszystkie potrawy, które zawierają tylko i wyłącznie podane produkty.

Zakładając takie dane wejściowe:

  1.  
  2. CREATE TABLE produkty
  3. (
  4. idProduktu int,
  5. nazwa varchar(255)
  6. );
  7.  
  8. CREATE TABLE potrawy
  9. (
  10. idPotrawy int,
  11. opis varchar(255)
  12. );
  13.  
  14. CREATE TABLE skladnikiPotraw
  15. (
  16. idPotrawy int,
  17. idProduktu int,
  18. ilosc int
  19. );
  20.  
  21. INSERT INTO produkty
  22. SELECT 1, 'prod 1'
  23. UNION
  24. SELECT 2, 'prod 2'
  25. UNION
  26. SELECT 3, 'prod 3'
  27. UNION
  28. SELECT 4, 'prod 4'
  29. UNION
  30. SELECT 5, 'prod 5'
  31. UNION
  32. SELECT 6, 'prod 6'
  33.  
  34.  
  35. INSERT INTO potrawy
  36. SELECT 1, 'potr 1'
  37. UNION
  38. SELECT 2, 'potr 2'
  39. UNION
  40. SELECT 3, 'potr 3'
  41. UNION
  42. SELECT 4, 'potr 4'
  43. UNION
  44. SELECT 5, 'potr 5'
  45. UNION
  46. SELECT 6, 'potr 6'
  47.  
  48.  
  49.  
  50. INSERT INTO skladnikiPotraw
  51. SELECT 1, 1, 12
  52. UNION
  53. SELECT 1, 2, 12
  54. UNION
  55. SELECT 1, 3, 12
  56. UNION
  57. SELECT 2, 1, 45
  58. UNION
  59. SELECT 2, 2, 10
  60. UNION
  61. SELECT 2, 3, 5
  62. UNION
  63. SELECT 2, 4, 18
  64. UNION
  65. SELECT 3, 5, 3
  66. UNION
  67. SELECT 3, 6, 7
  68. UNION
  69. SELECT 3, 1, 4
  70. UNION
  71. SELECT 6, 1, 5
  72. UNION
  73. SELECT 6, 2, 1
  74.  


i taki warunek na wymagane produkty ( Jako że bawię się w konsoli, to zrobiłem sobie tabelę z id wymaganych produktów. Docelowo id mogą być przekazywane jako tablica w parametrze funkcji):

  1.  
  2. CREATE TABLE produkty_wymagane
  3. (
  4. id_produktu int
  5. )
  6.  
  7. INSERT INTO produkty_wymagane
  8. SELECT 1
  9. UNION
  10. SELECT 2
  11.  


to wynikiem powinna być tylko i wyłącznie potrawa ID 6


Wykombinowałem sobie takie zapytanie:

  1.  
  2. SELECT *
  3. FROM potrawy potr
  4. JOIN skladnikiPotraw sklad ON sklad.idPotrawy=potr.idPotrawy
  5. JOIN (
  6. SELECT sp.idPotrawy, count(*) AS iloscProduktow
  7. FROM skladnikiPotraw sp
  8. WHERE
  9. sp.idProduktu IN(SELECT * FROM produkty_wymagane) -- ograniczenie na id produktów
  10. AND sp.idPotrawy NOT IN(
  11. SELECT idPotrawy
  12. FROM skladnikiPotraw
  13. WHERE
  14. idPotrawy=sp.idPotrawy
  15. AND idProduktu NOT IN(SELECT * FROM produkty_wymagane)) -- ograniczenie na ilość produktów w potrawach
  16. GROUP BY sp.idPotrawy
  17. HAVING count(*) >= (SELECT count(*) FROM produkty_wymagane)
  18. ) AS skladProd
  19. ON skladProd.idPotrawy=potr.idPotrawy
  20. JOIN produkty prod ON prod.idProduktu=sklad.idProduktu
  21.  



Czy o takie coś koledze chodziło questionmark.gif?


Jeżeli tak, to losowanie potraw 3 x 21 nie powinno już być problemem.
_chris_
Zapytanie jest genialne, robi robotę, ale jest jedno ale:) w tej tabeli produkty wymagane musi być drugie pole ilosc i ono też musi być brane pod uwagę. Dodatkowo zastanawiałem się nad wzięcie pod uwagę jakiejś odchyłki że jak potrawa wymaga 100g czegoś, a u mnie bedzie 98g no to tak czy inaczej możemy zrobić taką potrawę.

Dałbyś radę dołożyć jeszcze warunek ograniczający na ilość produktu w g ?
trafas
Dane wejściowe:

  1. CREATE TABLE produkty
  2. (
  3. idProduktu int,
  4. nazwa varchar(255)
  5. );
  6.  
  7. CREATE TABLE potrawy
  8. (
  9. idPotrawy int,
  10. opis varchar(255)
  11. );
  12.  
  13. CREATE TABLE skladnikiPotraw
  14. (
  15. idPotrawy int,
  16. idProduktu int,
  17. ilosc int
  18. );
  19.  
  20. INSERT INTO produkty
  21. SELECT 1, 'prod 1'
  22. UNION
  23. SELECT 2, 'prod 2'
  24. UNION
  25. SELECT 3, 'prod 3'
  26. UNION
  27. SELECT 4, 'prod 4'
  28. UNION
  29. SELECT 5, 'prod 5'
  30. UNION
  31. SELECT 6, 'prod 6'
  32.  
  33.  
  34. INSERT INTO potrawy
  35. SELECT 1, 'potr 1'
  36. UNION
  37. SELECT 2, 'potr 2'
  38. UNION
  39. SELECT 3, 'potr 3'
  40. UNION
  41. SELECT 4, 'potr 4'
  42. UNION
  43. SELECT 5, 'potr 5'
  44. UNION
  45. SELECT 6, 'potr 6'
  46.  
  47.  
  48.  
  49. INSERT INTO skladnikiPotraw
  50. SELECT 1, 1, 12
  51. UNION
  52. SELECT 1, 2, 12
  53. UNION
  54. SELECT 1, 3, 12
  55. UNION
  56. SELECT 2, 1, 45
  57. UNION
  58. SELECT 2, 2, 10
  59. UNION
  60. SELECT 2, 3, 5
  61. UNION
  62. SELECT 2, 4, 18
  63. UNION
  64. SELECT 3, 5, 3
  65. UNION
  66. SELECT 3, 6, 7
  67. UNION
  68. SELECT 3, 1, 4
  69. UNION
  70. SELECT 5, 1, 100
  71. UNION
  72. SELECT 5, 2, 50
  73. UNION
  74. SELECT 6, 1, 5
  75. UNION
  76. SELECT 6, 2, 1



Zakres danych:

  1.  
  2. CREATE TABLE produkty_wymagane
  3. (
  4. id_produktu int,
  5. wymagana_ilosc int
  6. )
  7.  
  8.  
  9. INSERT INTO produkty_wymagane
  10. SELECT 1, 98
  11. UNION
  12. SELECT 2, 45
  13.  



Wynik:

  1.  
  2. SELECT *
  3. FROM potrawy potr
  4. JOIN skladnikiPotraw sklad ON sklad.idPotrawy=potr.idPotrawy
  5. JOIN (
  6. SELECT sp.idPotrawy, count(*) AS iloscProduktow
  7. FROM skladnikiPotraw sp
  8. JOIN produkty_wymagane pw ON pw.id_produktu=sp.idProduktu -- produkty wymagane
  9. WHERE
  10. sp.ilosc BETWEEN pw.wymagana_ilosc - 10 AND pw.wymagana_ilosc + 10 -- wymagana ilość z zakresem +/- 10g
  11. AND sp.idPotrawy NOT IN(
  12. SELECT DISTINCT idPotrawy
  13. FROM skladnikiPotraw
  14. WHERE
  15. idPotrawy=sp.idPotrawy
  16. AND idProduktu NOT IN(SELECT id_produktu FROM produkty_wymagane)) -- ograniczenie na produkty spoza wymaganych idProduktu
  17. GROUP BY sp.idPotrawy
  18. HAVING count(*) = (SELECT count(*) FROM produkty_wymagane) ------ warunek na ilość podanych produktów
  19. ) AS skladProd
  20. ON skladProd.idPotrawy=potr.idPotrawy
  21. JOIN produkty prod ON prod.idProduktu=sklad.idProduktu
  22.  
  23.  
_chris_
Nieważne... Przydżumiła mnie coś ta dzisiejsza pogoda. Działa jak należy smile.gif Dzięki wielkie!
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.