Skocz do zawartości

Polecane posty

W rozwiązaniu @maniack dodajesz kolejny OR i zwiększasz count do 3:

SELECT idprodukt
FROM table
WHERE (nazwa_cechy='powierzchnia' AND wartosc=1) OR (nazwa_cechy='długość' AND wartosc=350) OR (nazwa_cechy='kolor' AND wartosc='red')
GROUP BY idprodukt
HAVING COUNT(*)=3

Ogólnie w tym zapytaniu wyszukujmy produkty które spełniają któryś z warunków (może jeden, może dwa, może trzy), a potem countem bierzemy tylko te produkty które występują dokładnie 3 razy. Jeśli warunków byłoby 4 to wtedy dajemy count=4, itd

 

Tutaj mała uwaga: baza musi być "czysta". Przy założeniu że wszystkie pola są kluczem głównym to mamy to niejako wymuszone. Ale jeśli wartości mogą się powtarzać i np. produkt będzie miał dwa razy kolor=red to zapytanie przestanie działać. Mało prawdopodobne, żeby się to zdarzyło, ale różne rzeczy w życiu widziałem.

 

Z podzapytaniem dodajesz jeden IN:

SELECT idprodukt
FROM table
WHERE idprodukt IN (SELECT idprodukt FROM table WHERE nazwa_cechy='powierzchnia' AND wartość=1 )
AND idprodukt IN (SELECT idprodukt FROM table WHERE nazwa_cechy='kolor' AND wartość='red' )
AND nazwa_cechy='długość' AND wartość=350;
Edytowano przez nnd_newbie (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Nie mam zielonego pojęcia czemu chłopakowi nie powiecie, że jego tabela łamie prawie wszystkie postaci normalne i absolutnie nie ma prawa bytu w jakiejkolwiek aplikacji bo jest spieprzona fundamentalnie.

 

Produkt w jednej tabeli z ID, cechy w innej tabeli z ID, i w trzeciej tabeli połączenie produktu, cechy i wartości tej cechy. Zapytanie można wtedy po ludzku zrobić na kilka dobrych sposobów i nie trzeba robić takich machlojek jak te wyżej. Jednocześnie baza z definicji pilnuje tego, żebyś @nnd_newbie nie widział swoich "cudów", które mogą się pojawić jedynie w takich spieprzonych fundamentalnie tabelach.

 

Nawet nie chcę sobie wyobrażać coś takiego działającego na produkcji.

Edytowano przez Archi (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Może nie może poprawić. Sądzę, że sam jej sobie nie wymyślił, tylko dostał w spadku. W biznesie funkcjonują niestety bazy danych spieprzone fundamentalnie. Polecam przegląd baz danych np. programów księgowych, szczególnie w starszych wersjach. Niestety pracuje się na tym co się dostaje.

 

Poza tym akurat wertykalny sposób organizacji nie należy do rzadkości i występuje kiedy nie znamy liczby parametrów którymi będziemy opisywać produkty. Zerknij sobie do bazy danych jakiegolwiek sklepu internetowego gdzie produktom możemy nadawać cechy czy tagi (np. Prestashop). Wtedy dostaniesz tabelę uporządkowaną w sposób wertykalny.

 

Jasne można posprzątać, żeby nie było tak brzydko jak tu, ale problemy z wyszukaniem pozostaną podobne.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Nie mam zielonego pojęcia czemu chłopakowi nie powiecie, że jego tabela łamie prawie wszystkie postaci normalne i absolutnie nie ma prawa bytu w jakiejkolwiek aplikacji bo jest spieprzona fundamentalnie.

 

Produkt w jednej tabeli z ID, cechy w innej tabeli z ID, i w trzeciej tabeli połączenie produktu, cechy i wartości tej cechy. Zapytanie można wtedy po ludzku zrobić na kilka dobrych sposobów i nie trzeba robić takich machlojek jak te wyżej. Jednocześnie baza z definicji pilnuje tego, żebyś @nnd_newbie nie widział swoich "cudów", które mogą się pojawić jedynie w takich spieprzonych fundamentalnie tabelach.

 

Nawet nie chcę sobie wyobrażać coś takiego działającego na produkcji.

 

Niestety w procesie denormalizacji czasami takie tabele powstają. Tylko trzeba zachować zdrowy rozsądek.

 

 

@piotrszmigin:

Co do pytania autora, tutaj zapytanie pivot dla tabeli (pisane z palca więc może nie zadziałać jak coś pisz będziemy poprawiać):

SELECT
	ID,
	SUM(IF(`nazwa cechy` = 'powierzchnia', wartość, NULL)) AS powierzchnia,
	SUM(IF(`nazwa cechy` = 'długość', wartość, NULL)) AS długość,
	SUM(IF(`nazwa cechy` = 'kolor', wartość, NULL)) AS kolor
FROM products GROUP BY ID;

Przykład jak znaleźć produkty z interesującymi nas parametrami:

SELECT *
FROM (
	SELECT
		ID,
		SUM(IF(`nazwa cechy` = 'powierzchnia', wartość, NULL)) AS powierzchnia,
		SUM(IF(`nazwa cechy` = 'długość', wartość, NULL)) AS długość,
		SUM(IF(`nazwa cechy` = 'kolor', wartość, NULL)) AS kolor
	FROM products GROUP BY ID
) WHERE powierzchnia > 50 AND długość = 250;

Spokojnie możesz dodać kolejny warunek i ograniczyć do wyświetlania tylko i wyłącznie samego ID (w drugim zapytaniu).

Jeśli chcesz brać pod uwagę więcej parametrów możesz je dodać analogicznie w pierwszym zapytaniu które jest pivotem (obraca tabelę), jak może zauważyłeś w drugim zapytaniu jest wykorzystywana właśnie table którą zwraca pierwsze zapytanie, inaczej mówiąc pierwsze zapytanie jest użyte w drugim jako podzapytanie. Jeśli więc chcesz dodać kolejną kolumnę do zapytania pivot i warunek w klauzuli where.

Edytowano przez Fizyda (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Jeśli zamiast nazwy cechy wstawi id cechy z innej tabeli, to będzie miał dokładnie to samo co proponujesz. Więc na jakie inne "kilka dobrych sposobów" można będzie to obsłużyć? :)

 

Sam fakt, że klucz będzie na id produkty i id cechy uniemożliwi Ci fuckup wspomniany wyżej, w którym masz ten sam produkt z kolorem czerwony i zielony. Z kolei to przełoży się na napisanie SQLki, która będzie działać w każdej sytuacji, a nie jak twoja przy założeniu konkretnych danych w konkretnych wierszach i kolumnach.

 

Jeśli nadal nie widzisz problemu to nie mamy o czym gadać. INSERT rozwalający całą aplikację nawet nie jest śmieszny - jest tragiczny.

Edytowano przez Archi (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

 

Sam fakt, że klucz będzie na id produkty i id cechy uniemożliwi Ci fuckup wspomniany wyżej.

 

Jaki fuckup? Wprowadzenie produktu z podwojonym atrybutem to nie "rozwalanie bazy danych". To drobna niedogodność której można zresztą przeciwdziałać na poziomie aplikacji czy zakładając klucz UNIQUE.

 

Poza tym idcechy w kluczu głównym to może być za duże ograniczenie. Możemy chcieć, żeby produkt miał więcej wartości np. dla produktu o biało-czerwonym kolorze.

 

Możemy to zrobić przez mnożenie wartości: "biały, czerwony, biało/czerwony", albo przez rozbijanie na poszczególne atrybuty: Kolor biały:tak, Kolor czerwony: tak. Albo przez umożliwienie nadawania kilku wartości tego samego atrybutu.

 

I to ostatnie rozwiązanie jest powszechne, eleganckie (z punktu widzenia użytkownika) i umożliwia ładne filtrowanie. Kolor to tylko przykład. Jest wiele takich atrybutów np. "Typ zasilania" z wartościami "230V", "12V" czy różnego typu technologie sieciowe np. prędkość sieci, obsługiwane protokoły routowania.

 

Za szybko się zapieniasz, za szybko chcesz nakładać ograniczenia. Dziwi mnie, że nie spotkałeś się jeszcze z takimi bazami.

 

Poza tym załóżmy, że baza jest taka jak chcesz. Kluczem głównym jest (idprodukt, idcechy). Pochwalisz się jakie to "zapytanie można wtedy po ludzku zrobić na kilka dobrych sposobów i nie trzeba robić takich machlojek jak te wyżej"?

Edytowano przez nnd_newbie (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się


×