Autor Zpráva
H13
Profil
Ahoj, potřeboval bych poradit s jedním sql dotazem, mám následující tabulky:

tabulka SKUPINA-A : id | jmeno
tabulka SKUPINA-B : id | jmeno

tabulka POLOZKA : id|jmeno|skupina-tabulka|skupina-id

Data pro tabulku SKUPINA-A
1|skupinova-polozka1a
2|skupinova-polozka2a

Data pro tabulku SKUPINA-B
1|skupinova-polozka1b
2|skupinova-polozka2b

Data pro tabulky POLOZKA
1|polozka1|SKUPINA-A|1
2|polozka2|SKUPINA-B|2
3|polozka3|SKUPINA-B|1
4|polozka4| - | - (čtvrtá položka nepatří do žádné skupiny)

A potřeboval bych pomocí jednoho SQL dotazu dostat seznam všech položek, ale tak aby jméno položky obsahovalo i jméno skupiny, tedy výsledek by měl být:

1 polozka1 (skupinova-polozka1a)
2 polozka2 (skupinova-polozka2b)
3 polozka3 (skupinova-polozka1b)
4 polozka4

SQL:
SELECT polozka.id, polozka.jmeno,
skupinaA.id as skupinaAid, skupinaA.jmeno as skupinaAjmeno,
skupinaB.id as skupinaBid, skupinaB.jmeno as skupinaBjmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno


Potřeboval bych do toho SQL dát podmínku, že když má položka skupinu v tabulce SKUPINA-A tak ať se hledá název skupiny tam a když má položka skupinu v tabulce SKUPINA-B tak ať se bere název skupiny tady a když nemá skupinu ani tam ani tam, tak ať zůstane jméno skupiny prázdný

něco jako:
CASE polozka.skupina-tabulka = SKUPINA-A THEN LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id
ELSE IF polozka.skupina-tabulka = SKUPINA-B THEN LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id
ELSE žádnej LEFT JOIN ...

Kdyby tomu někdo rozuměl a měl nápad jak vytvořit tento dotaz, byl bych mu vděčnej. Díky moc, Honza
TomášK
Profil
Pokud tabulky SKUPINA-A a SKUPINA-B obsahují stejné sloupce, pak z toho udělej jednu tabulku (id, jmeno, skupina). Ale možná si jen ostatní vynechal kvůli zjednodušení?
Zkus to takhle:
SELECT polozka.id, polozka.jmeno,
IF(skupinaA.id IS NOT NULL, skupinaA.jmeno, skupinaB.jmeno) AS skupina_jmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno
Alphard
Profil
ještě by asi šlo něco ve smyslu
left join (select * from SKUPINA-A union all select * from SKUPINA-B) t

ale co bude rychlejší nevím
H13
Profil
TomášK
Ano, struktura druhé tabulky je jiná, je to zjednodušený

TomášK
Alphard
bohužel v obou případech dostávám NULL :-(

Pokud nechám:
SELECT polozka.id, polozka.jmeno,
skupinaA.id as skupinaAid, skupinaA.jmeno as skupinaAjmeno,
skupinaB.id as skupinaBid, skupinaB.jmeno as skupinaBjmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno

pak ty data dostanu, jen v případě, kdy skupina není prázdná, dostanu prostě oba dva výsledky (jak ze skupiny A, tak i z B :-( )
TomášK
Profil
bohužel v obou případech dostávám NULL :-(

Kde dostáváš NULL? Můj dotaz (pokud jsem neudělal chybu, nezkoušel jsem ho) vrací:
1 polozka1 (skupinova-polozka1a)
2 polozka2 (skupinova-polozka2b)
3 polozka3 (skupinova-polozka1b)
4 polozka4 (NULL)

Je tohle to NULL, které ti vadí nebo to vrací něco jiného? Napadá mě, že může být problém s tím, že nepoužívám agregační funkci v místě, kde by být měla (i když zrovna MySQL ji strikně nevyžaduje a nějaký řádek vždy vrátí) a chová se to jinak než si myslím.
H13
Profil
TomášK
Omlouvám se, zapomněl jsem si zapnout debug (takže ne nulový výsledek), ale:
1054 - Unknown column 'skupinaA.jmeno'

EDIT - tak to byl překlep u mě, takže teď to funguje, jen ale dostávám ve skupina_jmeno položky z tabulky SKUPINA-A pro položky tabulky SKUPINA-B... :-(
TomášK
Profil
Koukám, že chyba byla odhalena rychleji než jsem stihl dopsat příspěvek :)
H13
Profil
No, ale ještě mi to blbne, viz předchozí EDIT:

EDIT - tak to byl překlep u mě, takže teď to funguje, jen ale dostávám ve skupina_jmeno položky z tabulky SKUPINA-A pro položky tabulky SKUPINA-B... :-(

v konkrétním příkladě tedy:

3 polozka3 (skupinova-polozka1a)

místo

3 polozka3 (skupinova-polozka1b)

Když to obrátím, tedy z:
IF(skupinaA.id IS NOT NULL, skupinaA.jmeno, skupinaB.jmeno) AS skupina_jmeno
na:
IF(skupinaB.id IS NOT NULL, skupinaB.jmeno, skupinaA.jmeno) AS skupina_jmeno

tak je to naopak... prostě to bere pouze z jedný tabulky (hodnotu pro skupina_jmeno) :-(
Alphard
Profil
Ano, struktura druhé tabulky je jiná, je to zjednodušený
Vycházel jsem z toho, že je stejná, nevím, jestli zase zjednodušujete, ale jestli nejsou potřeba další sloupce, mohlo by fungovat

left join (select id, jmeno from SKUPINA-A union all select id, jmeno from SKUPINA-B) t

prostě abychom srovnali sloupce

a jaký dotaz tam máte teď? nějak se v tom ztrácím

IF(skupinaA.id IS NOT NULL, skupinaA.jmeno, skupinaB.jmeno) AS skupina_jmeno

stejně nebude fungovat, protože skupina může být null, tohle může být A, nebo B, ale ne NULL
když už podmínkovat, tak se to bude asi muset zanořit (nebo dvě podmínky spojit jinak)
H13
Profil
Teď mám tento dotaz:

SELECT polozka.id, polozka.jmeno,
IF(skupinaA.id IS NOT NULL, skupinaA.jmeno, skupinaB.jmeno) AS skupina_jmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno


a vypíše:
1 polozka1 (skupinova-polozka1a)
2 polozka2 (skupinova-polozka2b)
3 polozka3 (skupinova-polozka1a)
4 polozka4

místo:
1 polozka1 (skupinova-polozka1a)
2 polozka2 (skupinova-polozka2b)
3 polozka3 (skupinova-polozka1b)
4 polozka4

tedy nerozlišuje mezi tabulkami, prostě bere hodnotu jen z jedný tabulky, pokud jde o stejný ID

EDIT:
tohle bude asi špatná podmínka:
skupinaA.id IS NOT NULL
protože se může stát, že v druhý tabulce toto id existuje také
Alphard
Profil
tohle by mělo jít, ale návrh tabulek se mi nelíbí

SELECT polozka.id, polozka.jmeno, t.jmeno
FROM POLOZKA as polozka 
LEFT JOIN (select id, jmeno, 'SKUPINA-A' s from `SKUPINA-A` union all select id, jmeno, 'SKUPINA-B' s from `SKUPINA-B`) t on polozka.`skupina-id` = t.id and t.s = polozka.`skupina-tabulka`
ORDER BY polozka.jmeno
H13
Profil
Alphard
Za t.jmeno dostávám všude NULL :-(

Zatím mě to funguje takto (ale zkouším to pouze s 5 řádkama, takže nevím co to udělá s případnýma kombinacema):

SELECT polozka.id, polozka.jmeno, polozka.skupina-tabulka
IF(polozka.skupina-tabulka = 'SKUPINA-A', skupinaA.jmeno, skupinaB.jmeno) AS skupina_jmeno,
IF(polozka.skupina-tabulka = 'SKUPINA-B', skupinaB.jmeno, skupinaA.jmeno) AS skupina_jmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno
Alphard
Profil
H13:
nevím, mně to jde (nevidím do vašeho nezjednodušeného příkladu), tohle je výpis, který dostanu

1	polozka1	skupinova-polozka1a
2	polozka2	skupinova-polozka2b
3	polozka3	skupinova-polozka1b
4	polozka4	NULL


ale jestli vám to jde, tak OK, aspoň vám doporučím přejmenovat ty tabulky, mě to v phpMinAdminovi nevzalo SKUPINA-A, ale až `SKUPINA-A`
i jestli vám to teď jde, tak riskujete do budoucna
H13
Profil
Ještě jsem udělal drobnou kosmetiku (IF jsem vyměnil za CASE):

SELECT polozka.id, polozka.jmeno, polozka.skupina-tabulka
CASE WHEN polozka.skupina-tabulka = 'SKUPINA-A' THEN skupinaA.jmeno
WHEN polozka.skupina-tabulka = 'SKUPINA-B' THEN skupinaB.jmeno END AS skupina_jmeno
FROM POLOZKA as polozka 
LEFT JOIN SKUPINA-A AS skupinaA ON polozka.skupina-id = skupinaA.id 
LEFT JOIN SKUPINA-B AS skupinaB ON polozka.skupina-id = skupinaB.id 
GROUP BY polozka.id
ORDER BY polozka.jmeno


BTW: Název 'SKUPINA-A' jsem zvolil pouze jako příklad zde, abych nějak oddělil jména tabulek od jmen sloupců (ale stejnak jsem to zamotal, protože jsem zde uvedl stejný hodnoty pro jméno tabulky a hodnotu ve sloupci skupina-tabulka :-( ), jinak samozřejmě takovej název tabulky nemám...

Podívám se ještě na ten tvůj dotaz, možná tam zase dělám nějakej překlep :-(

Každopádně díky moc za rady, Honza


Alphard

EDIT: Tak opravdu jsem se zase překlepl, jede to:

SELECT polozka.id, polozka.jmeno, t.jmeno
FROM POLOZKA as polozka 
LEFT JOIN (select id, jmeno, 'SKUPINA-A' s from `SKUPINA-A` union all select id, jmeno, 'SKUPINA-B' s from `SKUPINA-B`) t on polozka.`skupina-id` = t.id and t.s = polozka.`skupina-tabulka`
ORDER BY polozka.jmeno


ještě jednou díky moc
Toto téma je uzamčeno. Odpověď nelze zaslat.