Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Wybierz wiersze MYSQL, ale wiersze w kolumny i kolumny w wiersze

Przy stałych i znanych kolumnach, oto jak to zrobić (ja pozwoliłem nazwać tabelę „oceny”):

Pomysł ogólny:

Aby utworzyć połączenie różnych zapytań i je wykonać.

Ponieważ potrzebujesz rzeczywistych danych jako nagłówków kolumn, pierwsza część unii będzie wyglądać następująco:

SELECT 'id', '1', '2', ....

Samo to zapytanie zduplikuje wynik, dlatego musimy poinformować MySQL, że potrzebujemy 0 wierszy, dodając LIMIT 0, 0 .

Nasz pierwszy wiersz unii będzie zawierał 'Name' , a także wszystkie dane z kolumny „Nazwa” tabeli. Aby uzyskać tę linię, potrzebujemy zapytania takiego jak:

SELECT 'Name',
    (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT Name FROM grades LIMIT 1, 1),
    (SELECT Name FROM grades LIMIT 2, 1),
    ...

Używając tej samej logiki, nasz drugi wiersz będzie wyglądał tak:

SELECT 'Marks',
    (SELECT Marks FROM grades LIMIT 0, 1),
    (SELECT Marks FROM grades LIMIT 1, 1),
    (SELECT Marks FROM grades LIMIT 2, 1),
    ...

Pobieranie nagłówka:

Musimy utworzyć wiersz z MySQL, taki jak:

SELECT 'id', '1', '2', ... LIMIT 0, 0;

Aby uzyskać tę linię, użyjemy CONCAT() i GROUP_CONCAT() funkcje:

SELECT 'id', 
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades)
LIMIT 0, 0;

i zapiszemy tę linię w nowej zmiennej:

SET @header = CONCAT('SELECT \'id\', ',
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades),
    ' LIMIT 0, 0');

Tworzenie linii:

Musimy utworzyć dwa zapytania, takie jak:

SELECT 'Name',
    (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT Name FROM grades LIMIT 1, 1),
    (SELECT Name FROM grades LIMIT 2, 1),
    ...

Ponieważ nie wiemy z góry, ile wierszy znajduje się w naszej oryginalnej tabeli, użyjemy zmiennych do wygenerowania różnych LIMIT x, 1 sprawozdania. Można je wyprodukować w następujący sposób:

SET @a = -1;
SELECT @a:[email protected]+1 FROM grades;

Korzystając z tego fragmentu kodu, możemy tworzyć nasze podzapytania:

SELECT GROUP_CONCAT(
    CONCAT(' (SELECT name FROM grades LIMIT ',
        @a:[email protected]+1,
        ', 1)')
    )
FROM grades

Którą wstawimy do zmiennej o nazwach @line1, wraz z danymi pierwszej kolumny (która jest nazwą drugiej kolumny):

SET @a = -1;
SET @line1 = CONCAT(
    'SELECT \'Name\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Name FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

Postępując zgodnie z tą samą logiką, drugi wiersz będzie wyglądał następująco:

SET @a := -1;
SET @line2 = CONCAT(
    'SELECT \'Marks\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Marks FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

Łącząc je wszystkie:

Nasze trzy zmienne zawierają teraz:

@header:
SELECT 'id',  '1', '2' LIMIT 0, 0

@line1:
SELECT 'Name', (SELECT Name FROM grades LIMIT 0, 1),
    (SELECT name FROM grades LIMIT 1, 1)

@line2:
SELECT 'Marks', (SELECT Marks FROM grades LIMIT 0, 1),
    (SELECT marks FROM grades LIMIT 1, 1)

Musimy tylko utworzyć końcową zmienną za pomocą CONCAT() , przygotuj je jako nowe zapytanie i wykonaj:

SET @query = CONCAT('(',
    @header,
    ') UNION (',
    @line1,
    ') UNION (',
    @line2,
    ')'
);

PREPARE my_query FROM @query;
EXECUTE my_query;

Całe rozwiązanie:

(do testowania i odniesienia):

SET @header = CONCAT('SELECT \'id\', ',
    (SELECT GROUP_CONCAT(CONCAT(' \'', id, '\'')) FROM grades),
    ' LIMIT 0, 0');

SET @a = -1;
SET @line1 = CONCAT(
    'SELECT \'Name\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Name FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

SET @a := -1;
SET @line2 = CONCAT(
    'SELECT \'Marks\',',
    (
        SELECT GROUP_CONCAT(
            CONCAT(' (SELECT Marks FROM grades LIMIT ',
                @a:[email protected]+1,
                ', 1)')
            )
        FROM grades
    ));

SET @query = CONCAT('(',
    @header,
    ') UNION (',
    @line1,
    ') UNION (',
    @line2,
    ')'
);

PREPARE my_query FROM @query;
EXECUTE my_query;

Wyjście:

+-------+------+-------+
| id    | 1    | 2     |
+-------+------+-------+
| Name  | Ram  | Shyam |
| Marks | 45   | 87    |
+-------+------+-------+
2 rows in set (0.00 sec)

Myśli końcowe:

  • Nadal nie jestem pewien, dlaczego musisz przekształcić wiersze w kolumny, i jestem pewien, że przedstawione przeze mnie rozwiązanie nie jest najlepsze (pod względem wydajności).

  • Możesz nawet użyć mojego rozwiązania na początek i dostosować je do rozwiązania ogólnego przeznaczenia, w którym nazwy kolumn tabeli (i liczba wierszy) nie są znane, używając information_schema .COLUMNS jako źródło, ale myślę, że to po prostu za daleko.

  • Mocno wierzę, że znacznie lepiej jest umieścić oryginalną tabelę w tablicy, a następnie ją obrócić, uzyskując w ten sposób dane w pożądanym formacie.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL - Jak przeanalizować wartość ciągu do formatu DATETIME wewnątrz instrukcji INSERT?

  2. Jak zastosować paginację do wyniku zapytania SHOW TABLES w PHP

  3. Parsowanie bardzo dużych plików XML w php

  4. Pinguj serwer MySQL

  5. Jak wybrać najnowszy zestaw datowanych rekordów z tabeli mysql?