Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Select DISTINCT - po jednej kolumnie (delphi/firebird)

375 views
Skip to first unread message

mirekk36

unread,
Feb 4, 2009, 10:53:14 AM2/4/09
to
Witam,

próbuję zrobić takie zapytanie:

Select Distinct (col1), col2 from tabela

col1 - zawiera pola powtarzające się, które chcę wyeliminować tym zapytaniem
col2 zawiera pola o róznych wartościach

niestety u mnie to Distinct odnosi się tak jakby w zapytaniu także do col2

col1 | col2
-------------
0001 | ala
0001 | ola
0002 | marek
0003 | ula

chciałbym uzyskać z powyższej tabelki:

0001 ala
0002 marek
0003 ula

a niestety uzyskuję:

0001 | ala
0001 | ola
0002 | marek
0003 | ula

coś chyba źle kombinuję z tym distinct czy jak?

używam Delphi 2006 oraz Firebird 2.1


--
Wysłano z serwisu Usenet w portalu Gazeta.pl -> http://www.gazeta.pl/usenet/

wloochacz

unread,
Feb 4, 2009, 11:09:17 AM2/4/09
to
mirekk36 pisze:
/ciach/

Select col1, min(col2)
from tabela
group by col1
order by 1, 2

--
wloochacz

mirekk36

unread,
Feb 4, 2009, 11:33:20 AM2/4/09
to
wloochacz <nospam.w...@nospam.dgbit.pl> napisał(a):

>
> Select col1, min(col2)
> from tabela
> group by col1
> order by 1, 2
>

bardzo dziękuję, zadziałało pięknie jak chciałem. Sprawdziłem sobie szybko
jak działają funkcje min, max a przy okazji rozjaśniło mi się wykorzystanie
group by.

tak więc rozumiem już jak to działa (jestem początkujący w SQLu więc sorry)
ale dopytam -

1. czy Distinct też nadaje się do tego typu zapytań?
2. czy Distinct w takich przypadkach eleiminuje duplikaty tylko gdy
wszystkie pola w porównywanych rekordach są równe (z tego wynika że chyba
tak)

3. zakładając jednak, że moja TABELA ma 50 kolumn to do każdej kolumny
musiałbym zastosować te funkcje min() - jak sprawdziłem, ale czy jest jakiś
może jeszcze inny prostszy sposób ? bo ten select dosyć rozbudowany chciałem
używać w widoku gdzie pola są budowane za pomocą nawet kilku zagnieżdżonych
poleceń coalesce i przy łączeniu kilku tabel typu left join. Ale jeśli
trzeba to powstawiam wszędzie to min()

pozdrawiam Mirek

mirekk36

unread,
Feb 4, 2009, 12:37:52 PM2/4/09
to
wloochacz <nospam.w...@nospam.dgbit.pl> napisał(a):

>
> Select col1, min(col2)
> from tabela
> group by col1
> order by 1, 2
>

hmmm niestety w takim bardziej skomlikowanym zapytaniu np:

select
col1,
min(coalesce(t2.col2, t1.col3)) as WYNIK)
from Table as t1
left join table1 as t2 on ( t2.col1 = t1.col1 )

już nie da rady użyć funkcji MIN() w takim przypadku jak powyżej :(

generalnie ten select (widok) ma zwracać rekordy po złożeniu pól z kilku
tabel gdzie po drodze występuje taki warunek WHERE że dla Distinct'a właśnie
pewne pole składane za pomocą coalesce ma różne wartości

eeeeh wiem trochę to zakręcone ale muszę obojętnie czy za pomocą widoku czy
za pomocą zwykłego zapytania osiągnąć dosyć dla mnie początkującego
skomplikowany efekt i mam ciężki orzech do zgryzienia

cut

unread,
Feb 4, 2009, 12:49:46 PM2/4/09
to
mirekk36 pisze:

> eeeeh wiem trochę to zakręcone ale muszę obojętnie czy za pomocą widoku czy
> za pomocą zwykłego zapytania osiągnąć dosyć dla mnie początkującego
> skomplikowany efekt i mam ciężki orzech do zgryzienia
>
>

może napisz dokładnie co chcesz osiągnąć, będzie łatwiej Ci pomoc bo być
może od zlej strony próbujesz.

wloochacz

unread,
Feb 4, 2009, 2:08:45 PM2/4/09
to
mirekk36 pisze:

> wloochacz <nospam.w...@nospam.dgbit.pl> napisał(a):
>
>> Select col1, min(col2)
>> from tabela
>> group by col1
>> order by 1, 2
>>
>
> hmmm niestety w takim bardziej skomlikowanym zapytaniu np:
>
> select
> col1,
> min(coalesce(t2.col2, t1.col3)) as WYNIK)
> from Table as t1
> left join table1 as t2 on ( t2.col1 = t1.col1 )
>
> już nie da rady użyć funkcji MIN() w takim przypadku jak powyżej :(
Na oko, to jest źle napisane, powinno być tak:
select
t1.col1,
min(coalesce(t2.col2, t1.col3)) as WYNIK

from Table as t1
left join table1 as t2 on (t2.col1 = t1.col1)
group by t1.col1
order by 1, 2

Piszę z palca, ale powinno zadziałać bez problemów.

> generalnie ten select (widok) ma zwracać rekordy po złożeniu pól z kilku
> tabel gdzie po drodze występuje taki warunek WHERE że dla Distinct'a właśnie
> pewne pole składane za pomocą coalesce ma różne wartości

Nie ma problemu - to jest tylko wyrażenia, więc powinno działać.

> eeeeh wiem trochę to zakręcone ale muszę obojętnie czy za pomocą widoku czy
> za pomocą zwykłego zapytania osiągnąć dosyć dla mnie początkującego
> skomplikowany efekt i mam ciężki orzech do zgryzienia

Być może, a być może nie.
Jak słyszę, że tam jet 50 kolumn, dane mają taką strukturę jak
narysowałeś, a chcesz uzyskać to co opisałeś - to mi to zalatuje złym
projektem bazy.

--
wloochacz

mirekk36

unread,
Feb 4, 2009, 3:58:27 PM2/4/09
to
wloochacz <wloo...@nospam.dgbit.spameromnie.pl> napisał(a):


> Na oko, to jest źle napisane, powinno być tak:
> select
> t1.col1,
> min(coalesce(t2.col2, t1.col3)) as WYNIK
> from Table as t1
> left join table1 as t2 on (t2.col1 = t1.col1)
> group by t1.col1
> order by 1, 2
>
> Piszę z palca, ale powinno zadziałać bez problemów.

no i rzeczywiście zadziałało a mój błąd polegał na tym, że nawias funkcji
MIN zamknąłem za wyrażeniem "as WYNIK" .... teraz jest OK


> Być może, a być może nie.
> Jak słyszę, że tam jet 50 kolumn, dane mają taką strukturę jak
> narysowałeś, a chcesz uzyskać to co opisałeś - to mi to zalatuje złym
> projektem bazy.
>

no może 50 kolumn to przesada ale policzyłem dokładnie i jest ich 25.
Pewnie, że baza może być źle zaprojektowana i zapewne można zrobić to lepiej
ale to moje początki początków. I tak już nieco lepiej niż przy pierwszym
podejściu do tej bazy jakieś 2 miesiące temu. W całej tej bazie jest tylko
taka jedna tabela mająca tyle kolumn - to rekordy zawierające dane odnośnie
wysyłanych i odbieranych przez system wiadomości typu SMS. Większość tych
kolumn to pewne statusy, które później w gridzie są wykorzystywane do
prezentacji bieżącego stanu. Oczywiście też istnieje kilka tabel z
wzajemnymi powiązaniami .... no ale ciężko by było ot tak nagle wszystko tu
tłumaczyć.

Domniemuję tylko, że taki sposób jaki podał kolega wloochacz nie jest jakimś
ekstremalnym rozwiązaniem tylko normalnie przyjętym w takich sytuacjach ?

pozdrawiam

wloochacz

unread,
Feb 4, 2009, 4:26:34 PM2/4/09
to
mirekk36 pisze:

> wloochacz <wloo...@nospam.dgbit.spameromnie.pl> napisał(a):
>
>
>> Na oko, to jest źle napisane, powinno być tak:
>> select
>> t1.col1,
>> min(coalesce(t2.col2, t1.col3)) as WYNIK
>> from Table as t1
>> left join table1 as t2 on (t2.col1 = t1.col1)
>> group by t1.col1
>> order by 1, 2
>>
>> Piszę z palca, ale powinno zadziałać bez problemów.
>
> no i rzeczywiście zadziałało a mój błąd polegał na tym, że nawias funkcji
> MIN zamknąłem za wyrażeniem "as WYNIK" .... teraz jest OK
Wiem o tym...

>> Być może, a być może nie.
>> Jak słyszę, że tam jet 50 kolumn, dane mają taką strukturę jak
>> narysowałeś, a chcesz uzyskać to co opisałeś - to mi to zalatuje złym
>> projektem bazy.
>>
>
> no może 50 kolumn to przesada ale policzyłem dokładnie i jest ich 25.
> Pewnie, że baza może być źle zaprojektowana i zapewne można zrobić to lepiej
> ale to moje początki początków. I tak już nieco lepiej niż przy pierwszym
> podejściu do tej bazy jakieś 2 miesiące temu. W całej tej bazie jest tylko
> taka jedna tabela mająca tyle kolumn - to rekordy zawierające dane odnośnie
> wysyłanych i odbieranych przez system wiadomości typu SMS. Większość tych
> kolumn to pewne statusy, które później w gridzie są wykorzystywane do
> prezentacji bieżącego stanu. Oczywiście też istnieje kilka tabel z
> wzajemnymi powiązaniami .... no ale ciężko by było ot tak nagle wszystko tu
> tłumaczyć.

Takie dane:


col1 | col2
-------------
0001 | ala
0001 | ola
0002 | marek
0003 | ula

I takie fiku miku, jakie chciałeś są wewnętrznie sprzeczne.
Dla mnie bardziej logicznym rozwiązaniem by było użycie funkcji LIST,
czyli tak:

select
t1.col1,
LIST(coalesce(t2.col2, t1.col3), ';') as WYNIK


from Table as t1
left join table1 as t2 on (t2.col1 = t1.col1)
group by t1.col1
order by 1, 2

Ale to tylko zgadywanka z mojej strony...

> Domniemuję tylko, że taki sposób jaki podał kolega wloochacz nie jest jakimś
> ekstremalnym rozwiązaniem tylko normalnie przyjętym w takich sytuacjach ?

He, he; żart polega na tym, że nie wiadomo jaka to sytuacja. Ale wierz
mi - to przedszkole w zastosowaniu SQLa; może kiedyś będziesz
zastanawiał się co oznacza PLAN zapytania, a może nie ;-)

--
wloochacz

Adam Siwoń

unread,
Feb 4, 2009, 4:40:47 PM2/4/09
to
mirekk36 pisze:

> wloochacz <wloo...@nospam.dgbit.spameromnie.pl> napisał(a):
>
>
>> Na oko, to jest źle napisane, powinno być tak:
>> select
>> t1.col1,
>> min(coalesce(t2.col2, t1.col3)) as WYNIK
>> from Table as t1
>> left join table1 as t2 on (t2.col1 = t1.col1)
>> group by t1.col1
>> order by 1

tyle chyba wystarczy - wartości w kolumnie 1 się raczej nie powtórzą,
więc 2 w order by jest raczej zbyteczna. ;)

[...]


>> Być może, a być może nie.
>> Jak słyszę, że tam jet 50 kolumn, dane mają taką strukturę jak
>> narysowałeś, a chcesz uzyskać to co opisałeś - to mi to zalatuje złym
>> projektem bazy.
>
> no może 50 kolumn to przesada ale policzyłem dokładnie i jest ich 25.
> Pewnie, że baza może być źle zaprojektowana i zapewne można zrobić to lepiej
> ale to moje początki początków. I tak już nieco lepiej niż przy pierwszym
> podejściu do tej bazy jakieś 2 miesiące temu. W całej tej bazie jest tylko
> taka jedna tabela mająca tyle kolumn - to rekordy zawierające dane odnośnie

ilość kolumn to nie problem. Tabela może mieć i sto kolumn, jeśli ma to
uzasadnienie w logice aplikacji. Problem leży w odpowiednim przydziale
kolumn do tabeli i prawidłowym ułożeniu relacji między tymi tabelami.
Poczytaj trochę o normalizacji baz danych to Ci będzie łatwiej.

> Domniemuję tylko, że taki sposób jaki podał kolega wloochacz nie jest jakimś
> ekstremalnym rozwiązaniem tylko normalnie przyjętym w takich sytuacjach ?

Generalnie nie jest. Tylko nie napisałeś tak do końca co chcesz uzyskać
w przypadku tej większej ilości kolumn. Bo jak zadasz zapytanie tak:
select
t1.col1,
min(t1.col2),
min(t1.col3)
from Table as t1

to dostaniesz sieczkę minimalnych wartości pól tabeli pogrupowanych po
pierwszym polu a nie wartości z konkretnego rekordu.

--
z pozdrowieniami
Adam Siwoń

0 new messages