Zadałem tutaj pytanie: /programming/43807566/how-to-divide-two-values-from-the-same-column-but-at-different-rows
o dzieleniu wartości z tej samej tabeli, w tej samej kolumnie, ale w różnych wierszach. Teraz mam problem polegający na tym, że mam więcej liczników i mianowników (z różnymi uns
). Czy nadal self join
jest dobrym sposobem na rozwiązanie tego problemu w Postgres, czy są lepsze rozwiązania?
Przykład:
| postcode | value | uns |
|----------|-------|-----|
| AA | 40 | 53 |
| BB | 20 | 53 |
| AA | 10 | 54 |
| AA | 20 | 55 |
| AA | 10 | 56 |
| AA | 30 | 57 |
| AA | 50 | 58 |
| BB | 10 | 54 |
| BB | 10 | 55 |
| BB | 70 | 56 |
| BB | 80 | 57 |
| BB | 10 | 58 |
Wynik powinien być:
| postcode | formula |
|----------|------------|
| AA | 18.888... |
| BB | 14.375 |
Gdzie wartości są pogrupowane według kodu pocztowego, a formuła jest (wartość z uns):
(V53 * V56 + V54 * V57 + V55 * V58) / (V56 + V57 + V58)
Zwracanie uwagi, aby uniknąć ewentualnego podziału przez zero. Formuła może być jeszcze bardziej złożona, ale to dobry przykład.
postgresql
pivot
computed-column
Randomize
źródło
źródło
uns
stały się nazwami kolumn - stamtąd, niezależnie od użytej formuły, wartości powinny stać się wykonalne. Czy formuła zostanie zakodowana na stałe, czy będzie dynamicznie uzyskiwana w jakiś sposób?Odpowiedzi:
Jest to problem związany z przestawieniem / przestawieniem , tak jak u Michaela już dokładnie zdiagnozowano .
Jeśli nie znasz
tablefunc
modułu Postgres, przeczytaj podstawowe instrukcje tutaj:Zapytanie staje się proste i bardzo szybkie (szybsze niż inne przedstawione tutaj rozwiązania):
NULLIF
aby zapobiec podziałowi przez zero.dbfiddle tutaj
źródło
Możesz agregować wszystkie pary uns / value w obiekt JSON, a następnie użyć go, aby uzyskać dostęp do wartości UNS według nazwy. Wymaga to rzutowania, ponieważ wartości można wyodrębnić tylko jako tekst z obiektu JSON, ale wówczas formuła wygląda bardzo podobnie do opisu:
Agregację, ocenę mianownika i dzielnika podzieliłem na trzy etapy, aby uczynić je bardziej czytelnymi.
Przykład online: http://rextester.com/IZYT54566
Możesz uprościć formułę, tworząc funkcję:
źródło
Wzorzec PIVOT działałby w tym celu. Konwertuje wartości wierszy na kolumny w jednym rzędzie, zgodnie z ich wspólnym kluczem. Istnieje kilka sposobów na wdrożenie tego. Niektóre wymagają tylko jednego skanowania tabeli.
Po PIVOT masz tabelę z jednym wierszem na kod pocztowy i kolumną na wartość. Pozostała część zapytania byłaby zapisana tak, jakby odwoływała się do pojedynczej tabeli.
źródło
Zakładając, że
(postcode, uns)
sąUNIQUE
(prawdopodobnie PK), wzorzec PIVOT, jak już skomentował @ michael-green, można zaimplementować przenośnie za pomocą następującego zapytania:Sprawdź to na SQLFiddle .
źródło
Zakładając, że
(postcode, uns)
są toUNIQUE
(prawdopodobnie PK), prawdopodobnie najprostszy , prawdopodobnie najbardziej przenośny, choć prawdopodobnie nie optymalny: użyj tyle podselekcji, ile potrzeba :Sprawdź w SQLFiddle .
źródło