Skocz do zawartości

Web Hosting Talk

  • arubacloud.pl

    Partner technologiczny

    Aruba Cloud jest marką usług cloud na rynku europejskim. Została stworzona w celu dostarczenia firmom kompleksowych rozwiązań Cloud niezależnie od ich planów i projektów.

 

Zdjęcie

zapytanie sql

zapytanie sql

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

zapytanie sql

#1 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Nowy
  • 6 postów

Napisany 19 maj 2017 - 10:22

witam

mamy tabelę z atrybutami produktów

ID produkt ; nazwa cechy ; wartość
777 ; powierzchnia ; 1 ;
777 ; długość ; 350 ;
778 ; długość ; 350 ;
778 ; powierzchnia ; 2 ;
779 ; długość ; 350 ;
779 ; powierzchnia; 1 ;


jakim zapytaniem otrzymamy tylko produkty które np mają długość 350 ale i powierzchnię 1 ???

dzięki
  • 0

#2 nnd_newbie

nnd_newbie

    Regularny użytkownik

  • Użytkownicy
  • 85 postów

Napisany 19 maj 2017 - 10:47

jakim zapytaniem otrzymamy tylko produkty które np mają długość 350 ale i powierzchnię 1 ???

dzięki

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;

Niezbyt ładnie ale zadziała (przynajmniej w MYSQL)


Edytowany przez nnd_newbie, 19 maj 2017 - 10:50.

  • 0

#3 davee

davee

    Nowy użytkownik

  • Użytkownicy
  • 13 postów

Napisany 19 maj 2017 - 10:48

SELECT `ID produktu` FROM (SELECT `ID produktu` FROM <nazwa_tabeli> WHERE `nazwa cechy` = "długość" AND `wartość` = 350) WHERE `nazwa cechy` = "powierzchnia" AND `wartość` = 1;

 

Możesz spróbować tak ale nie jest to chyba najbardziej wydajny sposób.


  • 0

#4 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Nowy
  • 6 postów

Napisany 19 maj 2017 - 11:12

dzięki panowie będę testować później i dam znać
bardziej wydajny jest przykład 1 czy 2 ?
  • 0

#5 rzessski

rzessski

    Nowy użytkownik

  • Użytkownicy
  • 14 postów

Napisany 19 maj 2017 - 11:38

a czemu nie po prostu

 

select idprodukt from table where nazwa = '350' AND powierzchnia = '1'; 

 


  • 0

#6 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 440 postów

Napisany 19 maj 2017 - 12:46

Wszystkie podane rozwiązania są błędne, trzeba użyć joina na tabeli z produktami oraz tej którą pokazałaś. Ewentualnie można użyć pivota. W sumie to bez pivota się nie obejdzie.

 

Nie mam teraz na to czasu, ale może dziś postaram Ci się coś napisać, jeśli nie to dopiero w poniedziałek.


Edytowany przez Fizyda, 19 maj 2017 - 12:47.

  • 0

#7 Rafiki

Rafiki

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 224 postów

Napisany 19 maj 2017 - 12:55

Wszystkie podane rozwiązania są błędne, trzeba użyć joina na tabeli z produktami oraz tej którą pokazałaś. Ewentualnie można użyć pivota. W sumie to bez pivota się nie obejdzie.

 

Nie mam teraz na to czasu, ale może dziś postaram Ci się coś napisać, jeśli nie to dopiero w poniedziałek.

 

JOIN do operacji na jednej tabeli ????

Grubo ;)

 

Autor nigdzie nic nie pisał o drugiej tabeli (np z nazwami produktów czy jakimikolwiek innymi danymi)

 

W mysql można stosować nawiasy i instrukcje typu AND i OR. Więcej tutaj: https://www.techonth...ysql/and_or.php (przykład nr. 3 pokazuje rozwiązanie Twojego problemu)

 

PS. Twój problem to podstawy mysql więc może warto przeczytać jakiś kurs :)


Edytowany przez Rafiki, 19 maj 2017 - 13:02.

  • 0

#8 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 440 postów

Napisany 19 maj 2017 - 12:58

 

JOIN do operacji na jednej tabeli ????

Grubo ;)

 

Czytaj od początku do końca, a nie tylko fragmentami ;)

 

 

trzeba użyć joina na tabeli z produktami oraz tej którą pokazałaś.

 

Poza tym później dodałem że i tak bez pivota się nie obejdzie i tak, czyli tym samym join nie jest niezbędny.


  • 0

#9 Rafiki

Rafiki

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 224 postów

Napisany 19 maj 2017 - 13:00

 

Czytaj od początku do końca, a nie tylko fragmentami ;)

 

 

Poza tym później dodałem że i tak bez pivota się nie obejdzie i tak, czyli tym samym join nie jest niezbędny.

 

no właśnie przeczytałem ale Ty chyba jeszcze nie....


  • 0

#10 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Nowy
  • 6 postów

Napisany 19 maj 2017 - 13:04

Dla uproszczenia nie podawałem drugiej tabeli z id produktu i nazwa produktu. Możemy przyjąć że jest tylko jedna która opisałem na początku. 2 i 3 odp chyba ok co ??
rafiki masz na myśli

SELECT customer_id, last_name, first_name
FROM customers
WHERE (last_name = 'Johnson')
OR (last_name = 'Anderson' AND state = 'California')
OR (last_name = 'Smith' AND status = 'Active' AND state = 'Florida');
  • 0

#11 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 440 postów

Napisany 19 maj 2017 - 13:05

 

no właśnie przeczytałem ale Ty chyba jeszcze nie....

Edytowałeś post po tym jak odpisałem ...

 

 

Autor nigdzie nic nie pisał o drugiej tabeli (np z nazwami produktów czy jakimikolwiek innymi danymi)

 

W mysql można stosować nawiasy i instrukcje typu AND i OR. Więcej tutaj: https://www.techonth...ysql/and_or.php (przykład nr. 3 pokazuje rozwiązanie Twojego problemu)

 

PS. Twój problem to podstawy mysql więc może warto przeczytać jakiś kurs :)

 

Nie napisał też o tym że takowej tabeli nie ma. Po schemacie tabeli którą pokazał gołym okiem widać że jest to tabela która wchodzi w relację jeden do wielu z tabelą z produktami i przechowywane w niej są nietypowe pola dla produktów które nie są wspólne dla wszystkich produktów w bazie.

 

Twój link i propozycja również nie rozwiązuje problemu. Raz jeszcze mówię, trzeba zastosować pivota.

 

EDIT:

Prawdopodobniej szybciej będzie zrobić to z joinem i pivotem niż samym pivotem na jednej tabeli, ponieważ w drugim przypadku będzie to trochę jazda figurowa jeśli chodzi o zapytanie.


Edytowany przez Fizyda, 19 maj 2017 - 13:06.

  • 0

#12 Rafiki

Rafiki

    Stały użytkownik

  • Użytkownicy
  • PipPipPipPipPip
  • 224 postów

Napisany 19 maj 2017 - 13:30

@Fizyda. sora ale znowu pokazujesz ,że nie masz racji...czepiasz się już któryś raz moich wypowiedzi a pierw wypadało by abyś sam zweryfikował swoją wiedzę i porady. Jeśli masz problem do mojej osoby zapraszam na PW, a publicznie na forum radziłbym zachować merytoryczną dyskusję dot. problemów i wiedzy które traktuje wątek.

 

po pierwsze - wiadomość edytowałem dodając link z rozwiązaniem i wypowiedz PS. - nic odnośnie wypowiedzi dot. Ciebie nie zostało zmienione

po drugie - sprawdź dokładniej do czego służy JOIN i w jakim celu chcesz łączyć jedną tabele, używać JOIN'a i obciążać dodatkowo bazę?

po trzecie - cały czas chyba nie przeczytałeś postu autora tego tematu

 

a teraz dla Ciebie screen z rozwiązaniem - wynik z phpmyadmina i tabela utworzona na szybko....

zaprezentowany jest wynik zapytania ....sama tabela posiada więcej rekordów niż dwa zaprezentowane z wyniku.

 

@piotrszmigin - tak chodziło mi dokładnie o te rozwiązanie  - oczywiście zamiast imion i stanów trzeba podmienić swoje wartości :)

 

Załączone pliki


Edytowany przez Rafiki, 19 maj 2017 - 13:44.

  • 0

#13 davee

davee

    Nowy użytkownik

  • Użytkownicy
  • 13 postów

Napisany 19 maj 2017 - 13:47

Dla uproszczenia nie podawałem drugiej tabeli z id produktu i nazwa produktu. Możemy przyjąć że jest tylko jedna która opisałem na początku. 2 i 3 odp chyba ok co ??
rafiki masz na myśli

SELECT customer_id, last_name, first_name
FROM customers
WHERE (last_name = 'Johnson')
OR (last_name = 'Anderson' AND state = 'California')
OR (last_name = 'Smith' AND status = 'Active' AND state = 'Florida');

 

Nie wiem jaką masz konfigurację serwer bazy danych, ale u mnie po krótkim teście na 10 000 rekordach działa bardzo dobrze zarówno moje rozwiązanie jak i kolegi przede mną.


  • 0

#14 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 440 postów

Napisany 19 maj 2017 - 15:25

@Rafiki nie mam nic do Twojej osoby i w ogóle nie kojarzę bym czepiał się Twoich postów - czytaj jeśli tak jest/było nie robię tego umyślnie celowo.

Twoja wypowiedź była edytowana 3 razy, i nie mów że nie. Pierwsza do której się odnosiłem zawierała 2 linijki które zacytowałem (zacytowałem cały post taki jakim był w momencie gdy na niego odpowiadałem). Później dodałeś linijkę o tym że autor nigdzie nie napisał nic że jest inna tabela, a następnie link do rozwiązania.

 

Już wiem też w czym tkwi problem, chodzi dokładnie o to jak rozumiemy następujące zdanie z pierwszego postu:

 

 

jakim zapytaniem otrzymamy tylko produkty które np mają długość 350 ale i powierzchnię 1 ???

 

Ja to rozumiem że szukamy produktów które mają zadaną długość i powierzchnię. Z tego co widzę Ty to rozumiesz że szukamy produktów które mają zadaną długość lub zadaną powierzchnię, i w tym przypadku Twoje rozwiązanie jest dokładnie tym co potrzeba.

Zauważ jednak iż pozostałe osoby które zaproponowały rozwiązania używały tylko AND czyli zrozumiały problem tak jak ja, niestety ich rozwiązania są błędne i nie znajdą żadnych wyników. Cała nieścisłość powstała z winy autora, ponieważ tak opisał to czego potrzebuje, że jak teraz na to patrzę faktycznie można to podciągnąć pod OR, chociaż dla mnie nadal tam jest AND.

 

Nie rozumiem też czemu uczepiłeś się tak tego JOINa skoro sam wycofałem się z tego rozwiązania już w poście w którym go zaproponowałem, zupełnie nie rozumiem o co Ci z tym JOINem chodzi.

 

Twoje rozwiązanie jest poprawne tylko w tedy gdy chcemy uzyskać produkty które mają szukaną powierzchnię lub długość. Niestety jeśli chodzi to by znaleźć produkty które mają daną powierzchnię i długość, nie zrobisz tego jak proponujesz i musisz użyć pivota.

 

Dodatkowo ja uważam w dalszym ciągu (przynajmniej do czasu aż jasno nie napisze o co pytał) że chodzi o to by znaleźć produkty które mają podaną długość i powierzchnię, choćby z tego powodu, że wątpię by ktoś pytał o tak prostą rzecz. Nawet jeśli dopiero uczyłby się sql to to są rzeczy które musiał przerobić w jakimkolwiek kursie/tutorialu z internetu.


  • 0

#15 nnd_newbie

nnd_newbie

    Regularny użytkownik

  • Użytkownicy
  • 85 postów

Napisany 19 maj 2017 - 17:32

Nie sądzę, żeby była nieścisłość. Autor szuka produkty które mają zadaną długość ORAZ powierzchnię, inaczej nie byłoby problemu. Trudnośc polega na konstrukcji danej tabeli (wertykalnie) czego nie zauważył chyba ani @rzessski ani @Rafiki

 

1) Rozwiązanie 1 ode mnie i 2 od @davee są poprawne. Dla wyjaśnienia: zapytanie wewnętrzne wyciągnie z tabeli elementy które mają zadaną  powierzchnię, a następnie spośród nich zapytanie zewnętrzne wybierze te które mają także zadaną długość.

2) Rozwiązania podane przez @rzessski i @Rafiki nie zadziałają bo są dla innej konstrukcji tabeli (takiej w której długość i powierzchnia są w jednym wierszu)

3) Join zadziała tylko po co zarzynać bazę jak można to prościej.

4) Pivot jest rozwiązaniem dedykowanym do takich właśnie zastosowań

 

Tutaj masz ładny przykład jak odwrócić bazę wertykalną do horyzontalnej przy użycia pivota: https://4programmers...45748#id1345748


Edytowany przez nnd_newbie, 19 maj 2017 - 17:36.

  • 0

#16 Fizyda

Fizyda

    Stały użytkownik

  • WHT Pro
  • PipPipPipPipPip
  • 440 postów

Napisany 19 maj 2017 - 20:02

1) Rozwiązanie 1 ode mnie i 2 od @davee są poprawne. Dla wyjaśnienia: zapytanie wewnętrzne wyciągnie z tabeli elementy które mają zadaną  powierzchnię, a następnie spośród nich zapytanie zewnętrzne wybierze te które mają także zadaną długość.

 

Racja, szczerze mówiąc nie wpadłbym żeby to zrobić przez podzapytanie, znaczy może bym wpadł, ale to nie było rozwiązanie które pierwsze nasuwa mi się na myśl. Dlatego też tylko zerknąłem w Wasze rozwiązania, nie przeanalizowałem ich dokładniej, mój błąd.


  • 0

#17 zbenek12345

zbenek12345

    Często na forum

  • Użytkownicy
  • 52 postów

Napisany 20 maj 2017 - 07:26

a czemu nie po prostu
 
select idprodukt from table where nazwa = '350' AND powierzchnia = '1'; 
 

Dlaczego to rozwiązanie jest błędne? Skoro jest nieprawidłowe to może ktoś w końcu podać poprawne zapytanie na pierwszy post autora :) Sam jestem ciekaw.
  • 0

#18 piotrszmigin

piotrszmigin

    Nowy użytkownik

  • Nowy
  • 6 postów

Napisany 20 maj 2017 - 09:09

Dzięki za odp... na pierwszy rzut oka Newbie wygląda rozwiązanie ok. Sprawdzę i dam znać.... zbenek zapytanie jest ok ale nie zwróci tego co chcemy ;)
  • 0

#19 maniack

maniack

    Weteran WHT

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

Napisany 20 maj 2017 - 10:12

Dlaczego to rozwiązanie jest błędne?

Bo w tabeli nie ma ani kolumny "nazwa", ani kolumny "powierzchnia".
  • 0

#20 nnd_newbie

nnd_newbie

    Regularny użytkownik

  • Użytkownicy
  • 85 postów

Napisany 20 maj 2017 - 12:22

Żeby zamknąć temat. W załączniku dwa skrypty.

 

tworzenie_tabeli.txt - tworzy tabelę i wypełnia losowymi danymi. Na koniec dodaje 5 produktów z których tylko dwa (idproduct 3 i 4) mają powierzchnię 1 i dlugość 350

 

zapytania.txt - trzy zapytania

1) Z zapytaniem wewnętrznym

2) Z joinem

3) Zamiana tabeli z wertykalnej na horyzontalną i wyciągnięcie danych poprzez standardowe zapytanie WHERE AND

 

Jak ktoś chce sobie przetestować wydajność to w procedurze insert_data() można zmienić zakres pętli z 200 do większej

 

PS 1. Zrobione na MySQL. W innych bazach pewnie można lepiej np. pivot w MSSQL

PS 2. Skrypty są pisane w Linuxie. Więc w Windowsie lepiej otwierać w czymś lepszym niż Notatnik. Polecam Notepad++

 

Załączony plik  tworzenie_tabeli.txt   1,77K   3 pobrań

Załączony plik  zapytania.txt   883bajtów   6 pobrań


  • 0





0 użytkowników czyta ten temat

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