Próbowałem wyszukiwać posty, ale znalazłem tylko rozwiązania dla SQL Server / Access. Potrzebuję rozwiązania w MySQL (5.X).
Mam tabelę (zwaną historią) z 3 kolumnami: hostid, nazwa elementu, wartość przedmiotu.
Jeśli zrobię select ( select * from history
), zwróci
+--------+----------+-----------+
| hostid | itemname | itemvalue |
+--------+----------+-----------+
| 1 | A | 10 |
+--------+----------+-----------+
| 1 | B | 3 |
+--------+----------+-----------+
| 2 | A | 9 |
+--------+----------+-----------+
| 2 | c | 40 |
+--------+----------+-----------+
Jak zapytać bazę danych, aby zwrócić coś takiego
+--------+------+-----+-----+
| hostid | A | B | C |
+--------+------+-----+-----+
| 1 | 10 | 3 | 0 |
+--------+------+-----+-----+
| 2 | 9 | 0 | 40 |
+--------+------+-----+-----+
Odpowiedzi:
Dodam nieco dłuższe i bardziej szczegółowe wyjaśnienie kroków, które należy podjąć, aby rozwiązać ten problem. Przepraszam, jeśli to za długo.
Zacznę od bazy, którą podałeś, i użyję jej do zdefiniowania kilku terminów, których użyję do końca tego postu. To będzie tabela bazowa :
To będzie nasz cel, ładna tabela przestawna :
Wartości w
history.hostid
kolumnie staną się wartościami Y w tabeli przestawnej. Wartości whistory.itemname
kolumnie staną się wartościami x (z oczywistych powodów).Kiedy muszę rozwiązać problem związany z tworzeniem tabeli przestawnej, rozwiązuję ten problem, stosując trzyetapowy proces (z opcjonalnym czwartym krokiem):
Zastosujmy te kroki do twojego problemu i zobaczmy, co otrzymamy:
Krok 1: wybierz interesujące kolumny . W pożądanym wyniku
hostid
podaje wartości y iitemname
podaje wartości x .Krok 2: przedłuż tabelę podstawową o dodatkowe kolumny . Zwykle potrzebujemy jednej kolumny na wartość x. Przypomnijmy, że nasza kolumna wartości x to
itemname
:Pamiętaj, że nie zmieniliśmy liczby wierszy - po prostu dodaliśmy dodatkowe kolumny. Zwróć również uwagę na wzorzec
NULL
s - wiersz zitemname = "A"
ma wartość inną niż null dla nowej kolumnyA
i wartości null dla innych nowych kolumn.Krok 3: grupuj i agreguj tabelę rozszerzoną . Musimy to zrobić
group by hostid
, ponieważ zapewnia wartości y:(Pamiętaj, że teraz mamy jeden wiersz na wartość y). Dobra, już prawie jesteśmy! Musimy tylko pozbyć się tych brzydkich
NULL
.Krok 4: upiększ . Zamierzamy po prostu zastąpić dowolne wartości zerowe zerami, aby zestaw wyników był ładniejszy:
I gotowe - zbudowaliśmy ładną, ładną tabelę przestawną za pomocą MySQL.
Uwagi dotyczące stosowania tej procedury:
itemvalue
w tym przykładzieNULL
, ale może to być0
lub""
, w zależności od twojej dokładnej sytuacjisum
, alecount
imax
często też jest używany (max
jest często używany podczas budowania jednorzędowych „obiektów”, które zostały rozmieszczone w wielu rzędach)group by
klauzuli (i nie zapomnij oselect
nich)Znane ograniczenia:
źródło
źródło
group by
.MAX
zamiastSUM
ponieważ mojeitemValue
są ciągami, a nie wartościami liczbowymi.Inną opcją, szczególnie przydatną, jeśli masz wiele elementów, które musisz przestawić, jest pozwolenie mysqlowi zbudować zapytanie:
FIDDLE Dodano kilka dodatkowych wartości, aby zobaczyć, jak działa
GROUP_CONCAT
ma domyślną wartość 1000, więc jeśli masz naprawdę duże zapytanie, zmień ten parametr przed jego uruchomieniemTest:
źródło
'ifnull(SUM(case when itemname = ''',
pomocą''' then itemvalue end),0) AS
„,” do'SUM(case when itemname = '''
z''' then itemvalue else 0 end) AS ',
. Dane wyjściowe takie jakSUM(case when itemname = 'A' then itemvalue else 0 end) AS 'A'
.Korzystając z pomysłu Matta Fenwicka, który pomógł mi rozwiązać problem (wielkie dzięki), zredukujmy go do jednego zapytania:
źródło
I EDIT Agung Sagita „s odpowiedź od podzapytaniu się przyłączyć. Nie jestem pewien, jak duża różnica między tym 2 sposobem, ale tylko dla innego odniesienia.
źródło
użyj podkwerendy
ale będzie to stanowić problem, jeśli zapytanie podrzędne będzie skutkowało więcej niż wierszem, użyj dalszej funkcji agregującej w podzapytaniu
źródło
Moje rozwiązanie:
Daje oczekiwane wyniki w przedłożonej sprawie.
źródło
Robię
Group By hostId
to, aby wyświetlać tylko pierwszy wiersz z wartościami,takimi jak:
źródło
Wymyślam jeden sposób, aby moje raporty przekształcały wiersze w kolumny prawie dynamiczne za pomocą prostych zapytań. Możesz to zobaczyć i przetestować online tutaj .
Liczba kolumn zapytania jest stała, ale wartości są dynamiczne i oparte na wartościach wierszy. Możesz go zbudować Tak więc używam jednego zapytania do zbudowania nagłówka tabeli, a drugiego do wyświetlenia wartości:
Możesz to także streścić:
Wyniki RexTester :
http://rextester.com/ZSWKS28923
Dla jednego prawdziwego przykładu zastosowania, ten raport poniżej pokazuje w kolumnach godziny odlotów przylotów łodzi / autobusu z graficznym harmonogramem. Zobaczysz jedną dodatkową kolumnę, która nie zostanie użyta w ostatniej kolumnie bez pomylenia wizualizacji: ** system biletowy do sprzedaży biletów online i prezentacyjnych
źródło
Jeśli możesz użyć MariaDB, istnieje bardzo bardzo proste rozwiązanie.
Od MariaDB-10.02 dodano nowy silnik pamięci o nazwie CONNECT, który może pomóc nam przekonwertować wyniki innego zapytania lub tabeli na tabelę przestawną, dokładnie tak, jak chcesz: możesz zajrzeć do dokumentacji .
Przede wszystkim zainstaluj silnik pamięci masowej Connect .
Teraz kolumna przestawna naszej tabeli jest,
itemname
a dane dla każdego elementu znajdują się witemvalue
kolumnie, dzięki czemu możemy uzyskać wynikową tabelę przestawną za pomocą tego zapytania:Teraz możemy wybrać, co chcemy z
pivot_table
:Więcej informacji tutaj
źródło
Nie jest to dokładna odpowiedź, której szukasz, ale było to rozwiązanie, którego potrzebowałem w moim projekcie i mam nadzieję, że to komuś pomoże. Spowoduje to wyświetlenie pozycji od 1 do n wierszy oddzielonych przecinkami. Group_Concat umożliwia to w MySQL.
Ten cmentarz ma dwie wspólne nazwy, więc nazwy są wymienione w różnych wierszach połączonych jednym identyfikatorem, ale dwa identyfikatory nazw, a zapytanie tworzy coś w rodzaju tego
CemeteryID Cemetery_Name Latitude
1 Appleton, Sulpher Springs 35.4276242832293
źródło
Przykro mi to mówić i być może nie rozwiązuję dokładnie problemu, ale PostgreSQL jest o 10 lat starszy od MySQL i jest bardzo zaawansowany w porównaniu do MySQL i istnieje wiele sposobów na osiągnięcie tego z łatwością. Zainstaluj PostgreSQL i wykonaj to zapytanie
wtedy voila! A oto obszerna dokumentacja: PostgreSQL: Dokumentacja: 9.1: tablefunc lub to zapytanie
potem znowu voila! PostgreSQL: Dokumentacja: 9.0: hstore
źródło