xammil
10.09.2012, 16:10:48
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
10.09.2012, 17:37:27
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
10.09.2012, 19:14:05
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

pozdrawiam Kamil
bpskiba
10.09.2012, 20:16:47
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
11.09.2012, 07:32:19
SELECT *
FROM `artykuly` AS A
LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
WHERE
AP.`opcje_1`=1 AND
AP.`opcje_1`=2 AND
AP.`opcje_1`=3 AND
AP.`opcje_2`=1 AND
AP.`opcje_2`=2 AND
AP.`opcje_2`=3 AND
AP.`opcje_3`=1 AND
AP.`opcje_3`=2 AND
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
11.09.2012, 09:05:08
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ś:
SELECT *
FROM `artykuly` AS A
LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
WHERE
(
AP.`opcje_1`=1 AND
AP.`opcje_1`=2 AND
AP.`opcje_1`=3
) OR (
AP.`opcje_2`=1 AND
AP.`opcje_2`=2 AND
AP.`opcje_2`=3 AND
) OR(
AP.`opcje_3`=1 AND
AP.`opcje_3`=2 AND
AP.`opcje_3`=3 )
xammil
11.09.2012, 09:21:43
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
11.09.2012, 09:31:10
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
11.09.2012, 09: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 ?
redeemer
11.09.2012, 10:22:18
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ś?
SELECT *
FROM `artykuly` AS A
LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
WHERE
(AP.`id_atrybutu` = 10 AND AP.id_wartosci = 100 ... )
OR
(AP.`id_atrybutu` = 20 AND AP.id_wartosci = 200 ...)
OR
(AP.`id_atrybutu` = 30 AND AP.id_wartosci = 300 ...)
Najlepiej wklej strukturę tabel, oraz jakiego wyniku oczekujesz od zapytania.
xammil
11.09.2012, 11:41:02
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
11.09.2012, 14:44:52
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
11.09.2012, 15:02:15
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
11.09.2012, 21:31:46
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
SELECT *
FROM `artykuly` AS A
LEFT JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
GROUP BY A.`id`
HAVING count(AP.`id_artykulu`)>1
maly_swd
12.09.2012, 09:23:23
@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
SELECT *
FROM `artykuly` AS A
JOIN `artykuly_opcje` AS AP ON (A.`id`=AP.`id_artykulu`)
GROUP BY A.`id`
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.