Potřebujete spojit dva a více sloupců textových řetězců v SQL? Seznamte se s funkcí SQL CONCAT, která umožňuje efektivně řetězit textové údaje.
Při práci s databázovými tabulkami se často stává, že potřebujeme spojit obsah několika textových sloupců dohromady, namísto získávání dat z jediného sloupce. To je obzvláště užitečné, když chceme dosáhnout výstupu, který je lépe srozumitelný a čitelnější.
Například, můžeme sloučit sloupce `first_name` a `last_name` a získat tak sloupec `full_name`. Podobně můžeme vytvořit `full_address` spojením sloupců s ulicí, městem, krajem a dalšími potřebnými údaji.
V SQL je funkce `CONCAT` nástrojem pro spojování řetězců. V tomto návodu si probereme:
- Základní syntaxi funkce SQL CONCAT
- Konkrétní příklady použití
- Postupy při práci s hodnotami NULL během řetězení sloupců
Začněme s popisem funkce!
Syntaxe funkce SQL CONCAT
Syntaxe pro použití funkce SQL `CONCAT` vypadá takto:
CONCAT(řetězec_1, řetězec_2, ..., řetězec_n);
Zde `řetězec_1`, `řetězec_2`, …, `řetězec_n` reprezentují textové řetězce, které chceme spojit. Mohou to být buď přímo zadané textové řetězce, názvy sloupců, nebo jejich kombinace.
Spojování textových řetězců pomocí CONCAT
Funkci `CONCAT` můžeme použít i pro spojování textových konstant (literálů), pojďme si ukázat jednoduchý příklad.
Zde spojujeme řetězce ‚Ahoj, ‚ a ‚světe!‘ do jednoho pozdravu:
SELECT CONCAT('Ahoj, ', 'světe!') AS pozdrav;
Výsledkem tohoto dotazu bude následující výstup:
+---------------+ |
| pozdrav | |
+---------------+ |
| Ahoj, světe! | |
+---------------+ |
1 řádek ve výsledku (0.00 sec) |
Nicméně v praxi budete pravděpodobně častěji spojovat sloupce tabulky, než konstantní texty. Podívejme se tedy na několik příkladů použití funkce `CONCAT` na data z databáze.
Jak spojovat sloupce v SQL
Nyní se zaměříme na práci s databázovou tabulkou.
📑 Všechny demonstrační dotazy jsou spouštěny na MySQL databázi. Nicméně můžete s klidem postupovat i s jiným RDBMS dle Vašeho výběru.
Vytvoření databázové tabulky se záznamy
Vytvořme si testovací databázi:
CREATE DATABASE db1;
use db1;
Nyní vytvoříme tabulku `employees` s informacemi o zaměstnancích. Tabulka bude obsahovat sloupce s uvedenými datovými typy:
CREATE TABLE employees ( ID INT AUTO_INCREMENT PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), street VARCHAR(100), city VARCHAR(50), state VARCHAR(2), username VARCHAR(20) );
Vložíme několik záznamů do tabulky `employees`:
INSERT INTO employees (first_name, last_name, street, city, state, username) VALUES ('Jan', 'Novák', 'Hlavní 123', 'Praha', 'PH', 'jan123'), ('Alena', 'Svobodová', 'Dlouhá 456', 'Brno', 'BO', 'alena456'), ('Petr', 'Černý', 'Krátká 789', 'Ostrava', 'OL', 'petr789'), ('Marie', 'Bílá', 'Zahradní 321', 'Plzeň', 'PL', 'marie456'), ('Josef', 'Modrý', 'Lesní 555', 'Liberec', 'LB', 'josef789'), ('Eva', 'Zelená', 'Náměstí 777', 'Olomouc', 'OL', 'eva123'), ('Tomáš', 'Žlutý', 'Sídlištní 999', 'Hradec Králové', 'HK', 'tomas456'), ('Lucie', 'Fialová', 'Polní 111', 'České Budějovice', 'CB', 'lucie789'), ('David', 'Oranžový', 'Příčná 222', 'Ústí nad Labem', 'UL', 'david123'), ('Tereza', 'Šedá', 'Okružní 444', 'Pardubice', 'PA', 'tereza456');
Příklad 1: Zobrazení celých jmen
Jako první si ukážeme, jak pomocí funkce `SQL CONCAT` spojit sloupce `first_name` a `last_name`, abychom získali celé jméno:
SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees;
Měli byste obdržet následující výsledek:
+----------------+ |
| full_name | |
+----------------+ |
| Jan Novák | |
| Alena Svobodová | |
| Petr Černý | |
| Marie Bílá | |
| Josef Modrý | |
| Eva Zelená | |
| Tomáš Žlutý | |
| Lucie Fialová | |
| David Oranžový | |
| Tereza Šedá | |
+----------------+ |
10 řádků ve výsledku (0.00 sec) |
Všimněte si, že kromě sloupců jméno a příjmení jsme pro oddělení jmen vložili mezeru jako textový literál `‘ ‚`.
Příklad 2: Sestavení adres
Pojďme si ukázat další příklad.
Tabulka `employees` obsahuje sloupce pro ulici, město a kraj. Spojením těchto tří sloupců a použitím čárky jako oddělovače můžeme vytvořit sloupec `full_address`:
SELECT CONCAT(street, ', ', city, ', ', state) AS full_address FROM employees;
Výstup bude vypadat takto:
+--------------------------------+ |
| full_address | |
+--------------------------------+ |
| Hlavní 123, Praha, PH | |
| Dlouhá 456, Brno, BO | |
| Krátká 789, Ostrava, OL | |
| Zahradní 321, Plzeň, PL | |
| Lesní 555, Liberec, LB | |
| Náměstí 777, Olomouc, OL | |
| Sídlištní 999, Hradec Králové, HK | |
| Polní 111, České Budějovice, CB | |
| Příčná 222, Ústí nad Labem, UL | |
| Okružní 444, Pardubice, PA | |
+--------------------------------+ |
10 řádků ve výsledku (0.00 sec) |
Příklad 3: Vytvoření URL profilů
V tabulce `employees` máme také sloupec `username`.
Představme si, že máte web na adrese `https://www.example.com/` a uživatelské profily jsou dostupné na `https://www.example.com/user/`. Pomocí funkce `CONCAT` můžeme vygenerovat URL adresy profilů takto:
SELECT CONCAT('https://www.example.com/user/', username) AS profile_url FROM employees;
Jak je vidět, získali jsme URL adresy pro všechny zaměstnance:
+-----------------------------------------+ |
| profile_url | |
+-----------------------------------------+ |
| https://www.example.com/user/jan123 | |
| https://www.example.com/user/alena456 | |
| https://www.example.com/user/petr789 | |
| https://www.example.com/user/marie456 | |
| https://www.example.com/user/josef789 | |
| https://www.example.com/user/eva123 | |
| https://www.example.com/user/tomas456 | |
| https://www.example.com/user/lucie789 | |
| https://www.example.com/user/david123 | |
| https://www.example.com/user/tereza456 | |
+-----------------------------------------+ |
10 řádků ve výsledku (0.00 sec) |
Zpracování hodnot NULL
V naší tabulce `employees` mají všechny záznamy vyplněna všechna pole. Co se ale stane, pokud má jeden nebo více sloupců hodnotu NULL?
Pojďme si ukázat příklad. Aktualizujeme záznam se `ID = 2`, nastavíme sloupec `street` na hodnotu NULL:
UPDATE employees SET street = NULL WHERE ID = 2; -- Aktualizace záznamu s ID 2
Dotaz OK, 1 ovlivněný řádek (0.05 sec) Zápis odpovídá: 1 Změněno: 1 Upozornění: 0
Nyní se pokusíme pomocí `CONCAT` zobrazit sloupec `full_address`:
SELECT CONCAT(street, ', ', city, ', ', state) AS full_address FROM employees;
Výsledek bude následující:
+--------------------------------+ |
| full_address | |
+--------------------------------+ |
| Hlavní 123, Praha, PH | |
| NULL | |
| Krátká 789, Ostrava, OL | |
| Zahradní 321, Plzeň, PL | |
| Lesní 555, Liberec, LB | |
| Náměstí 777, Olomouc, OL | |
| Sídlištní 999, Hradec Králové, HK | |
| Polní 111, České Budějovice, CB | |
| Příčná 222, Ústí nad Labem, UL | |
| Okružní 444, Pardubice, PA | |
+--------------------------------+ |
10 řádků ve výsledku (0.00 sec) |
Jak vidíte, druhý záznam má hodnotu `NULL`.
Chtěli bychom ale, aby výstup alespoň obsahoval město a kraj, což nám dá přibližnou představu o adrese. V takových situacích, kdy se mohou objevit hodnoty NULL, můžeme místo funkce `CONCAT` použít `CONCAT_WS`. Podívejme se, jak to funguje.
Použití CONCAT_WS pro zpracování hodnot NULL
Funkce `CONCAT_WS` je alternativou k `CONCAT`, která je vhodná, když se může v datech objevit jedna nebo více hodnot NULL.
Funkci `CONCAT_WS` můžeme použít následujícím způsobem:
CONCAT_WS(oddělovač, řetězec_1, řetězec_2,..., řetězec_n)
Nyní spustíme následující dotaz:
SELECT CONCAT_WS(', ', street, city, state) AS full_address FROM employees;
Výstup bude:
+--------------------------------+ |
| full_address | |
+--------------------------------+ |
| Hlavní 123, Praha, PH | |
| Brno, BO | |
| Krátká 789, Ostrava, OL | |
| Zahradní 321, Plzeň, PL | |
| Lesní 555, Liberec, LB | |
| Náměstí 777, Olomouc, OL | |
| Sídlištní 999, Hradec Králové, HK | |
| Polní 111, České Budějovice, CB | |
| Příčná 222, Ústí nad Labem, UL | |
| Okružní 444, Pardubice, PA | |
+--------------------------------+ |
10 řádků ve výsledku (0.01 sec) |
Jak můžete vidět, pro druhý záznam jsme obdrželi ‚Brno, BO‘, protože sloupec `street` je NULL.
⚠ Při použití funkce `CONCAT_WS` je nutné zadat oddělovač. Pokud oddělovač nezadáte, výsledkem bude `NULL`, pokud je jeden nebo více sloupců NULL (podobně jako u funkce `CONCAT`).
Shrnutí
Zopakujme si, co jsme se naučili:
- Při dotazování databáze se často setkáme s potřebou spojit více textových sloupců do jednoho, aby byly výsledky dotazů lépe srozumitelné. Pro tyto účely můžeme použít funkci `CONCAT` se syntaxí `CONCAT(řetězec_1, řetězec_2, …, řetězec_n)`.
- Můžeme spojovat textové literály, sloupce nebo jejich kombinace. Nicméně, pokud se v datech objeví hodnota NULL, celý výsledek pro daný záznam bude `NULL`. Pro elegantní zpracování hodnot `NULL` je možné použít funkci `CONCAT_WS` se syntaxí `CONCAT_WS(oddělovač, řetězec_1, řetězec_2, …, řetězec_n)`.
- `CONCAT_WS` zpracovává hodnoty `NULL` tím způsobem, že spojí pouze ty řetězce, které nejsou `NULL`, a použije přitom zadaný oddělovač.
Pro rychlou orientaci v příkazech SQL si můžete uložit do záložek tento SQL Cheat Sheet.