Autor Zpráva
gaminn
Profil *
Zdravím,

mám tabulku se státy:

ID NAME
1 ČR
2 SR

a tabulku s městy

ID ID_STATU NAME STATUS
1 1 Praha 1
2 1 Brno 2
3 1 Ostrava 0
4 1 Plzeň 0
5 2 Košice 0
6 2 Trenčín 3


A nyní chci pomocí jednoho dotazu vybrat všechny státy, k nim přiřadit počet všech jejich měst, které k nim patří a dále potom jedno město, které má status = 1, pokud není město se statusem 1, potom chci město, které má status = 2, pokud to není, chci město se status = 3. (pokud město s nenulovým statusem není (popř není vůbec žádné město), může být jako hodnota vráceno NULL)

Pokud je to možné, neptejte se, k čemu to potřebuji, proč mají města nějaký status apod. Je to jen výmysl, který si potom analogicky převedu na své tabulky.

Díky
gaminn
Profil *
Až nyní jsem si všimnul, že můj požadavek není zobrazen celý (chtělo by tuto chybu opravit, už se mi to stalo několikrát), tak tedy:

A nyní chci pomocí jednoho dotazu vybrat všechny státy, k nim přiřadit počet všech jejich měst, které k nim patří a dále potom jedno město, které má status = 1, pokud není město se statusem 1, potom chci město, které má status = 2, pokud to není, chci město se status = 3. (pokud město s nenulovým statusem není (popř není vůbec žádné město), může být jako hodnota vráceno NULL)

Pokud je to možné, neptejte se, k čemu to potřebuji, proč mají města nějaký status apod. Je to jen výmysl, který si potom analogicky převedu na své tabulky.
Kajman_
Profil *
Asi se zase něco schovalo, nebo se to v tom minulém neschovalo, vypadá to stejně.

No a sql implementací je spousta, zkuste být příště konkrétnější o kterou z nich (a v jaké verzi) se zajímáte.

select s.name stat, count(*) mest, m1.name mesto
from staty s
left join mesta m1 on s.id=m1.id_statu
left join mesta m2 on (m1.status=0 and m1.id=m2.id) or (m1.id_statu=m2.id_statu and (m2.status>0 and m1.status>m2.status or (m1.status=m2.status and m1.id>m2.id)))
left join mesta m3 on s.id=m3.id_statu
where m2.id is null
group by s.id, s.name, m1.name
union
select s.name stat, count(*) mest, null mesto
from staty s
left join mesta m1 on s.id=m1.id_statu
group by s.id, s.name
having ifnull(max(m1.status),0)=0
order by 1
gaminn
Profil *
No tak tomu se říká dotaz;) Díky moc, ale asi bude nad mé síly ho pochopit.

Byl tam jenom drobný zádrhel: where m2.id is null jsem změnil na where m2.id is not null (vracelo to město s nejnižším statusem, já jsem chtěl ten nejvyšší)
Kajman_
Profil *
where m2.id is not null

No, to asi fungovat nebude :-) V popisu jste psal, že menší mají přednost. Pro otočení je třeba změnit m1.status>m2.status na m1.status<m2.status.
gaminn
Profil *
Já vlastně ani nevím, co chci - je to tak, že chci vypsat město s nejmenším nenulovým statusem, pokud jsou u státu města jen s nulovým statusem, nechci žádné město. Takže to fungovalo dobře, nevím, co jsem zmatkoval.

Udělal jsem si ještě jeden dotaz, který by měl konat stejnou funkci:

SELECT s.name, COUNT( m.id ) , (

SELECT name
FROM mesta
WHERE STATUS = (

SELECT MIN( STATUS )
FROM mesta
WHERE id_statu = s.id
AND STATUS >0

)
AND id_statu = s.id
LIMIT 1
)

FROM mesta AS m
LEFT JOIN staty AS s ON s.id = m.id_statu
GROUP BY m.id_statu


Zdá se, že funguje a je mnohem rychlejší (0.0006s proti 0.0033s), navíc ho chápu (jestli to nebude tím, že jsem ho napsal sám;)). Můžete říct, okme odborníka, jestli je v pořádku?
Kajman_
Profil *
No, právě proto jsem lamentoval, že nenapíšete db ani verzi... tak jsem to napsal pro starou mysql.

Řešení s poddotazy je asi stravitelnější :-) Ale takhle tam nebudete mít státy, které nemají žádné město.
gaminn
Profil *
No teď už to je k ničemu, je to MySQL 5.0;)

Státy bez měst se nemusí zobrazit - budu to aplikovat na jiné tabulky, kde to takto bude žádoucí.
Toto téma je uzamčeno. Odpověď nelze zaslat.

0