Přidat otázku mezi oblíbenéZasílat nové odpovědi e-mailemVyřešeno SQL dotaz

Nedaří se mi už delší dobu zkonstruovat dotaz.

Mám tabulku, která má několik sloupců.

A já chci vytáhnout všechny záznamy tak, aby podle jednoho konkrétního sloupce nebyly duplicity.

Na to lze použít distinct, ale nefungoval tak, jak jsem ho použil:

SELECT distinct (entry_state), address_book_id, entry_company FROM address_book group by entry_state WHERE entry_state NOT LIKE ' ' ORDER BY entry_company

bohužel distinct takto jednoduše nelze použít, protože v ostatních sloupcích jsou duplicity žádoucí.

Další nápad mám:

SELECT * FROM address_book WHERE entry_state NOT LIKE ' ' in (select entry_state FROM address_book GROUP BY entry_state HAVING count(entry_state)>1))

Hlasi chybu :-(
A navíc si uvědomuji, že tímto způsobem by se duplicity nezobrazili ani jednou a já chci duplicity zobrazit (ale jen 1x)

Jsou zobrazeny jen nové odpovědi. Zobrazit všechny
Předmět Autor Datum
za prve, group by nemoze byt pouzite pred where .... jednotlive klauzuly maju svoje poradie: 1. wher…
wam_Spider007 06.09.2012 21:10
wam_Spider007
select pole1, max(pole2), max(pole3), max(polex) from tabulka group by pole1; Dá se použít funkce m…
Flash_Gordon 06.09.2012 21:30
Flash_Gordon
ano, funkcia max ide pouzit aj na datumy aj na retazce. treba ale brat do uvahy, ze k danemu emailu…
wam_Spider007 06.09.2012 21:36
wam_Spider007
inak je to cele dost nezmyselne, lebo chces z niekolkych riadkov, ktore sa zhoduju len v jednom stlp…
Flash_Gordon 06.09.2012 21:47
Flash_Gordon
daj si na entry_state unique index a uz sa nepodari vlozit 2 riadky s rovnakym mailom :-D
wam_Spider007 06.09.2012 21:50
wam_Spider007
Díky, funguje. Ještě bych se chtěl zeptat, jaktože tu funkci max v tom dotazu vlastně používám na o…
Flash_Gordon 07.09.2012 08:48
Flash_Gordon
max je agregacna funkcia, rovnako ako min, avg, sum a podobne. cize z nejakej skupiny riadkov vyberi…
wam_Spider007 07.09.2012 10:16
wam_Spider007
Jjj. Zkusil jsem tam vynechat funkci max a funguje to i bez ní. Není tam tedy použítí max zbytečné?
Flash_Gordon 07.09.2012 10:37
Flash_Gordon
kde si vynechal tu funkciu max? Bez nej to ist urcite nemoze.
wam_Spider007 07.09.2012 13:59
wam_Spider007
A přece se točí. :-) Vypadá to takhle: SELECT entry_state,address_book_id as address_book_id, entr…
Flash_Gordon 07.09.2012 14:50
Flash_Gordon
No mas pravdu, teraz som si to vyskusal narychlo nasimulovat. Vyzera, ze to da do tych dalsich poli… poslední
wam_Spider007 07.09.2012 15:47
wam_Spider007

za prve, group by nemoze byt pouzite pred where ....
jednotlive klauzuly maju svoje poradie:
1. where
2. group by
3. having
4. order by

za druhe:
distinct robi to, ze ti zrusi duplicity konkretnych riadkov ako takych cize sa musia hodnoty zhodovat vo vsetkych zobrazovanych stlpcoch.

za tretie:
co tym chces dosiahnut? nejaky priklad dat by bodol. Lebo z tohto mam trochu dojem, ze hasis blbym dotazom este vacsiu blbost v datovom modeli.

inak ak chces zrusi duplicitu podla nejakeho stlpca a v ostatnych stlpcoch ti je jedno aka hodnota bude v ramci danej skupiny, tak takto:

select pole1, max(pole2), max(pole3), max(polex) from tabulka group by pole1;

pripadne:

select pole1, group_concat(pole2), group_concat(pole2), ... from tabulka group by pole1;

inak ten dotaz, ktory je tucnym je za prve syntakticky uplne zle a logicky totalna blbost.

select pole1, max(pole2), max(pole3), max(polex) from tabulka group by pole1;

Dá se použít funkce max na řetězce?
Nemůžu to teď vyzkoušet.

Tabulka se jmenuje address_book a má tyto sloupce:

address_book_id - jedinečné id
entry_state - text email
entry_company - text popis

A i když to vypadá kuriózně, některé firmy jsou zaregistrovány vícekrát pod stejným mailem, ale s trochu odlišným názvem.

No a potřebuju vytáhnout všechny maily takto:

SELECT distinct entry_state FROM address_book

Nicméně chci ke každému vytaženému mailu znát i address_book_id a entry_company, což uvedený dotaz pochopitelně nedělá.

ano, funkcia max ide pouzit aj na datumy aj na retazce. treba ale brat do uvahy, ze k danemu emailu dostanes vzdy len jeden udaj z danej skupiny.

preto je asi jedina moznost ten group_concat.
dostanes jeden riadok s danym mailom a k nemu v druhych stlpcoch vsetky hodnoty patriace danemu mailu oddelene ciarkou.
inak je to cele dost nezmyselne, lebo chces z niekolkych riadkov, ktore sa zhoduju len v jednom stlpci urobit 1 riadok. kam sa maju podiet tie ostatne hodnoty v stlpcoch z dalsich riadkov?

Nicméně chci ke každému vytaženému mailu znát i address_book_id a entry_company, což uvedený dotaz pochopitelně nedělá.

a co ak mas 3 riadky s mailom abc@abc.sk?
ktore address_book_id k nemu chces vytiahnut? z riadku c.1, alebo c.2 pripadne c.3? ak ktorekolvek, tak pouzi to max (pripadne min), ak vsetky, tak jedine group_concat. distinct je v tomto pripade uplne nanic. to by bolo dobre iba ak by si mal napriklad 2 rovnake riadky.

inak je to cele dost nezmyselne, lebo chces z niekolkych riadkov, ktore sa zhoduju len v jednom stlpci urobit 1 riadok. kam sa maju podiet tie ostatne hodnoty v stlpcoch z dalsich riadkov?

To je v pohodě.
Duplikace vznikly historicky tím, že se někdo netrpělivý registroval vícekrát a nezapamatoval si přesně co napsal předtím do popisu, a napsal to binárně jinak. :-) Takže je šumafuck, který z duplicitních popisů se přiřadí k adrese. Důležité jen je, aby každý vytažený řádek z db měl jiný email.

Zítra to vyzkouším, teď jdu spát.

Díky, funguje.

Ještě bych se chtěl zeptat, jaktože tu funkci max v tom dotazu vlastně používám na ostatní sloupce, když cílem je unikátní právě ten první sloupec.

Chtěl bych tomu rozumět.

Respektive co v tom dotazu se stará o to, aby vypadly shodné záznamy v prvním poli.

max je agregacna funkcia, rovnako ako min, avg, sum a podobne. cize z nejakej skupiny riadkov vyberie maximalnu hodnotu z daneho stlpca. kedze ale v selecte je este group by na stlpec s mailom, tak vyberie vzdy maximalnu hodnotu pre urcenu skupinu mailov.

priklad: mas tabulku T1 a v nej stlpec mail a cislo. v tabulke su 4 riadky nasledovne:

abc@abc.sk | 1
abc@abc.sk | 2
dfe@dfe.sk | 3
dfe@dfe.sk | 4

ak by som spravil select
select max(cislo) from t1;
vrati mi to len 4

ak ale dam select mail, max(cislo) from t1 group by mail;
vrati mi to
abc@abc.sk | 2
dfe@dfe.sk | 4

Inak napadol ma este jeden select pre to tvoje riesenie a to take, ze by vratil vzdy posledny registrovany riadok pre kazdy mail:

select address_book_id, entry_company, entry_state from address_book where address_book_id in (select max(address_book_id) from address_book group by entry_state);

No mas pravdu, teraz som si to vyskusal narychlo nasimulovat. Vyzera, ze to da do tych dalsich poli vzdy hodnoty z prveho riadku pre ten dany mail.
MySQL vie niekedy prekvapit, ale na 100% mozem povedat, ze Oracle alebo MS SQL by pri tomto zapise vyhlasil chybu, ze one 2 polia nie su agregovane nejakou agregacnou funkciou. Chlapci z MySQL si to ale asi spravili po svojom. Ale co cakat, ked je to zadarmo.

na okraj, nepouzivaj not like, na vyhodnocovanie je dost pomaly. Radsej daj entry_state <> ''

Zpět do poradny Odpovědět na původní otázku Nahoru