NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Diskuze: SQL SELECT kde hodnota môže ale nemusí byť null

V předchozím kvízu, Online test znalostí PHP, jsme si ověřili nabyté zkušenosti z kurzu.

Aktivity
Avatar
DREAMDEV
Člen
Avatar
DREAMDEV:30.11.2016 23:14

Robím systém kde užívateľ si môže vytvárať priečinky ktoré môžu byť vnorené do seba. Každý z nich má teda stĺpec folder_id (id rodiča) no tento stĺpec má hodnotu null tam kde rodič je v podstate root.

Moja otázka je, ako napísať jednu query tak aby som nemusel písať 2 rôzne query, kedže na číselné hodnoty musím použiť "WHERE folder_id=$x" a na null "WHERE folder_id IS NOT NULL"?

Alebo ako by ste to riešili vy?

 
Odpovědět
30.11.2016 23:14
Avatar
Lava
Člen
Avatar
Lava:1.12.2016 7:52

Založ si riadok, v ktorom budeš mať akože "root" a ten bude mať id=1. Potom všetky priečinky, ktoré budú v roote budú mať id rodiča 1 a tým to odlíšiš potom v PHP, že je to root. Aspoň ja mám s takýmto riešením iks skúsenosti.

Nahoru Odpovědět
1.12.2016 7:52
Aspartám, sacharín, to je môj vitamín
Avatar
DREAMDEV
Člen
Avatar
DREAMDEV:1.12.2016 11:34

Nebolo by lepsie nastavit folder_id namiesto null na 0 aby databaza ostala cista ked nebude vytvoreny ziadny priecinok?

 
Nahoru Odpovědět
1.12.2016 11:34
Avatar
Lava
Člen
Avatar
Odpovídá na DREAMDEV
Lava:1.12.2016 12:01

No však to isté píšem ja... môže to byť 0, 1, alebo hocijaká iná konštanta... hlavne aby to nebolo null.

Asi by bolo dobre, keby is tu dal celé query, no tvoj problém sa zrejme bude dať vyriešiť aj tak, aby si napísal

SELECT ... FROM ... WHERE folder_id=$x AND folder_id IS NOT NULL
Nahoru Odpovědět
1.12.2016 12:01
Aspartám, sacharín, to je môj vitamín
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Lava
DREAMDEV:1.12.2016 12:06

No keby som nastavil to folder_id na 0 tak ten root by som v databaze nevytvaral vobec. AI ti nikdy nehodi idcko 0 zacina od 1 takze to neni az tak celkom to iste :)

 
Nahoru Odpovědět
1.12.2016 12:06
Avatar
Jan Bezdíček
Tvůrce
Avatar
Odpovídá na Lava
Jan Bezdíček:1.12.2016 12:08

Jaky ma smysl ta cast s

AND folder_id IS NOT NULL

?

 
Nahoru Odpovědět
1.12.2016 12:08
Avatar
Odpovídá na DREAMDEV
Michal Haňáček:1.12.2016 12:17

Mrkni se na COALESCE ...

Nahoru Odpovědět
1.12.2016 12:17
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Nahoru Odpovědět
1.12.2016 12:17
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Michal Haňáček
DREAMDEV:1.12.2016 12:26

Nenapada ma ako by sa ta funkcia dala tu pouzit. Ide o to ze chcem spravit nasledovny select:
WHERE folder_id=$x

ale ak $x je null tak potom predchadzajuca query nefunguje a musim pouzit tuto:
WHERE folder_id IS NULL

Otazka je ako to spraviť pomocou 1 query?

 
Nahoru Odpovědět
1.12.2016 12:26
Avatar
Odpovídá na DREAMDEV
Michal Haňáček:1.12.2016 13:20

Viděl bych to asi nějako takto:

SELECT COALESCE(folder_id, <zastupna_hodnota_za_null>) FROM XXX WHERE folder_id=$x OR folder_id IS NULL

Jen mi není úplně jasné, na co vybíráš konkrétní folder_id, nebo všechny kde je folder_id null.

Nahoru Odpovědět
1.12.2016 13:20
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Michal Haňáček
DREAMDEV:1.12.2016 13:35

No priecinky mozu byt vnorene do seba cize kazdy ma stlpec id co je jeho unikatne id a stlpec folder_id co je vlastne nieco ako parent_id.

Tamta query vytiahne vsetky zaznami kde folder_id=$x + prida k tomu vsetky zaznami kde je folder_id null to nie je dobre.

Ide o to ze ked si otvorim priecinok s id napriklad 6 tak sa mi zobrazia vsetky priecinky kde parent_id=6. Ale ked otvorim v podstate root priecinok zobrazia sa vsetky priecinky kde parent_id IS NULL.

Preto potrebujem bud query ktora to zvladne. Alebo nejaky napad ako prerobit navrh db :)

Moja ideologia bola taka ze kym uzivatel sam nevytvori nejaky priecinok databazova tabulka by mala byt prazdna a preto root nie je ulozeny v db.

 
Nahoru Odpovědět
1.12.2016 13:35
Avatar
Michal Haňáček:1.12.2016 15:09

Chápu co máš, ale asi jsem úplně hloupej, protože doteď kloudně nechápu co z toho QRY chceš dostat.

  1. chceš seznam všech složek odkazujících na nějaké ID?
  2. chceš seznam všech root složek?
  3. chceš něco jiného? napiš mi co.
Nahoru Odpovědět
1.12.2016 15:09
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Michal Haňáček
DREAMDEV:1.12.2016 15:23

chcem (a) a (b) v jednom v podstate :) lebo predsa je to velmi podobna vec s minimalnym rozdielom a podla mna na to staci 1 query.

Keby tie root zlozky mali parent_id 0 a nie null tak potom by to islo krasne jednou jedinou query. Preto teraz aktualne prerabam tymto spôsobom. Chapes, z postu mi moze prist nejake $x a ked tam mam query WHERE folder_id=$x a nahodov mi pride z postu null a nie nejake konkretne id tak uz musim pomocov ifu pouzit inu query, a to nechcem.

Kedze uz to riesim tak ze som null nahradil 0 tak je po probleme ale:
1.) chcem vediet ci sa da taka query zostavit
2.) chcem prediskutovat ine mozne riesenia
3.) kto bude posluchat dostane bod za spravne riesenie :D :D

 
Nahoru Odpovědět
1.12.2016 15:23
Avatar
Odpovídá na DREAMDEV
Michal Haňáček:1.12.2016 15:28

Tamta query vytiahne vsetky zaznami kde folder_id=$x + prida k tomu vsetky zaznami kde je folder_id null to nie je dobre.

chcem (a) a (b) v jednom v podstate :) lebo predsa je to velmi podobna vec s minimalnym rozdielom a podla mna na to staci 1 query.

To si trochu protiřečí, nemyslíš?

Nahoru Odpovědět
1.12.2016 15:28
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Michal Haňáček
DREAMDEV:1.12.2016 15:40

No ja ich nechcem vsetky naraz predsa!

Ta tvoja query by urobila to ze ak pride id 6 tak query vytiahne vsetky priecinky kde je folder_id=6 a este k tomu prida aj priecinky kde folder_id IS NULL. To je zle!

Ak mi pride z postu null tak chcem zobrazit priecinky kde folder_id je null. Ak mi pride z postu 6 napriklad tak chcem zobrazit iba priecinky kde folder_id je 6 a nie kde folder_id je 6 alebo null.

Ta tvoja query by v oboch pripadoch vytiahla vsetky priecinky korych folder_id je null. Plus v prvom pripade by k nim pridala este priecinky ktorych folder_id je 6.

Stale nechapačky?

 
Nahoru Odpovědět
1.12.2016 15:40
Avatar
Odpovídá na DREAMDEV
Neaktivní uživatel:1.12.2016 16:44

Takže ty chceš pro parametr x = null vybrat všechny s folder_id = null, a pro x ∈ N vybrat všechny, kde je folder_id je x?

SELECT id FROM table WHERE (x IS NULL AND folder_id IS NULL) OR (x IS NOT NULL AND folder_id = x);
Editováno 1.12.2016 16:46
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
Nahoru Odpovědět
1.12.2016 16:44
Neaktivní uživatelský účet
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Neaktivní uživatel
DREAMDEV:1.12.2016 16:53

Máme víťaza :D to je presne ono ale je to kua kua dlha query no aj tak dobre vediet :P Ďakujem krásne :)

 
Nahoru Odpovědět
1.12.2016 16:53
Avatar
Odpovídá na DREAMDEV
Michal Haňáček:1.12.2016 16:58

Teď už chápačky. Až dosud jsi ale nenapsal co od toho chceš. To že to víš ty neznamená, že to chápou ti, kterým dotaz pokládáš...

Obecně by tohle mělo řešit query přes parametry, vkládat hodnotu přímo do query je nebezpečné (SQL injection) a v tomhle případě ti neumožňuje dosáhnout toho co chceš.

Ale k věci:

SELECT ... FROM ... WHERE IIF($x == -999, folder_id is null, folder_id=$x);

Neaktivní uživatel
Ta druhá podmínka je zbytečná, když vybíráš folder_id dle hodnoty, nevrátí ti ty kde je hodnota nul.l

Nahoru Odpovědět
1.12.2016 16:58
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
Odpovídá na DREAMDEV
Neaktivní uživatel:1.12.2016 16:59

Já jsem na to koukal už včera, ale nevěděl jsem, co chceš :D Musíš si uvědomit, že null v databázích je úplně jiný jako v programování. V programování je to dejme tomu jako něco bez hodnoty, neinicializované. V databázích je to jako neznámá hodnota. To znamená, že nemůžeš říct, jestli se null něčemu rovná nebo ne, proto všechny porovnání nad null hodnotami vrací null.

1 = 1     -- 1
1 = null  -- 0
1 <> null -- 0

null = null  -- 0
null <> null -- 0

null is not null -- 0
null is null     -- 1
Nahoru Odpovědět
1.12.2016 16:59
Neaktivní uživatelský účet
Avatar
Nahoru Odpovědět
1.12.2016 17:00
Neaktivní uživatelský účet
Avatar
Odpovídá na Michal Haňáček
Neaktivní uživatel:1.12.2016 17:04

Pokud se nepletu, tak IIF není standartní součást SQL, tudíž to není zas tak fajn řešení.

Nahoru Odpovědět
1.12.2016 17:04
Neaktivní uživatelský účet
Avatar
Odpovídá na Neaktivní uživatel
Michal Haňáček:1.12.2016 17:07

Máš pravdu, mohl jsem ho nahradit. Ale přišlo mi to nejčitelnější (když nepočítám ten překlep s rovnítkama :D ). Byl to jen návrh řešení, co si z toho tazatel vezme je na něm ...

Nahoru Odpovědět
1.12.2016 17:07
Každé rozhodnutí a každý krok v životě nás někam posune. Bohužel jen některé nás posouvají dopředu.
Avatar
DREAMDEV
Člen
Avatar
Odpovídá na Michal Haňáček
DREAMDEV:1.12.2016 20:14

Postupne sme sa ale k tomu dostali a pochopili co by som si vlastne od vas prosil takze vsetko je v poriadku tiez som len clovek a nie som dokonali ale snazil som sa to vysvetlit tak aby ste to pochopili :)

Ano riesim to cez parametre ale sem som to napisal pre ulahcenie ako cistu query :)

 
Nahoru Odpovědět
1.12.2016 20:14
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 23 zpráv z 23.