Kawałek Kodu

Czy można wyczarować rekordy znikąd? Jasne! I to bez magicznej różdżki!

Zaczniemy od najprostszego zaklęcia, które wyczaruje nam 10 rekordów z wartościami od 0 do 9.

SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9

Trochę mało. Jak wygląda drugie zaklęcie?

SELECT a.a+b.a*10 FROM 
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS a
  CROSS JOIN
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS b

Tu czarujemy dwa razy. Pierwsze podzapytanie daje nam jedności, wartości drugiego zapytania pomnożone przez 10 i zsumowane z jednościami (CROSS JOIN oraz dodawanie), dają nam wartości od 0 do 99.

Nadal mało? Nic nie stoi na przeszkodzie, aby dodać trzecie podzapytanie (również połączone poprzez CROSS JOIN), a do wyrażenia dodać setki (liczby, a nie coś innego!). Wtedy wyrażenie przyjmie postać: a.a+b.a*10+c.a*100.

Co jednak w przypadku kiedy chcemy uzyskać tylko wycinek zakresu? Dodajemy magiczną klauzulę WHERE.

SELECT a.a+b.a*10 FROM 
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS a
  CROSS JOIN
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS b
WHERE (a.a+b.a*10)>=10 AND (a.a+b.a*10)<55

Rzucając to zapytanie otrzymamy liczby od 10 do 54.

Manipulując wyrażeniem głównego zapytania możemy otrzymywać inne kombinacje wartości, np: (a.a+b.a*10) MOD 2, da nam naprzemiennie 0 oraz 1.

Wszystko fajnie, a nawet za dużo. Dlaczego za dużo? Bo otrzymujemy zadaną liczbę rekordów, ale o różnych wartościach.
A jak otrzymać 50 takich samych wartości? Nie inaczej jak zaklęciem:

SELECT 9 FROM 
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS a
  CROSS JOIN
(SELECT 0 AS a UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) AS b
WHERE (a.a+b.a*10)<=49

W tym przypadku otrzymamy 50 dziewiątek.

Ponieważ chcemy otrzymać okrągłą liczbę rekordów, zapytanie można trochę uprościć. Podpowiem, że należy usunąć warunek oraz skrócić drugie podzapytanie. Podobnie możemy postąpić jeśli chcemy ograniczyć zbiór od dołu zaczynając od pełnej dziesiątki.

Czujesz się oczarowany?

 

Przydatne linki:
Plaga mrówek, czyli jak zmultiplikować rekordy zapytania