Skocz do zawartości


 

Zdjęcie

zapytanie sql

zapytanie sql

  • Proszę się zalogować aby odpowiedzieć
33 odpowiedzi na ten temat

zapytanie sql

#21 zbenek12345

zbenek12345

    Często na forum

  • Użytkownicy
  • 55 postów

Napisany 21 maj 2017 - 09:51

Zrozumiałem. To jest dobre rozwiązanie do pierwszego postu od newbie - SELECT idprodukt
FROM table
WHERE idprodukt IN (SELECT idprodukt FROM table WHERE nazwa_cechy='powierzchnia' AND wartość=1 )
AND nazwa_cechy='długość' AND wartość=350;
? :)
  • 0

#22 maniack

maniack

    Weteran WHT

  • WHT+
  • PipPipPipPipPipPipPipPip
  • 667 postów
  • Skąd:Bielsko-Biała
  • Firma:netBOMB

Napisany 21 maj 2017 - 11:49

To jest poprawne rozwiązanie, choć przy większych zbiorach danych może nie być najwydajniejsze.

Chyba najlepsze rozwiązanie zaproponował @Rafiki, choć zapomniał o najważniejszej rzeczy, czyli o spełnieniu wszystkich warunków równocześnie:
SELECT idprodukt
FROM table
WHERE (nazwa_cechy='powierzchnia' AND wartosc=1) OR (nazwa_cechy='długość' AND wartosc=350)
GROUP BY idprodukt
HAVING COUNT(*)=2

  • 0

#23 zbenek12345

zbenek12345

    Często na forum

  • Użytkownicy
  • 55 postów

Napisany 21 maj 2017 - 20:23

Elegancko, propsuje. Zapytania wydajne są bardzo ważne. Chcąc podnieść umiejętności w tworzeniu zapytań najlepiej trenować, trenować aż do opanowania? Mam jeszcze pytanie na marginesie. Jakie zapytania są najbardziej przydatne przy różnego rodzaju zbiorach? Pytanie może być nieco niezrozumiałe, ale mam nadzieje iż wiecie o co mi chodzi :)


  • 0

#24 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Użytkownicy
  • 7 postów

Napisany 22 maj 2017 - 11:15

ok a gdy dodamy jeszcze jeden parametr np kolor = red to jak wtedy taki zapytanie będzie wyglądać. mam na mysli zapytanie które pan pierwotnie napisał na górze ... dzięki
  • 0

#25 Kamikadze

Kamikadze

    Poziomka

  • Firma Bronze
  • PipPipPipPipPipPipPipPip
  • 5864 postów
  • Skąd:Sulejówek
  • Firma:własna
  • Imię:Emil
  • Nazwisko:Marszalec

Napisany 22 maj 2017 - 12:06

Dopsiujesz do WHERE AND kolor=red według schematu.


  • 0

Skonfiguruj.pl - Skonfiguruj swój serwer!

SerwerStatus.pl - Darmowe monitorowanie Twoich serwerów!

GameStatus.pl - Darmowe monitorowanie serwerów gier!

imgURL.pl - Darmowy hosting obrazków!


#26 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Użytkownicy
  • 7 postów

Napisany 22 maj 2017 - 13:07

pytanie czy na pewno bo tam mamy pod zapytanie które nam wydobywa rekordy a dopiero drugim zawezamy wyniki
  • 0

#27 nnd_newbie

nnd_newbie

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 139 postów

Napisany 22 maj 2017 - 14:11

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;

Edytowany przez nnd_newbie, 22 maj 2017 - 14:22.

  • 0

#28 Archi

Archi

    Wyznawca OVH

  • WHT+
  • PipPipPipPipPipPipPipPip
  • 2803 postów
  • Skąd:Warszawa
  • Imię:Łukasz

Napisany 22 maj 2017 - 14:40

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.


Edytowany przez Archi, 22 maj 2017 - 14:44.

  • 0

#29 nnd_newbie

nnd_newbie

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 139 postów

Napisany 22 maj 2017 - 15:06

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.


  • 0

#30 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 488 postów

Napisany 22 maj 2017 - 15:06

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.


Edytowany przez Fizyda, 22 maj 2017 - 15:08.

  • 0

#31 maniack

maniack

    Weteran WHT

  • WHT+
  • PipPipPipPipPipPipPipPip
  • 667 postów
  • Skąd:Bielsko-Biała
  • Firma:netBOMB

Napisany 22 maj 2017 - 18:20

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

Dokładnie tak :)
 

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.

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ć? :)
  • 0

#32 Archi

Archi

    Wyznawca OVH

  • WHT+
  • PipPipPipPipPipPipPipPip
  • 2803 postów
  • Skąd:Warszawa
  • Imię:Łukasz

Napisany 23 maj 2017 - 05:42

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.


Edytowany przez Archi, 23 maj 2017 - 05:45.

  • 0

#33 nnd_newbie

nnd_newbie

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 139 postów

Napisany 23 maj 2017 - 07:53

 

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"?


Edytowany przez nnd_newbie, 23 maj 2017 - 08:02.

  • 0

#34 maniack

maniack

    Weteran WHT

  • WHT+
  • PipPipPipPipPipPipPipPip
  • 667 postów
  • Skąd:Bielsko-Biała
  • Firma:netBOMB

Napisany 23 maj 2017 - 18:40

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.

@Archi, wybacz, ale o ile szanuję twoją wiedzę okołolinuksową, o tyle w tematach bazodanowych co rusz rzucasz teorie, których w życiu nie sprawdziłeś w praktyce, i nie dopuszczasz myśli, że możesz nie mieć racji :)
  • 0





0 użytkowników czyta ten temat

0 użytkowników, 0 gości, 0 anonimowych użytkowników