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/
Select col1, min(col2)
from tabela
group by col1
order by 1, 2
--
wloochacz
>
> 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
>
> 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
> 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.
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
> 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
>> 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
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ń