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)

Předmět Autor Datum
a jaku chybu?
MM.. 06.09.2012 18:06
MM..
V sql syntaxi. Abych z toho nedělal drama. Mám tabulku, která obsahuje několik sloupců. Jeden ze s…
Flash_Gordon 06.09.2012 18:08
Flash_Gordon
No a jaky bol problem s tym prvym SQL prikazom? (zameral by som sa skor na to)
MM.. 06.09.2012 20:44
MM..
No :-). Provést se provede, ale zobrazí emaily duplicitně (jakoby tam DISTINCT vůbec nebyl). Zabil…
Flash_Gordon 06.09.2012 20:54
Flash_Gordon
To ale potom zacni od zakladu, SELECT DISTINCT neco FROM neco a neco nech je len jeden stlpec, ne…
MM.. 06.09.2012 21:04
MM..
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

No :-).

Provést se provede, ale zobrazí emaily duplicitně (jakoby tam DISTINCT vůbec nebyl).

Zabil jsem s tím tolik času, kdybych to věděl, tak by mě vyšlo efektivněji udělat to na programové vrstvě ručně.

Pokud někoho nenapadne přímé řešení v sql, budu to řešit na pracnější a pomalejší aplikační vrstvě.

To ale potom zacni od zakladu,

SELECT DISTINCT neco FROM neco

a neco nech je len jeden stlpec, ne 3 naraz. Funguje? urcite ano, a potom pridavaj az zistis kedy sa to posere...
Ja nie som moc na SQL takze to co mas v dotaze je na mna uz moc :D Ale toto jednoduche IMHO fungovat musi, a potom na to pridavaj dalsie veci

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