Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: MySql - Zapytanie dla wyszukiwania, wiele wartości jedna kolumna, NIE IN !
Forum PHP.pl > Forum > Bazy danych > MySQL
xammil
Witam, mam problem z zapytaniem w MySql, problem wyglada tak:

Muszę wyszukać w jednej kolumnie różne wartosci np:

...WHERE
`kolumna_1` = 10 AND
`kolumna_1` = 20 AND
`kolumna_1` = 30 AND

kolumna_1 to (INT)

'prawie' idealnie nadaje się IN (10,20,30), z tym ze potrzebuje wyniku gdzie dla kolumny_1 WHERE wlasnie jest takie jak wyzej

zrobilem to zapytanie z LEFT JOIN, z tym ze łączyłem JOIN'em caly czas ta samą tabelę dla kolejnego AND..., to jest raczej mało wydajne (zakladajac że zapytanie może dojść do 30/40 AND na tej samej kolumnie)

Proszę o pomoc, niestety nie mam żadnego pomysłu na to ....

Pozdrawiam Kamil.
alegorn
ależ AND i IN są czymś zupełnie różne...

AND - sprawia ze wyszukujesz rekordy które spełniają wszystkie warunki czyli kolumna_1 musi mieć jednocześnie wartość 10, 20, 30 i ile byś jeszcze tam nie wstawił.... chyba średnio realne.

przemyśl sprawe, bo wydaje mi sie ze w zlym miejscu chcesz cos na sile 'naprawiac'


jesli nie - to poczytaj o uniach, tym mozesz zastąpić IN w sposob podobny do takiego jak chcesz uzyskac....


j.
xammil
dokladnie wiem jak dziala in i and, i tez dobrze wiem ze and'em tego nie zrobie niestety tego przypadku nie da sie inaczej ogarnac, poniewaz to jest jedyna opcja na wpisanie w baze tak roznych danych powiazanych jedynie kluczami...

pytanie brzmi, jak badz czy istnieje jakas funkcja w mysql ktora mi w tym pomoze..., przypadek jest troche beznadziejny ale wierze ze jestescie w stanie mi pomoc wink.gif

pozdrawiam Kamil
bpskiba
Wcale nie jest to beznadziejne. Jest wręcz banalne
Zapewne da się rozwiązać stosując operatory AND oraz OR i nawiasy. Zadałeś jednak pytanie tak, że nic z tego nie rozumiem. Opisz to lepiej
xammil
  1. SELECT *
  2. FROM `artykuly` AS A
  3. LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
  4. WHERE
  5.  
  6. AP.`opcje_1`=1 AND
  7. AP.`opcje_1`=2 AND
  8. AP.`opcje_1`=3 AND
  9.  
  10. AP.`opcje_2`=1 AND
  11. AP.`opcje_2`=2 AND
  12. AP.`opcje_2`=3 AND
  13.  
  14. AP.`opcje_3`=1 AND
  15. AP.`opcje_3`=2 AND
  16. AP.`opcje_3`=3 AND



To jest przykład zapytania (które oczywiscie nie zadziała...).

Więc jeszcze raz:

Potrzebuje pobrać artykuły dla których opcje z 3 kolumn ('opcje_1','opcje_2','opcje_3') nie maja tylko jednej wartosci, dla kazdej kolumny wystepuje 'n' opcji (opcje te nie sa stale i tez dla tego `opcje_X` zostaly stworzone by magazynowac tam duza ilosc danych dla artykulu -> 1 artykul wiele opcji)
bpskiba
Tak na początek:
Razi całkowicie nieprawidłowa budowa bazy. Powinieneś mieć trzy tabele
1 Artykuły (id_artykuły, nazwa itd)
2 Opcje (id_opcje, nazwa itd)
3 artykuły_opcje (id_artykuly_opcje, id_opcje, id_artykuły, nazwa itd)

W Twoim przypadku dodanie opcji skutkuje koniecznością przebudowy zapytań i dodania kolumny w bazie.
Nadal nie jestem pewien czy cię rozumiem. Co to znaczy: opcje z 3 kolumn ('opcje_1','opcje_2','opcje_3') nie maja tylko jednej wartosci
A co powiesz na takie coś:
  1. SELECT *
  2. FROM `artykuly` AS A
  3. LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
  4. WHERE
  5. (
  6. AP.`opcje_1`=1 AND
  7. AP.`opcje_1`=2 AND
  8. AP.`opcje_1`=3
  9. ) OR (
  10. AP.`opcje_2`=1 AND
  11. AP.`opcje_2`=2 AND
  12. AP.`opcje_2`=3 AND
  13. ) OR(
  14. AP.`opcje_3`=1 AND
  15. AP.`opcje_3`=2 AND
  16. AP.`opcje_3`=3 )
xammil
kolumny wygladaja tak

id_atrybutu, id_wartosci, wartosc_specjalna

10, 100, 1000
20, 200, 2000
30, 300, 3000
40, 400, 400

przykladowe wartości

i teraz senk w tym ze zawsze beda tworzone nowe atrybuty z nowymi wartosciami a w tym wyzej trzymam jedyne konfiguracje, fajnie by bylo miec dla kazdego atrybutu kolumne ale to wiarze sie z tym ze za kazdym razem gdy towrze/usuwam atrybut zmieniam baze, to co jest wyzej jest idealnym polaczeniem samych atrybutow z artykulem (w jednej tabeli trzymam wszystkie atrybuty, w drugiej wszystkie wartosci a w trzeciej polaczenie dla artykulu atrybut->wartosc->wartosc_specjalna (czyli id do polaczenia z poprzednimi tabelami) )

zapytanie ma wyciagac konfiguracje gdzie dla artykulu jest wybrany 'ten' 'ten' i 'ten' atrybut z 'takimi' 'takimi' 'takimi' wartosciami czyli 3 atrybuty z konkretnymi wartosciami
np

10, 100, 1000
20, 200, 2000
30, 300, 3000

wszystkie trzy musza byc przypisane do artykulu

i tu jest problem bo sam wiesz AND id_attr=30 ANd id_attr=33 nie ma prawa buty...

wydaje mi sie ze nie ma mozliwosci zrobic tego zapytania w mysql musze wybrac w miare sensownie dane z bazy i przemielic je w php z tym ze tych wynikow moze byc nawet 600*30 ...
maly_swd
To co podajesz w przykladzie to blad logiczny.
AP.`opcje_1`=1 AND AP.`opcje_1`=2 AND

zalozmy ze jestesmy w realnym swiecie i ze opcje_1 = "TO JESTES TY" a teraz 1 i 2 po znaku rownosci to:
1= Warszawa
2=Gdansk;)

Teraz Ty chcesz w jednym czasie byc w Warszawie i Gdansku .. a to jest niemozliwe...

Wiec moze opiszesz to bardziej precyzyjnie
xammil
nie uczcie mnie podstaw..., pytanie bylo proste i dosyc jasno opisane, chodzi o to czy jestem w stanie zrobic to w jedym zapytaniu czy dla kazdych kolejnych wybranych atrybutow musze znowu tworzy zapytanie z zawerzonym kregiem artyulow z poprzedniego zapytania ?
redeemer
Pytanie było niejasne, a tłumaczenie w stylu "zmienna = A AND zmienna = B" w ogóle nie pomaga. W dalszym ciągu nie wiem czy dobrze rozumiem Twój problem, ale może takie coś?
  1. SELECT *
  2. FROM `artykuly` AS A
  3. LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
  4. WHERE
  5.  
  6. (AP.`id_atrybutu` = 10 AND AP.id_wartosci = 100 ... )
  7. OR
  8. (AP.`id_atrybutu` = 20 AND AP.id_wartosci = 200 ...)
  9. OR
  10. (AP.`id_atrybutu` = 30 AND AP.id_wartosci = 300 ...)
Najlepiej wklej strukturę tabel, oraz jakiego wyniku oczekujesz od zapytania.
xammil
nie akutalne juz

aby bylo jasne nie moze wystapic zadne OR

jezeli ktos ma ochote mozemy porozmawiaco tym na PM

rozwiazalem problem po przez 'powielanie' kazdego zapytania z atrybutami, wyszukiwarka dziala w ajax'ie, kazdy atrybut jest zarzadzalny i niestety troche tych zapytan sie tworzy wiec w tym momencie musi to zostac

Dzieki za pomoc pozdrawiam Kamil

ps. jezeli ktos ma chceci tak jak pisalem PM
maly_swd
Cytat(xammil @ 11.09.2012, 10:39:36 ) *
nie uczcie mnie podstaw..., pytanie bylo proste i dosyc jasno opisane, chodzi o to czy jestem w stanie zrobic to w jedym zapytaniu czy dla kazdych kolejnych wybranych atrybutow musze znowu tworzy zapytanie z zawerzonym kregiem artyulow z poprzedniego zapytania ?

Skoro piszesz takie cos ...WHERE
`kolumna_1` = 10 AND
`kolumna_1` = 20 AND
`kolumna_1` = 30 AND


To jednak podstawy sa wymagane...
bpskiba
Gdy wielu forumowiczów pisze o niejasnym opisie problemu, o tym, że to da się rozwiązać jednym zapytaniem, o niezrozumieniu podstaw algebry relacji....
autor wątku powinien to przemyśleć.
sazian
dobra po długiej analizie chyba wiem o co chodzi


wyjaśnienie:
są dwie tabele w relacji 1:n
mają zostać wyświetlone tylko te wyniki z pierwszej tabeli dla których istnieje więcej niż jedna wartość w tabeli drugiej


rozwiązanie - pisane z palca
  1. SELECT *
  2. FROM `artykuly` AS A
  3. LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
  4.  
  5. GROUP BY A.`id`
  6. HAVING count(AP.`id_artykulu`)>1

maly_swd
@Sazian, jesli jest faktycznie tak jak piszesz... to mozna to bez LEFT JOINA, poniewaz jak zrobisz JOINEM to i tak musi byc zlaczenie, a pozniej HAVING>1 czyli tak czy siak powinno byc zlaczenie.
W teorii powinno to szybciej smigac

  1. SELECT *
  2. FROM `artykuly` AS A
  3. JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
  4.  
  5. GROUP BY A.`id`
  6. HAVING count(AP.`id_artykulu`)>1
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.