Miałem zadanie wymyślić sposób na przetłumaczenie następujących danych:
date category amount
1/1/2012 ABC 1000.00
2/1/2012 DEF 500.00
2/1/2012 GHI 800.00
2/10/2012 DEF 700.00
3/1/2012 ABC 1100.00
w następujący sposób:
date ABC DEF GHI
1/1/2012 1000.00
2/1/2012 500.00
2/1/2012 800.00
2/10/2012 700.00
3/1/2012 1100.00
Puste miejsca mogą mieć wartości NULL lub puste, albo jest w porządku, a kategorie musiałyby być dynamiczne. Innym możliwym zastrzeżeniem jest to, że będziemy uruchamiać kwerendę z ograniczoną pojemnością, co oznacza, że tabele tymczasowe są niedostępne. Próbowałem przeprowadzić badania i wylądowałem, PIVOT
ale ponieważ nigdy wcześniej tego nie używałem, naprawdę tego nie rozumiem, pomimo moich starań, aby to rozgryźć. Czy ktoś może skierować mnie we właściwym kierunku?
sql
sql-server
tsql
pivot
Sean Cunningham
źródło
źródło
Odpowiedzi:
Dynamiczna SQL PIVOT:
Wyniki:
źródło
@cols
możesz je usunąćDISTINCT
i użyć,GROUP BY
aORDER BY
kiedy otrzymasz listę@cols
.Dynamiczna SQL PIVOT
Inne podejście do tworzenia ciągu kolumn
Wynik
źródło
Wiem, że to pytanie jest starsze, ale szukałem odpowiedzi i pomyślałem, że mogę rozwinąć „dynamiczną” część problemu i być może komuś pomóc.
Przede wszystkim zbudowałem to rozwiązanie, aby rozwiązać problem, który miał kilku współpracowników z niestabilnymi i dużymi zestawami danych, które należy szybko przestawić.
To rozwiązanie wymaga utworzenia procedury składowanej, więc jeśli nie ma takiej potrzeby, proszę przestań czytać.
Ta procedura będzie obejmować kluczowe zmienne instrukcji przestawnej, aby dynamicznie tworzyć instrukcje przestawne dla różnych tabel, nazw kolumn i agregatów. Kolumna statyczna jest używana jako kolumna grupowania według / tożsamości dla elementu przestawnego (można go usunąć z kodu, jeśli nie jest to konieczne, ale jest dość powszechne w instrukcjach przestawnych i było konieczne do rozwiązania pierwotnego problemu), kolumna przestawna to miejsce, w którym końcowe kolumny wynikowe zostaną wygenerowane, a kolumna wartości jest tym, do czego agregat zostanie zastosowany. Parametr Table to nazwa tabeli zawierającej schemat (schema.tablename), w tej części kodu można by użyć trochę miłości, ponieważ nie jest ona tak czysta, jak bym tego chciał. Działa to dla mnie, ponieważ moje użycie nie było publicznie dostępne, a zastrzyk SQL nie był problemem.
Zacznijmy od kodu, aby utworzyć procedurę składowaną. Ten kod powinien działać we wszystkich wersjach SSMS 2005 i nowszych, ale nie testowałem go w 2005 ani 2016 roku, ale nie rozumiem, dlaczego to nie działa.
Następnie przygotujemy nasze dane do przykładu. Wziąłem przykład danych z zaakceptowanej odpowiedzi, dodając kilka elementów danych do wykorzystania w tym dowodzie koncepcji, aby pokazać różne wyniki łącznej zmiany.
Poniższe przykłady pokazują zróżnicowane instrukcje wykonania, pokazujące różne agregaty jako prosty przykład. Nie zdecydowałem się zmienić kolumny statycznej, przestawnej i wartościowej, aby zachować prosty przykład. Powinieneś być w stanie po prostu skopiować i wkleić kod, aby samemu z nim zadzierać
To wykonanie zwraca odpowiednio następujące zestawy danych.
źródło
Zaktualizowana wersja dla SQL Server 2017 przy użyciu funkcji STRING_AGG do utworzenia listy kolumn przestawnych:
źródło
Możesz to osiągnąć za pomocą dynamicznego TSQL (pamiętaj, aby użyć QUOTENAME, aby uniknąć ataków typu SQL injection):
Pivots z dynamicznymi kolumnami w SQL Server 2005
SQL Server - Dynamiczna tabela PIVOT - SQL Injection
Obowiązkowe odniesienie do Klątwy i błogosławieństw dynamicznego SQL
źródło
QUOTENAME
pomaga w atakach SQL injection tylko wtedy, gdy akceptujesz @tableName jako parametr od użytkownika i dołączasz go do zapytania takiego jakSET @sql = 'SELECT * FROM ' + @tableName;
. Możesz zbudować wiele wrażliwych dynamicznych ciągów SQL iQUOTENAME
nie zrobisz nic, by ci pomóc.Moje rozwiązanie usuwa niepotrzebne wartości zerowe
źródło
Poniższy kod przedstawia wyniki, które zastępują wartość NULL na zero na wyjściu.
Tworzenie tabeli i wstawianie danych:
Zapytanie w celu wygenerowania dokładnych wyników, które również zastępują NULL zerami:
WYNIK :
źródło