» »

SQL poizvedba z DISTINCT

SQL poizvedba z DISTINCT

shorvat ::

Lep pozdrav,

v bazi imam podvojene podatke in bi rad naredil izpis brez teh podvojenih podatkov (podvojeni ali potrojeni bi se izpisali 1x). Problem se mi pojevi, ker imam v bazi ločeno polje za ime in priimek. Primer:

BAZA:

id | ime | priimek | posta
-------------------------------------------------------
1 | janez | kovac | ljubljana
2 | marko | horvat | ptuj
3 | janez | kovac | ljubljana


rad bi, da bi mi izpisalo samo dve imeni: "janez kovac" in "marko horvat"! Se pravi da rabim stavek, kjer bo paramete DISTINCT uporabljen 2x!

Hvala!

shorvat ::

aja, uporabljam MySQL!

Poldi112 ::

Nimam vec nobenega mysql da bi preiskusil, ampak na postgres to dela:
select distinct * from kontakti;
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

shorvat ::

Niso čisto vsi podatki enaki v tabeli. Še enkrat tabela malo drugače:

id | ime | priimek | posta | tel |
-------------------------------------------------------
1 | janez | kovac | ljubljana | 031/345/675
2 | marko | horvat | ptuj | 040/454/545
3 | janez | kovac | ljubljana | 031-345-675

DavidJ ::

Tukaj.

Kaj takega nisem se nikoli rabil, poskusi s tem: "select id, distinct name, distinc priimek, distinct posta, tel from ..."

Ce ne bo slo pa malo potelovadi s PHP-jem pri izpisu.
"Do, or do not. There is no 'try'. "
- Yoda ('The Empire Strikes Back')

Poldi112 ::

Mislim da to ne bo slo.
Zal verjetno ne bo slo tudi to, ker ni cisto po sql standardu, lahko pa poiskusis:
select distinct on (ime,posta) ime, priimek, posta from test;
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

Reso ::

Za mssql vem da bi šlo nekako takole:

SELECT * FROM kontakti WHERE Id IN (SELECT MAX(id) FROM kontakti GROUP BY ime, priimek, posta)

Če je sintaktično pravilno ne vem čisto točno ampak jaz bi na tak način naredil. Drugače pa se lahko take malenkosti popravi znotraj programa.

frudi ::

zdaj ne vem, ali tvoj problem razumem čisto narobe, ampak če ga ne, bi šlo (v mssql) takole:
SELECT DISTINCT ime, priimek FROM tabela

DISTINCT ne deluje na celotni tabeli ali posameznih stolpcih, ampak na setu podatkov, ki jih izbereš (v tem primeru na kombinaciji ime/priimek)
1ACDoHVj3wn7N4EMpGVU4YGLR9HTfkNhTd... in case I've written something useful :)

krho ::

frudi NI RES DISTINCT je za celo vrstico po standardu in PIKA. Razen, če baza podpira DISTINCT ON (col1, col2)
si.Mail odprto-kodni odjemalec elektronske pošte. - http://www.simail.si
Uredite si svojo zbirko filmov, serij in iger - http://xcollect.sf.net

mercutio ::

Krho:
Tako kot je frudi napisal v MS SQL sigurno dela. Pa v Oraclu tudi. Zdej za standarde ne vem točno. Imaš morda kakšen link?

krho ::

Ok. Da malce popravim.
frudijev SQL vrne samo 2 stolpca (ime, priimek), shorvat pa rabi celo vrstico.
recimo SELECT DISTINCT ime, priimek, posta FROM tabela, potem naredi distinct nad tremi stolpci.
Če rabiš DISTINCT samo nad dolečenimi stolpci , tako kot ga rabi shorvat potem rabiš podporo za DISTINCT ON
si.Mail odprto-kodni odjemalec elektronske pošte. - http://www.simail.si
Uredite si svojo zbirko filmov, serij in iger - http://xcollect.sf.net

Zgodovina sprememb…

  • spremenil: krho ()

frudi ::

aha, šele zdaj sem opazil, da sta telefonski številki za en osebek vpisani drugače...

ni panike, naredi takole (to deluje v mssql)

SELECT ime, priimek, MIN(posta) AS posta, MIN(tel) AS tel
FROM tabela
GROUP BY ime, priimek


krho, kako pa bi z DISTINCT ON (ime, priimek) baza ve, katere poste in tel vrnit? če deluje tako kot si predstavljam, verjetno deluje enako, kot zgornji select?
1ACDoHVj3wn7N4EMpGVU4YGLR9HTfkNhTd... in case I've written something useful :)

shorvat ::

Ta zdanji post mi je pomagal, hvala vsem za odgovore!

krho ::

Oracle in Postgres mislim, da podpirata DISTINCT ON, druge baze pa mislim, da ne.

Kako deluje pa nimam pojma, verjetno pa podobno kot tvoj zadnji SQL. Jaz sem imel podoben problem kot shorvat, mislim, da sem ga potem rešil s redesignom.
si.Mail odprto-kodni odjemalec elektronske pošte. - http://www.simail.si
Uredite si svojo zbirko filmov, serij in iger - http://xcollect.sf.net

Zgodovina sprememb…

  • spremenil: krho ()

zdravc ::

Za pojasnilo kako deluje DISTINCT:

To je grupna funkcija, ki deluje na skupini podatkov, navedenih za ukazom. Prikaze samo razlicne kombinacije vrednosti (seveda po zapisih) iz navedene skupine podatkov. Za razliko od ostalih grupnih funkcij se ne uporablja skupaj z ostalimi, saj je njen namen samo to, da prikaze samo razlicne vrednosti.

Za resitev problema je tako frudi dal pravilno resitev. Ukaz distinct bi se uporabil samo v primeru, ko bi npr. rabil izpis vseh razlicnih imen in priimkov v primeru da se v bazi ponavljajo. Ce rabis zraven se kateri od ostalih podatkov se mora uporabi ukaz group by in katere od grupnih funkcij.

Vendar pa tudi ta resitev ne da pravilnega rezultata ce sta npr. ista ime in priimek zapisana veckrat z razlicno posto ali telefonom. S tem izgubimo informacijo, da ima npr. Janez Novah dva razlicna telefona.
Ce pa rabimo samo enega (vseeno katerega) potem pa je resitev pravilna.
kdor zna pa žih

Zgodovina sprememb…

  • spremenil: zdravc ()

Poldi112 ::

Ce te prav razumem se motis. Pri distinct on se doda poleg polj, ki naj jih prikaze, se polja po katerih naj izvaja distinct. Tako da lahko izpises vse, distinct bo pa izvajal samo po izbranih in bos dobil isto kot frudi s tem:

select distinct on (ime,priimek) ime, priimek, posta, telefon from tabela;

Me je pa presentilo delovanje group by. Vsak dan nekaj novega :)
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

zdravc ::

Jaz sicer nikoli ne uporabljam dodatka ON, mislim da sploh ni potreben (Oracle), vendar na tak nacin se nisem poskusil. Do sedaj sem distinct uporabljal samo za primere, ko sem rabil samo razlicne vrednosti iz mnozice zapisov in to samo razlicnih polj. Ce sem rabil na vseh poljih neke tabele, sem pac nastel vsa polja.

Vendar tvoj primer ni logicen. Select vedno vrne vse vrstice in, ce ne uporabis katere od grupnih funkcij na ostalih poljih, potem bo vedno vrnil vse zapise zaradi teh ostalih polj in sam distinct sploh ni potreben.
kdor zna pa žih

frudi ::

distinct je v bistbu že v osnovi napačna izbira za ta konkreten primer. distinct ali distinct on (ime, priimek) bi bila uporabna samo, če bi bile celotne vrstice (razen idja) podvojene. ker tukaj niso (telefon je za janeza kovaca dvakrat vnesen drugače), bi distinct kakorkoli bi ga že (zlo)rabil, vedno vrnil oba zapisa.
pri takih primerih se uporabi group by z nekim (od situacije odvisnim) kriterijem, kako izbrati eno od razlikujočih polj (v tem primeru tel). v tem primeru je najenostavneje kar z MIN ali MAX, lahko bi pa tudi napisal kako funkcijo, ki 'počisti' telefonsko številko znakov, ki niso cifre, oziroma jih zamenja z enotnim znakom. v tem primeru bi deloval že recimo REPL(tel, '/', '-'), potem pa lahko z DISTINCT ali GROUP BY izložiš podvojene zapise.
1ACDoHVj3wn7N4EMpGVU4YGLR9HTfkNhTd... in case I've written something useful :)

Poldi112 ::

Moj primer da popolnoma enak rezultat kot frudijeva resitev (samo da je njegova bolj standardna/univerzalna).

Grupira ti distinct, s tem da ti distinct on omogoca grupiranje samo na izbranih poljih in ne na vseh kot distinct (kar je pomembno, ce ne zelis da se ti ponavlja telefon oz. posta pri istem cloveku).
Where all think alike, no one thinks very much.
Walter Lippmann, leta 1922, o predpogoju za demokracijo.

zdravc ::

Bom preveril v sluzbi na Oracle-u to varianto z ON.

Je pac tako, da vse ne moremo vedeti. Hvala.
kdor zna pa žih


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

[SQL] Unikatni izpisi

Oddelek: Programiranje
212061 (1448) 111111111111
»

SQL-DML pomoč

Oddelek: Programiranje
5934 (757) JackCola
»

podatkovna baza

Oddelek: Programiranje
51919 (1740) scarymovie
»

[mysql] malo bolj zahtevna poizvedba

Oddelek: Programiranje
161518 (1369) destiny
»

v accessu slaba baza podatkov

Oddelek: Programiranje
81185 (1016) baksuz

Več podobnih tem