Hej. Dawno już pracowałem z bazami danych a teraz mam drobny problem z wymyśleniem odpowiedniego zapytania SQL. Być może istnieje prostsze rozwiązanie, jednak w głowie pozostały same podstawy, dlatego mój problem wydaje mi się trochę nietypowy - w każdym bądź razie - może ktoś tutaj pomoże?
Załóżmy, że mamy jedną prostą tabelę "services" z kilkoma różnymi rekordami:
CREATE TABLE services (
service_id INT AUTO_INCREMENT KEY,
number_order INT,
name VARCHAR(100)
);
INSERT INTO services(number_order, name) VALUES (3, 'Trzecia usługa');
INSERT INTO services(number_order, name) VALUES (1, 'Pierwsza usługa');
INSERT INTO services(number_order, name) VALUES (2, 'Druga usługa');
INSERT INTO services(number_order, name) VALUES (6, 'Szósta usługa');
INSERT INTO services(number_order, name) VALUES (7, 'Siódma usługa');
INSERT INTO services(number_order, name) VALUES (13, 'Trzynasta usługa');
Teraz możemy wyświetlić zawartość tej tabeli, ale warunkiem jest została uporządkowana według kolejności pola "number_order" rosnąco oraz jego wartości do 10 włącznie:
SELECT service_id, number_order, name
FROM services
WHERE number_order <= 10
ORDER BY number_order ASC;
Wynik jest oczywisty:
| service_id |
number_order |
name |
| 2 |
1 |
Pierwsza usługa |
| 3 |
2 |
Druga usługa |
| 1 |
3 |
Trzecia usługa |
| 4 |
6 |
Szósta usługa |
| 5 |
7 |
Siódma usługa |
OK. Jednak chciałbym uzyskać wynikową tabelę zwracającą zawsze 10 rekordów. Czyli w przypadku powyższej bazy danych szukam odpowiedniej kwerendy zwracającej dokładnie poniższy wynik:
| number |
name |
| 1 |
Pierwsza usługa |
| 2 |
Druga usługa |
| 3 |
Trzecia usługa |
| 4 |
NULL |
| 5 |
NULL |
| 6 |
Szósta usługa |
| 7 |
Siódma usługa |
| 8 |
NULL |
| 9 |
NULL |
| 10 |
NULL |
To tak jakby ta tabela "sercives" w bazie danych była połączona z abstrakcyjną tabelą z rekordami od 1 do 10. Znalazłem takie coś:
WITH RECURSIVE cte (number)
AS (
SELECT 1
UNION ALL
SELECT number + 1
FROM cte
WHERE number < 10
)
To generuje wiersze od 1 do 10:
| number |
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
Może trzeba iść w tym kierunku, jak poniżej:
SELECT * FROM cte;
WITH RECURSIVE cte AS (
SELECT 1 AS number
UNION ALL
SELECT number + 1
FROM cte, services
WHERE cte.number = services.number_order
AND number < 10
)
SELECT * FROM cte;
Tyle, że w tym przypadku dostanę jedną kolumnę i co dziwne - tylko 4 rekordy:
Ma ktoś jakieś pomysły? Dodam, że technologia musi być kompatybilna z MySQL. Z góry dzięki. Pozdrawiam.
Powyższy przykład jest dostępny na tym linku SQLFiddle.