Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: zliczanie wartości pól
Forum PHP.pl > Forum > Bazy danych > PostgreSQL
xdriverspl
witam, mam tabele

grupa | ilosc
gr1 | 3
gr2 | 2
gr3 | 6
gr1 | 2
gr2 | 4

chciałbym aby w wyniku zapytania otrzymać

gr1 | 5
gr2 | 6
gr3 | 6

jest jakis operator zliczajacy wartosci pol dla danej grupy? koniecznie wartosci nie ilosc tj w przypadku COUNT(*)
mortus
SUM
Sephirus
  1. SELECT grupa, SUM(ilosc) AS laczna_ilosc FROM tabela
  2. GROUP BY grupa ORDER BY grupa ASC


tak BTW - nie "ilosc" a "liczba" - wyraz ilość stosujemy do rzeczy "niepoliczalnych" smile.gif - wiem wiem czepiam się wink.gif
xdriverspl
dzięki smile.gif a tak przy okazji...

jakieś funkcje które policzą mi w kolejnej kolumnie procent z całości?
mmmmmmm
Mnóstwo. Począwszy od wartosc/SUM(Wartosc), na funkcjach WINDOW skończywszy.
xdriverspl
a jakieś przykłady? wertuje dokumentacje i nie natrafiłem narazie na nic sensownego

chciałbym aby w wyniku zapytania otrzymać

gr1 | 5|29.41
gr2 | 6|35.29
gr3 | 6|35.29

kolumna 1 - grupa
kolumna 2 - ilosc w grupie
kolumna 3 - udział procentowy
Sephirus
Można to ogarnąć (najprościej IMO) podzapytaniem wybierającym sumę wszystkich z tabeli.

  1. SELECT grupa, SUM(ilosc) AS laczna_ilosc, (SUM(ilosc)/(SELECT SUM(ilosc) FROM tabela)*100) AS udzial FROM tabela
  2. GROUP BY grupa ORDER BY grupa ASC


EDIT: nie "srednia" a "udzial" tongue.gif
mmmmmmm
Sum w podselekcie z grupowaniem?? Nawet postgresa może to zarżnąć przy dużej ilości danych. Właśnie po to wymyślono funkcje WINDOW.
  1. WITH tabela AS
  2. (
  3. SELECT 'a' grupa, 5 ilosc
  4. UNION
  5. SELECT 'b', 6
  6. UNION
  7. SELECT 'c', 6
  8. )
  9. SELECT *, ilosc*100./sum(ilosc) over() FROM tabela
xdriverspl
Cytat(mmmmmmm @ 17.05.2013, 18:28:32 ) *
Sum w podselekcie z grupowaniem?? Nawet postgresa może to zarżnąć przy dużej ilości danych. Właśnie po to wymyślono funkcje WINDOW.
  1. WITH tabela AS
  2. (
  3. SELECT 'a' grupa, 5 ilosc
  4. UNION
  5. SELECT 'b', 6
  6. UNION
  7. SELECT 'c', 6
  8. )
  9. SELECT *, ilosc*100./sum(ilosc) over() FROM tabela



Ciekawe... a mozesz napisac co za co odpowiada?
mmmmmmm
WITH tabela AS
(
SELECT 'a' grupa, 5 ilosc
UNION
SELECT 'b', 6
UNION
SELECT 'c', 6
)
Ten fragment zastępuje tabelę - nie miałem danych, więc musiałem je jakoś spreparować. Jak widać tabela nazywa się "tabela" i ma dwa pola "grupa", "ilosc".

SELECT *, ilosc*100./sum(ilosc) over() FROM tabela
To wyświetla wszystkie pola - * i dodatkowo jedno pole wyrażone przez ilosc*100./sum(ilosc) over()
To pole to wartość pola "ilosc" razy (100.) - specjalnie z kropką na końcu, aby postgresql wiedział, że ma do czynienia z liczbą zmiennoprzecinkową. sum(ilosc) over() oblicza sumę pola ilosc dla WSZYSTKICH rekordów z tabeli. Musiałbyś doczytać co robi tak naprawdę OVER(), bo akurat tu jest proste - bez paraetrów. Może być np. sum(ilosc) over(partition by grupa order by grupa)... Ale dla sum jest to troche bez sensu. lepiej widać na rank().
xdriverspl
Cytat(mmmmmmm @ 19.05.2013, 19:43:16 ) *
WITH tabela AS
(
SELECT 'a' grupa, 5 ilosc
UNION
SELECT 'b', 6
UNION
SELECT 'c', 6
)
Ten fragment zastępuje tabelę - nie miałem danych, więc musiałem je jakoś spreparować. Jak widać tabela nazywa się "tabela" i ma dwa pola "grupa", "ilosc".

SELECT *, ilosc*100./sum(ilosc) over() FROM tabela
To wyświetla wszystkie pola - * i dodatkowo jedno pole wyrażone przez ilosc*100./sum(ilosc) over()
To pole to wartość pola "ilosc" razy (100.) - specjalnie z kropką na końcu, aby postgresql wiedział, że ma do czynienia z liczbą zmiennoprzecinkową. sum(ilosc) over() oblicza sumę pola ilosc dla WSZYSTKICH rekordów z tabeli. Musiałbyś doczytać co robi tak naprawdę OVER(), bo akurat tu jest proste - bez paraetrów. Może być np. sum(ilosc) over(partition by grupa order by grupa)... Ale dla sum jest to troche bez sensu. lepiej widać na rank().


niestety nie zabardzo to dziala...
mam taka tabele

grupa| ilosc
a | 2
a | 5
a | 6
b | 2
b | 5
b | 3
c | 1
c | 23
c | 3

a wynik potrzebuje:

grupa| procent z calosci kolumny
a | xxx
b | xxx
c | xxx

a w twoim zapytaniu nie zlicza calosci grupy jedna grupa wystepuje po kilka razy w wyniku
mmmmmmm
Najprostsza przeróbka to:
  1. SELECT *, ilosc*100./sum(ilosc) over() FROM (SELECT grupa, Sum(ilosc) ilosc FROM tabela GROUP BY 1) x
xdriverspl
Cytat(mmmmmmm @ 20.05.2013, 11:02:54 ) *
Najprostsza przeróbka to:
  1. SELECT *, ilosc*100./sum(ilosc) over() FROM (SELECT grupa, Sum(ilosc) ilosc FROM tabela GROUP BY 1) x


no ok ale sam pisales ze "...nawet postgresa moze to zarżnąć..."

dlatego dopytuje o bardziej zaawansowane funkcje..
mmmmmmm
Nie.
Pisałem o czymś takim:
  1. SELECT grupa, SUM(ilosc) AS laczna_ilosc, (SUM(ilosc)/(SELECT SUM(ilosc) FROM tabela)*100) AS udzial FROM tabela
  2. GROUP BY grupa ORDER BY grupa ASC

(o ile dobrze pamiętam to nazywa się zapytanie skorelowane)
Jak widzisz dla każdego rekordu jest liczone
  1. SELECT SUM(ilosc) FROM tabela
Wynik tego jest czynnikiem dzielenia i na końcu to jest grupowane i sumowane. Pewnie optymalizator zapytań poradziłby sobie z tym, ale nie zawsze i nie na każdej bazie.
Zresztą można to zamienić na takie zapytanie (jest równoważne):
  1. SELECT grupa, SUM(ilosc) AS laczna_ilosc, (SUM(ilosc)/razem*100) AS udzial FROM tabela, (SELECT SUM(ilosc) razem FROM tabela) x
  2. GROUP BY grupa ORDER BY grupa ASC

Ale tu już sposób liczenia jest zupełnie inny - polecam zobaczyć plan zapytania (w PgAdmin "F7") dla wszystkich trzech zapytań. Nie sprawdzałem (z ciekawości zaraz to zrobię), ale myślę, że różnica będzie kosmiczna...

xdriverspl
witam, dalej podrąże temat smile.gif

mam tabele:

id_kontrahenta | adres

zależy mi na tym aby wyciągnąć dane typu:

1 lokalizacja | 5 kontrahentów
2 lokalizacje | 15 lkontrahentów
3 lokalizacje | 5 kontrahentów

no i wpadłem na pomysł :

SELECT
COUNT(idkh) ilosc
FROM
lokalizacja
GROUP BY
idkh
ORDER BY
ilosc DESC
;

zapytanie pokazuje mozliwe wartości dla ilości lokalizacji...

dodałem

SELECT
COUNT(COUNT(idkh))

io nie działa..
mmmmmmm
A konkretnie to co chcesz zrobić?
  1. SELECT Sum(ilosc) FROM (SELECT Count(*) ilosc FROM lokalizacje GROUP BY idkh)x
xdriverspl
Cytat(mmmmmmm @ 5.06.2013, 16:39:49 ) *
A konkretnie to co chcesz zrobić?
  1. SELECT Sum(ilosc) FROM (SELECT Count(*) ilosc FROM lokalizacje GROUP BY idkh)x


Robię statystyki i mam tabele "lokalizacja" w tabeli m. in. kolumny: "id" "adres"..

i w 1 zapytaniu wypisuje ilóść lokalizacji danego "id" i z tym nie mam problemu..

W drugim muszę zrobić coś takiego że "pytam" smile.gif o ilość "id" które mają 0, 1, 2, 3, 4... lokalizacje..

czyli najpierw sprawdzam jakie są możliwości czyli są "id" mające 1, 3, 4, 5, 7, 11, 14 lokalizacji i bok musze jakoś uzyskać ilość ich wystąpień...

czyli np

ilość lokalizacji | ilość "id" które mają tyle lokalizacji
1 | 10
....
14 | 3
mmmmmmm
  1. SELECT ilosc, Count(*) FROM (SELECT idkh, Count(*) ilosc FROM lokalizacje GROUP BY idkh)x GROUP BY 1 ORDER BY 2 DESC
xdriverspl
Witam ponownie, mam takie oto zapytanie:

  1. SELECT idgrtow grupa , sum(ilosckont) Ilosc
  2. FROM zgloszenia
  3. WHERE idgrtow IS NOT NULL
  4. GROUP BY idgrtow
  5.  
  6. UNION ALL
  7.  
  8. SELECT idgrtow2 grupa , sum(ilosckont) Ilosc
  9. FROM zgloszenia
  10. WHERE idgrtow2 IS NOT NULL
  11. GROUP BY idgrtow2
  12. ORDER BY ilosc DESC
  13. ;


działa prawie tak jak tego chciałem, ale...

z pierwszej kolumny pobiera znaczniki grup oraz ilości a z drugiej zamiast dodawać do tych pierwszych wyników dodaje nowe rekordy...

wygląda to tak:

A 11 1sze zapytanie
B 2 1sze zapytanie
C 23 1sze zapytanie
A 2 2sze zapytanie
B 7 2sze zapytanie
C 45 2sze zapytanie

a powinno byc po prostu:

A 13 suma 1 i 2 zapytania
B 9 suma 1 i 2 zapytania
C 68 suma 1 i 2 zapytania
mmmmmmm
  1. SELECT grupa, Sum(ilosc) FROM (x) AS sub GROUP BY 1

Gdzie x to twoje zapytanie (bez order i srednika).
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2024 Invision Power Services, Inc.