Dlaczego czasem używany jest WHERE a czasem AND?

1

Witam wszystkich 2 tydzien nauki i teraz to naprawde czuje sie tak jakbym nic nie wiedzial? Mianowicie mam taka rozkmine

  1. Exercise
    Show the name, initial price, and final price of every item with initial price greater than $300.

    If the item wasn't sold (there was no bidding person), show the item's name anyway.

    select
    auction_item.name,
    auction_item.initial_price,
    bidder.final_price
    from auction_item
    left join bidder
    on auction_item.id = bidder.bought_item_id
    where auction_item.initial_price > 300;
    
  2. Exercise
    Show the title of each book and the name of its author — but only if the author was born in the 20th century.

    Otherwise, the author's name field should be NULL.

    SELECT
    b.title,
    a.name
    from book b
    left join author a
    on a.id = b.author_id
    and	birth_year BETWEEN 1901 AND 2000;
    

Czy ktos jest w stanie mi powiedziec dlaczego w 1 zapytaniu z LEFT JOINem używam warunku WHERE, a w 2 drugim AND?

  • Prosze bez smiechu
  • 2 CHATGPT nie pomaga
  • Wiem, ze uzywamy WHERE gdy wiersze z kolumn juz sa polaczone, wiem rowniez ze AND dajemy gdy tabele sa laczone? mimo wszystko, nie rozumiem tego

Pytanie czy ktos potrafi to wytlumaczyc jak prostemu chlopowi? dziekuje za szczere checi.

2

Nie rozumiem za bardzo czego nie rozumiesz.
W pierwszym przypadku łączysz tabele pod jednym warunkiem a potem na tym złączeniu dajesz dodatkowy warunek wywalając cały rekord z wyników
W drugim przypadku łączysz tabele pod dwoma warunkami, nadal przechodzi rekord z pierwszej tabeli ale jeśli te dwa warunki się nie spełnią to nic nie zostaje do niej dołączone

Cisu93miastoKrk napisał(a):
  • WIem, ze uzywamy where gdy wiersze z kolumn juz sa polaczone, wiem rowniez ze and dajemy gdy tabele sa laczone? mimo wszystko za c**** tego nie rozumiem

cofnij się. And oznacza tylko i i nic więcej. Nie porównujesz tutaj where z and bo to nie ma żadnego sensu. Porównujesz where z on. and należy tutaj do warunkowego złączenia. Może jak sobie to lepiej sformatujesz albo dodasz nawiasy to będzie ci łatwiej zrozumieć:

SELECT
  b.title,
  a.name
FROM book b
LEFT JOIN author a
  ON (a.id = b.author_id AND birth_year BETWEEN 1901 AND 2000);
0

ok to moze inaczej dlaczego w 1 zadaniu nie moge uzyc and i w 2 nie moge dac where?

2

Tłumacząc zapytania na naturalny język:

  1. Pokaż nazwę przedmiotów aukcji gdzie początkowa cena jest większa niż 300, dołącz do nich informacje o licytujących gdy identyfikator przedmiotu się zgadza
  2. Pokaż nazwy książek, dołącz do nich informacje o autorze gdy identyfikator autora się zgadza i rok urodzenia autora jest między 1901 a 2000

Twoje pytanie:
dlaczego w 1 zadaniu nie mogę użyć "i" a w 2 nie mogę dopisać "gdzie".

Odpowiedź brzmi: bo nie ma to żadnego sensu, tak samo jak twoje pytanie.

Możesz zamienić drugie zapytanie na:

  1. Pokaż nazwy książek gdzie rok urodzenia autora jest między 1901 a 2000, dołącz do nich informacje o autorze gdy identyfikator autora się zgadza

czyli:

SELECT
  b.title,
  a.name
FROM book b
LEFT JOIN author a ON a.id = b.author_id
WHERE birth_year BETWEEN 1901 AND 2000;

ale zmieni to wynik i przestanie pokazywać książki których autor nie spełnia tych warunków lub dla których dane autora są niedostępne.
Nie masz problemu ze zrozumieniem SQLa tylko zdań logicznych złożonych https://pl.wikipedia.org/wiki/Zdanie_logiczne

0
Cisu93miastoKrk napisał(a):

ok to moze inaczej dlaczego w 1 zadaniu nie moge uzyc and i w 2 nie moge dac where?

  • Do przyłączenia tabeli stosuje się JOIN..ON, łączy się tabele pod jakimś warunkiem.
  • Do dodania warunku stosuje się WHERE, filtruje się wyniki pod jakimś warunkiem.
  • AND to jest połączenie dwóch warunków, np. shapes.color='red' AND shapes.type='circle'. AND to jest wyrażenie, które można dodać wszędzie tam gdzie mamy jakieś wyrażenie boolean (true/false), czyli również w WHERE i ON.
1
Cisu93miastoKrk napisał(a):

ok to moze inaczej dlaczego w 1 zadaniu nie moge uzyc and i w 2 nie moge dac where?

Możesz 😀
Ogólnie w 1 zapytaniu masz join po jakimś tam kluczu ale where zawęża Ci wyniki tabeli głównej natomiast możesz to zapytanie zmienić na takie:

select
auction_item.name,
auction_item.initial_price,
bidder.final_price
from auction_item
left join bidder
on auction_item.id = bidder.bought_item_id and auction_item.initial_price > 300;

i w większości baz plan zapytania będzie ten sam choć niekiedy optymalizator może się pogubić dlatego lepiej odfiltrować tabelę główną w where. Z tego co pamiętam kolejność wykonywania poleceń w oracle to FROM/JOIN potem dopiero WHERE następnie GROUP BY -> HAVING i dopiero SELECT. Mało tego tu masz też LEFT JOIN czyli w tabeli bidder może nie być takiego bought_item_id więc tutaj aż się prosi o przerzucenie warunku do where zgodnie z przykładem

W drugim select również możesz zrobić na odwrót i warunek AND przerzucić do WHERE to też zadziała

SELECT
b.title,
a.name
from book b
left join author a
on a.id = b.author_id
where birth_year BETWEEN 1901 AND 2000;

ale jak wyżej joinujesz leftem tabelę, która może nie mieć wyników więc on fizycznie pobrałby wszystkie ID (bo najpierw robi joiny) a dopiero potem odfiltruje (pomijam już NULLe not NULL na tabeli itd) więc może się okazać, że optymalizatorowi łatwiej będzie (szybciej wykona) zapytanie z AND zamiast WHERE natomiast technicznie ograniczeń NIE MA wszystko opiera się o dobranie najlepszego planu zapytania dla danego zagadnienia na zadanym zestawie danych i konkretnej maszynie 😀

5

@woolfik nie masz racji nie moze zamienić w drugim warunku na where.

@Cisu93miastoKrk zmienimy trochę zapytanie, abyś zrozumiał dlaczego warunek na datę urodzenia jest w on

SELECT
  b.title,
  a.name
FROM book b
LEFT JOIN (select * from author where birth_year BETWEEN 1901 AND 2000) a
  ON a.id = b.author_id;

Czyli join poza połączeniem po author_id "Weźmie" tylko rekordy z birth_year od 1901 do 2000. Gdybyśmy dali to w where to nie pokazałbyś książek, które nie mają autora lub autor urodził się poza zadanym przedziałem

0

Ej czytajcie ze zrozumieniem ... napisałem przecież: pomijam już NULLe not NULL na tabeli itd)
A że działa to możecie sobie zobaczyć tutaj:
https://sqlfiddle.com/oracle/online-compiler?id=8a51a652-d55e-4b1f-8880-0b84b16b0c04

więc nie wkurzać mnie bo jak mówię, że działa to działa

0

pominiecie nulli not nulli w przypadku left/right joina trochę wypacza sens, to jakby napisać że inner join zadzial tak samo jak left join jeżeli zbiory będą takie same...
Zrestą to nie tylko kwestia nulli, lekko zmodyfikowany Twój przykład: https://sqlfiddle.com/oracle/online-compiler?id=5ca6bd51-f9a8-4cbe-b1bc-e5691f18bcdc

0

Czytajcie ze zrozumieniem ... pytacz zapytał dlaczeog nie możę. MOŻE! to czy to ma sens czy zwróci taki sam set danych itd to jest zupełnie inna kwestia. Do czego innego służą warunki przy joinach do czego innego w wehere i to opisaliście wyżej ja skupiłem się na samym aspekcie technicznym. Można przerzucać warunki między join i where ale ma to pewne konsewkencje np zwróci różny zakres danych. Można to uzuskać na wiele sposobów ale to nie jest klu mojej wpowiedzi ....
Tak samo ja mogę zmienić Twój przykład:
https://sqlfiddle.com/oracle/online-compiler?id=dc4f4fa6-c743-4fa1-be6a-e546e49566f9
i też zadziała wszystko zależy od kontkestu, potrzeb i danych

3

Na wstępie napiszę, że zawsze możesz dać WHERE.

A teraz przejdźmy do konkretów. Zapytania SQL składają się z jak by to powiedzieć "bloków kodu".
Najpierw masz SELECT gdzie wypisujesz jakie chcesz kolumny
Później masz FROM gdzie wypisujesz z jakich tabel chcesz to wyciagnąć i ewentualnie dajesz aliasy na nazwę tabeli
Później możesz (ale nie musisz) łączyć tabele z innymi tabelami, czyli różne JOIN. Gdy robisz JOIN to albo robisz CROSS JOIN (każdy z każdym) albo podajesz po czym łączysz. Możesz łączyć po jednej, dwóch, trzech, etc kolumnach. Jesli łaczysz po więcej niż jednej kolumnie to dajesz warunki logiczne np. AND / OR
Później możesz zawężać grupę wyników klauzulą WHERE
Później możesz grupować wyniki klazulą GROUP BY
Później możesz zawęzić wyniki grupowane klazulą HAVING
I na koniec możesz to wszystko posortować SORT BY [nazwa kolumny] asc/desc

1

Kwwestia zapisu. W teorii można prawie wszystko wcisnąć do where i niektórzy walący stęchlizną spece od Oracle nadal tak robią niestety, bo dawno temu w Oracle nie było join i pisało się coś na zasadzie select * from a, b where a.id = b.aid
Natomiast czytelniej jest jak używasz tych klauzul SQL (join.. on... i where) zgodnie z ich przeznaczeniem. Czyli w join podajesz warunek złączenia tabel, a w where dodatkowe warunki filtrowania zwracanego zbioru już po złączeniu (logicznie, bo technicznie, to optymalizator i tak w większości przypadków zastosuje te warunki na wejściu).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.