Michał Stanuch

Michał Stanuch Sales Menager, Metro
Group Poland, Real
sp. z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Witam,
Potrzebuję z tabeli wyciągnąć po 5największych wartości w każdej grupie

Tabela ma pola:
grupa, ilość, nazwa

z każdej grupy potrzebuję uzyskać po 5 największych wartości
tak żeby wyglądało to tak

grupa1 / top1 ilość / nazwa
grupa1 / top2 ilość / nazwa
grupa1 / top3 ilość / nazwa
grupa1 / top4 ilość / nazwa
grupa1 / top5 ilość / nazwa
grupa2 / top1 ilość / nazwa
grupa2 / top2 ilość / nazwa
grupa2 / top3 ilość / nazwa
grupa2 / top4 ilość / nazwa
grupa2 / top5 ilość / nazwa
i tak dalej

przeszukałem już wszystko i nic nie umiem znaleźć pomóżcie
Karol Kowalczyk

Karol Kowalczyk Programista, Marsh
Sp z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

2 kwerenry w stylu:

select top5 wartosc,.... from tbl order by wartosc desc

następnie union tych dwóch kwerend.
Michał Stanuch

Michał Stanuch Sales Menager, Metro
Group Poland, Real
sp. z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Nie do końca rozumię.
jakie 2 kwerendy?

mam tabelę połączoną z excela o nazwie smd
w tabeli jest kilka kolumn:
grupa / nazwa / ilość / wartość
wierszy jest ponad 90000
potrzebuję z każdej grupy jest ich około 50 zrobić tabelę lub kwerendę która pokaże tylko 5 największych wartości dla każdej grupy. wiem najpierw przesortować potem użyć TOP tylko jak bo nic mi nie wychodzi........
Karol Kowalczyk

Karol Kowalczyk Programista, Marsh
Sp z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Oki lepszy pomysł:
Coś na taki kształt bym wykorzystał

http://www.access.vis.pl/war007.htm


SELECT grupa,ilosc,nazwa (SELECT Count(*)
FROM smd As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa) AS LP, smd.nazwa, *
FROM tbl
WHERE ((((SELECT Count(*)
FROM tbl As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa))<6))
ORDER BY smd.ilosc DESC;



Przetwarzałem se z pewnej tabeli które struktura niech zostanie moja slodka tajemnicą wiec mogą być bledy skladniowe.Ten post został edytowany przez Autora dnia 19.02.14 o godzinie 22:19
Wojciech Muszyński

Wojciech Muszyński Tworzenie aplikacji
bazodanowych
(Oracle, APEX,
Access)

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Proponowałbym użycie funkcji DCount.

Składnia DCount (<pole>,<domena>,<warunek wyszukiwania>).

Warunek musi być dość skomplikowany i uwzględniać grupę i liczbę rekordów, dla których wartość pola "ilosc" jest większa od bieżącej.


select tblTABLICA.grupa,
tblTABLICA.ilosc,
tblTABLICA.nazwa,
"TOP " & DCount("*","tblTABLICA","[ilosc] >" & [ilosc] & " and grupa = '" & [grupa] & "'") + 1 as top_ilosc
from tblTABLICA
where DCount("*","tblTABLICA","[ilosc] >" & [ilosc] & " and grupa = '" & [grupa] & "'")<=4;



Dla największej ilości DCount da 0
dla drugiej z kolei da 1
dla 5 z kolei da 4
Dlatego porównanie jest <=4.

Ważny uwaga. Całość działa w sposób oczywisty, jeżeli ilości top 1 - do top 6 są różne.

W przeciwnym wypadku działa w ten sposób:
- jeżeli na pozycji 5 znajdą się X takie same wartości, to zwróci X rekordów TOP 5.
(dla X= 3 : top1, top2, top3, top4, top5, top5, top5)
- jeżeli na wcześniejszej pozycji będą takie same ilości, to zwróci mniej topów.
(np dla top3 są dwa rekordy, wtedy zwróci: top1, top2, top3, top3, top5).

Generalnie działa jak przydział medali przy miejscach ex aequo w sporcie dla "top 3":
1, 1, 3 albo 1, 2, 2 albo 1,1,3,3,3
Michał Stanuch

Michał Stanuch Sales Menager, Metro
Group Poland, Real
sp. z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Wielkie dzięki za wskazówki ale
Nie wiem dlaczego ale nie działa ........

select smd.grupa,
smd.ilosc,
smd.nazwa,
"TOP " & DCount("*","smd","[ilosc] >" & [ilosc] & " and grupa = '" & [grupa] & "'") + 1 as top_ilosc
from smd
where DCount("*","smd","[ilosc] >" & [ilosc] & " and grupa = '" & [grupa] & "'")<=4;
Zwraca kilkukrotnie NIEODPOWIEDNI TYP DANYCH W WYRAŻENIU KRYTERIUM i później "Błąd skladniowy (przecinek) w wyrażeniu kwerendy `[ilosc]>163,87 and grupa =`52". "

?????????

DRUGA

SELECT grupa,ilosc,nazwa (SELECT Count(*)
FROM smd As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa) AS LP, smd.nazwa, *
FROM smd
WHERE ((((SELECT Count(*)
FROM smd As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa))<6))
ORDER BY smd.ilosc DESC;

Niby wykonuje kwerendę ale żadnych efektów nie dzieje się nic

?????????????????
Wojciech Muszyński

Wojciech Muszyński Tworzenie aplikacji
bazodanowych
(Oracle, APEX,
Access)

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Jaki typ ma u Ciebie grupa?
U mnie w testach grupa to była zmienna znakowa.
Jeżeli u Ciebie grupa jest liczbą (podejrzewam autonumer) to zbędna staje się część związana z apostrofami.


Drugim problemem jest przecinek w liczbie ułamkowej. Prawdopodobnie Access "wrzucił" wartość z przecinkiem do kodu, który wymaga kropki. (testowałem na liczbach całkowitych).

Spróbuj jednego z dwóch rozwiązań,
Dla grupy typu znakowego:


select tblTABLICA.grupa,
tblTABLICA.ilosc,
tblTABLICA.nazwa,
"TOP " & DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = '" & [grupa] & "'") + 1 as top_ilosc
from tblTABLICA
where DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = '" & [grupa] & "'")<=4;



lub dla grupy typu liczbowego:


select tblTABLICA.grupa,
tblTABLICA.ilosc,
tblTABLICA.nazwa,
"TOP " & DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = " & [grupa] ) + 1 as top_ilosc
from tblTABLICA
where DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = " & [grupa] )<=4;



(tym razem nie sprawdzałem na bazie - więc mogą być literówki)Ten post został edytowany przez Autora dnia 20.02.14 o godzinie 21:24
Karol Kowalczyk

Karol Kowalczyk Programista, Marsh
Sp z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Utworzy sobie taka samą tabele w accesie(wszystkie kolumny text(255)):
grupa ilosc nazwa
a 1 aa1
a 4 aa2
a 6 aa3
a 1 aa4
a 45 aa5
a 21 aa6
a 21 aa7
a 125 aa8
b 21 aa9
b 54 aa10
b 34 aa11
b 34 aa12
b 32 aa13
b 2367 aa14
b 652 aa15
b 21 aa16
b 23 aa17
b 21 aa18
b 1253 aa19
b 12 aa20
c 342 aa21
c 12 aa22
c 21 aa23
c 2 aa24
c 21 aa25
c 21 aa26

Wkleiłem Twój kod:

SELECT grupa,ilosc,nazwa (SELECT Count(*)
FROM smd As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa) AS LP, smd.nazwa, *
FROM smd
WHERE ((((SELECT Count(*)
FROM smd As T1
WHERE T1.ilosc<=smd.ilosc and smd.grupa=T1.grupa))<6))
ORDER BY smd.ilosc DESC;


i otrzymałem:
grupa ilosc LP nazwa
c 21 5 aa26
c 21 5 aa25
c 21 5 aa23
b 21 5 aa18
b 21 5 aa16
b 21 5 aa9
a 21 5 aa7
a 21 5 aa6
c 2 2 aa24
b 1253 2 aa19
a 125 3 aa8
c 12 1 aa22
b 12 1 aa20
a 1 2 aa4
a 1 2 aa1

Wyślij mi na pw mail to Ci plik .accdb wyśle.Ten post został edytowany przez Autora dnia 21.02.14 o godzinie 02:01
Michał Stanuch

Michał Stanuch Sales Menager, Metro
Group Poland, Real
sp. z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Wojciech M.:
Jaki typ ma u Ciebie grupa?
U mnie w testach grupa to była zmienna znakowa.
Jeżeli u Ciebie grupa jest liczbą (podejrzewam autonumer) to zbędna staje się część związana z apostrofami.


Drugim problemem jest przecinek w liczbie ułamkowej. Prawdopodobnie Access "wrzucił" wartość z przecinkiem do kodu, który wymaga kropki. (testowałem na liczbach całkowitych).

Spróbuj jednego z dwóch rozwiązań,
Dla grupy typu znakowego:


select tblTABLICA.grupa,
tblTABLICA.ilosc,
tblTABLICA.nazwa,
"TOP " & DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = '" & [grupa] & "'") + 1 as top_ilosc
from tblTABLICA
where DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = '" & [grupa] & "'")<=4;[/quote]> [quote]


lub dla grupy typu liczbowego:


select tblTABLICA.grupa,
tblTABLICA.ilosc,
tblTABLICA.nazwa,
"TOP " & DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = " & [grupa] ) + 1 as top_ilosc
from tblTABLICA
where DCount("*","tblTABLICA","[ilosc] >" &replace ([ilosc],"," , ".") & " and grupa = " & [grupa] )<=4;[/quote]> [quote]


(tym razem nie sprawdzałem na bazie - więc mogą być literówki)

Działa bezbłędnie:
SELECT smd.grupa, smd.ilosc, smd.nazwa, "TOP " & DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa])+1 AS top_ilosc
FROM smd
WHERE (((DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa]))<=4))
ORDER BY smd.grupa, "TOP " & DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa])+1;
ale na małej bazie kilkanaście rekordów....
na tej którą muszę przerobić nie widać postępu....
Michał Stanuch

Michał Stanuch Sales Menager, Metro
Group Poland, Real
sp. z o.o.

Temat: POMOCY: Grupowanie po kilka najwyższych wartości dla...

Wykombinowałem coś takiego w excelu dla innej tabeli:
Najpierw sortowanie po grupa - jest wartością liczbową, później ilosc malejąco
dodałem kolejną kolumnę (N) z:
=JEŻELI(C2-C3=0;1;0) (i w dół) - w kolumnie C jest grupa zwraca 1 do czasu kiedy się nie zmieni wtedy 0
w kolejnej kolumnie (O)
=(O1+N2)*N2 (i w dół)
dodaje do wartości poprzedniego wiersza 1 aż do momentu kiedy grupa się zmieni wtedy mnoży przez 0 i liczy od nowa filtr wybieram 1,2,3,4,5 i mam TOP5 ilości w każdej grupie.
Działa i to całkiem nieźle nawet na ponad 20tys wierszy, alei tak potrzebuję to zrobić w accesie.

Rozwiązanie:
SELECT smd.grupa, smd.ilosc, smd.nazwa, "TOP " & DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa])+1 AS top_ilosc
FROM smd
WHERE (((DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa]))<=4))
ORDER BY smd.grupa, "TOP " & DCount("*","smd","[ilosc] >" & Replace([ilosc],",",".") & " and grupa = " & [grupa])+1;

dobrze działa przy małej ilości - usunąłem kilkanaście tys wierszy przy około 600 daje jeszcze wynik w normalnym czasie
przy 7tys wierszy już trwa to długo ale daje wynik około 5min
przy 9tys po 8min a baza ma około 60tys wierszy (po całej nocy nic..)

Następna dyskusja:

Pomocy w accsses ;&lt;




Wyślij zaproszenie do