SQL od podstaw · część 14

Funkcje skalarne tekstowe

Przekształcaj napisy, wycinaj fragmenty i łącz wartości. Poznaj różnice długości, Unicode oraz NULL w popularnych bazach.

Część bazodanowa INF.03

Jedna wartość wejściowa, jeden wynik

Funkcja skalarna oblicza wartość dla danego wyrażenia. W zapytaniu SELECT zwykle otrzymujesz wynik osobno dla każdego wybranego wiersza. UPPER(imie) zmienia postać imienia w wyniku; nie zapisuje zmiany w tabeli. Agregacja wielu wierszy, np. COUNT(*), będzie osobnym tematem.

Alawartość kolumny→UPPER(imie)obliczenie→ALAwartość wyniku
SELECT id, imie, UPPER(imie) AS duze_litery
FROM klienci ORDER BY id;

Po resecie pierwszy wiersz to 1, Ala, ALA. Nadal masz pięciu klientów. Alias opisuje obliczoną kolumnę; funkcja nie nadaje rekordowi nowego identyfikatora.

Mapa najczęstszych funkcji

CelMySQL 8.4 / MariaDBSQL ServerOracle 19cAccess w kwerendzie
Wielkie / małe literyUPPER / LOWERUPPER / LOWERUPPER / LOWERUCase / LCase
Długość tekstuCHAR_LENGTHLENLENGTHLen
Fragment od pozycjiSUBSTRINGSUBSTRINGSUBSTRMid
Spacje na krańcachTRIMTRIM (2017+)TRIMTrim
Zamiana fragmentuREPLACEREPLACEREPLACEReplace

To mapa podobnych zastosowań, nie gwarancja identycznej semantyki. MySQL LENGTH liczy bajty, CHAR_LENGTH znaki. SQL Server LEN pomija końcowe spacje; DATALENGTH liczy bajty. Oracle ma m.in. LENGTH i LENGTHB. Dlatego „liczba znaków” i „rozmiar w pamięci” nie są tym samym. Działanie na Unicode i reguły zmiany wielkości liter zależą od silnika oraz ustawień.

Ten sam cel: pierwsze trzy litery produktu

-- MySQL / MariaDB oraz SQL Server
SELECT nazwa, SUBSTRING(nazwa, 1, 3) AS skrot FROM produkty;
-- Oracle 19c
SELECT nazwa, SUBSTR(nazwa, 1, 3) AS skrot FROM produkty;
-- Access
SELECT nazwa, Mid(nazwa, 1, 3) AS skrot FROM produkty;
-- SQLite w edytorze
SELECT nazwa, SUBSTR(nazwa, 1, 3) AS skrot FROM produkty;

Dla Klawiatura wynikiem jest Kla. W tych przykładach pozycję pierwszego znaku oznacza 1. Nie przenoś bez sprawdzenia reguł pozycji 0, ujemnych pozycji i długości poza zakresem między bazami.

Łączenie tekstu i pułapka NULL

-- MySQL / MariaDB; także SQL Server 2012+
SELECT CONCAT(imie, ' / ', COALESCE(miasto, 'brak')) AS opis
FROM klienci ORDER BY id;
-- Oracle 19c
SELECT imie || ' / ' || COALESCE(miasto, 'brak') AS opis
FROM klienci ORDER BY id;
-- Access
SELECT imie & ' / ' & Nz(miasto, 'brak') AS opis
FROM klienci ORDER BY id;

Ewa otrzyma opis „Ewa / brak”. COALESCE wybiera pierwszą wartość różną od NULL; Nz w Access ma tu jawny tekst zastępczy. Sama funkcja CONCAT nie ma jednak wszędzie tych samych zasad: MySQL CONCAT(’A’, NULL) daje NULL, a SQL Server CONCAT(’A’, NULL) daje 'A’. W Oracle 19c 'A’ || NULL daje 'A’, a pusty napis jest traktowany jako NULL. W SQLite operator || propaguje NULL; w tym edytorze operator || jest obecnie poza dopuszczonym zakresem.

Edytor domyślnie wykonuje SQLite. Użyj UPPER, LOWER, LENGTH, SUBSTR, TRIM, INSTR lub REPLACE dla ćwiczeń natywnych. Przykłady CONCAT możesz porównać w trybach MySQL i SQL Server (od 2 do 6 argumentów). Tryby emulacji nie obsługują wszystkich funkcji z tabeli; Oracle i Access wykonuj we właściwym środowisku. SQLite UPPER/LOWER w standardowej kompilacji obejmują podstawowe litery ASCII, więc nie traktuj wyniku jako wzorca polskiej kolacji.

Wypróbuj zapytanie

SQLite — rzeczywisty silnik przeglądarki. MySQL / SQL Server — ograniczona emulacja składni. Wybierz tryb SQLite do natywnego LIKE. Pozostałe tryby nie są rzeczywistymi serwerami. Ścisłe typy, auto-ID i administrację ćwicz w prawdziwym SZBD.

Ładowanie edytora…

Czyszczenie wyniku a zmiana danych

-- Natywny SQLite: odczyt bez zmiany tabeli
SELECT TRIM('  Ala  ') AS bez_spacji,
       REPLACE('kod-2026', '-', '/') AS nowy_zapis,
       INSTR('[email protected]', '@') AS pozycja;

Oczekiwane wartości to Ala, kod/2026 i 4. TRIM domyślnie nie usuwa każdego możliwego znaku białego ani wszystkich spacji wewnątrz tekstu. Zagnieżdżenia czytaj od środka: LOWER(TRIM(imie)) najpierw usuwa spacje z krańców, potem zmienia wielkość liter.

Funkcję można umieścić w WHERE, np. LENGTH(imie) > 3. Na dużej bazie funkcja nakładana na indeksowaną kolumnę może utrudnić użycie zwykłego indeksu. Na egzaminie najpierw zadbaj o poprawność wyniku, a następnie o jasne i uzasadnione warunki.

Ćwiczenia SQL

  1. W SQLite pokaż nazwy produktów małymi literami oraz ich długości, po id.
  2. Wybierz klientów o imieniu dłuższym niż trzy znaki.
  3. Wyjaśnij różnicę CONCAT(’A’, NULL) w MySQL i SQL Server. Jak wymusić napis „brak” zamiast braku wartości?
Rozwiązania i wyjaśnienia
SELECT LOWER(nazwa) AS nazwa_mala, LENGTH(nazwa) AS znaki
FROM produkty ORDER BY id;
SELECT imie FROM klienci WHERE LENGTH(imie) > 3 ORDER BY id;
-- MySQL / SQL Server
SELECT CONCAT('A', COALESCE(NULL, 'brak')) AS wynik;

1. klawiatura: 10, mysz: 4, monitor: 7, kabel: 5. 2. O’Neil i Adam. 3. Bez COALESCE odpowiednio NULL i A; z jawnym zastępstwem wynik to Abrak. Apostrof w imieniu O’Neil należy do danych i jest liczony jako znak.

Zapamiętaj: rozróżniaj wartość, jej prezentację oraz zapis w tabeli. Znajomość nazwy funkcji nie wystarcza — sprawdź NULL, Unicode, pozycje i jednostkę długości.

Źródła: MySQL — funkcje tekstowe, SQL Server CONCAT, Oracle — konkatenacja, Access — funkcje tekstowe. INF.03.4: przetwarzanie wyników zapytań. Dalej: funkcje skalarne liczbowe.

Przewijanie do góry