Funcions d'una sola fila
Les funcions d'una sola fila (single-row functions) s'apliquen a cada fila individualment i retornen un únic valor per fila. Es poden usar a la clàusula SELECT, WHERE, ORDER BY i HAVING.
Es diferencien de les funcions d'agregació (COUNT, SUM...) en que no col·lapsen múltiples files en un resultat: si la consulta retorna 100 files, la funció s'executa 100 vegades.
Funcions de cadena
Conversió de majúscules i minúscules
Longitud
LENGTH i jocs de caràcters multibyte
A MySQL, LENGTH retorna el nombre de bytes, no de caràcters. Per a caràcters UTF-8 com à o ç (2 bytes en UTF-8), LENGTH pot retornar un valor diferent de CHAR_LENGTH. Usa sempre CHAR_LENGTH a MySQL quan treballes amb text en català o altres idiomes amb caràcters no ASCII.
Extracció de subcadena
Eliminació d'espais
Substitució i concatenació
-- Substitució
SELECT REPLACE('Hola món', 'món', 'world'); -- 'Hola world'
-- Concatenació amb operador
SELECT 'Hola' || ' ' || 'món'; -- 'Hola món'
-- Concatenació amb funció
SELECT CONCAT('Hola', ' ', 'món'); -- 'Hola món'
SELECT CONCAT_WS(', ', 'Girona', 'Blanes', 'Lloret'); -- 'Girona, Blanes, Lloret'
SELECT REPLACE('Hola món', 'món', 'world') FROM dual;
SELECT 'Hola' || ' ' || 'món' FROM dual;
SELECT CONCAT('Hola', ' món') FROM dual; -- CONCAT a Oracle accepta només 2 arguments
-- Per a mes de 2, encadena CONCATs o usa ||
SELECT CONCAT(CONCAT('Nom: ', nom), CONCAT(', Email: ', email)) FROM clients;
Rebliment i posició
SELECT LPAD('42', 6, '0') FROM dual; -- '000042'
SELECT RPAD('Blanes', 10, '.') FROM dual; -- 'Blanes....'
SELECT INSTR('Barcelona', 'an') FROM dual; -- 3
-- Segon i tercer argument opcionals: INSTR(str, substr, inici, ocurrencia)
SELECT INSTR('abcabc', 'a', 1, 2) FROM dual; -- 4 (2a ocurrencia de 'a')
AC0372/04/05 — Miniactivitat
RA4 · CA4.2
Amb la taula clients, escriviu una consulta que mostri:
- El nom i cognoms en majúscules concatenats en una sola columna (
NOM COGNOMS) - Les inicials de cada client (primera lletra del nom i primera del cognom)
- L'email amb el domini amagat (substituïu el domini per
***) - El DNI formateig amb un guió davant de la lletra (per exemple
12345678-A)
Funcions numèriques
Arrodoniment i truncament
Valor absolut, mòdul i potència
Aplicació pràctica: càlculs sobre dades
-- Preu amb IVA arrodonit a 2 decimals
SELECT nom,
preu,
ROUND(preu * 1.21, 2) AS preu_iva,
ROUND(preu * 0.21, 2) AS import_iva
FROM productes
WHERE actiu = TRUE;
-- Percentatge d'estoc respecte al màxim
SELECT nom,
estoc,
estoc_maxim,
ROUND(estoc::numeric / estoc_maxim * 100, 1) AS pct_estoc
FROM productes
WHERE estoc_maxim > 0;
AC0372/04/06 — Miniactivitat
RA4 · CA4.2
Amb la taula productes, escriviu consultes que retornin:
- El preu original, el preu amb IVA (21%) i el descompte del 10%, tots arrodonits a 2 decimals
- Les 5 taules amb estoc en múltiples de 10 mes proper (per exemple, 47 → 50)
- Quins productes tenen un preu que és potència exacta de 2 (2, 4, 8, 16, 32...)
Funcions de data i hora
Data i hora actuals
Extracció de components
SELECT EXTRACT(YEAR FROM CURRENT_DATE); -- 2026
SELECT EXTRACT(MONTH FROM CURRENT_DATE); -- 3
SELECT EXTRACT(DAY FROM CURRENT_DATE); -- 20
SELECT EXTRACT(DOW FROM CURRENT_DATE); -- 5 (0=diumenge)
SELECT EXTRACT(WEEK FROM CURRENT_DATE); -- setmana de l'any
-- Alternativa amb DATE_PART
SELECT DATE_PART('year', CURRENT_DATE); -- 2026
SELECT YEAR(NOW()); -- 2026
SELECT MONTH(NOW()); -- 3
SELECT DAY(NOW()); -- 20
SELECT HOUR(NOW()); -- 10
SELECT MINUTE(NOW()); -- 34
SELECT SECOND(NOW()); -- 22
SELECT DAYOFWEEK(NOW()); -- 1=diumenge ... 7=dissabte
SELECT WEEK(NOW()); -- setmana de l'any
SELECT DAYNAME(NOW()); -- 'Friday'
SELECT MONTHNAME(NOW()); -- 'March'
SELECT EXTRACT(YEAR FROM SYSDATE) FROM dual; -- 2026
SELECT EXTRACT(MONTH FROM SYSDATE) FROM dual; -- 3
SELECT EXTRACT(DAY FROM SYSDATE) FROM dual; -- 20
-- TO_CHAR és la forma habitual per extreure components
SELECT TO_CHAR(SYSDATE, 'YYYY') FROM dual; -- '2026'
SELECT TO_CHAR(SYSDATE, 'MM') FROM dual; -- '03'
SELECT TO_CHAR(SYSDATE, 'Day') FROM dual; -- 'Friday '
Aritmètica de dates
-- Sumar/restar intervals
SELECT CURRENT_DATE + INTERVAL '30 days';
SELECT CURRENT_DATE - INTERVAL '1 year';
SELECT CURRENT_TIMESTAMP + INTERVAL '2 hours 30 minutes';
-- Diferència entre dates (retorna un integer de dies)
SELECT data_fi - data_inici AS dies_entre
FROM projectes;
-- Diferència en una unitat concreta
SELECT DATE_PART('day', data_fi::timestamp - data_inici::timestamp)
FROM projectes;
-- AGE: calcula interval llegible
SELECT AGE(CURRENT_DATE, data_naixement) FROM persones;
-- retorna: '35 years 2 mons 5 days'
SELECT DATE_ADD(CURRENT_DATE, INTERVAL 30 DAY);
SELECT DATE_SUB(CURRENT_DATE, INTERVAL 1 YEAR);
SELECT DATE_ADD(NOW(), INTERVAL '2:30' HOUR_MINUTE);
-- Diferència en dies
SELECT DATEDIFF(data_fi, data_inici) AS dies_entre
FROM projectes;
-- Diferència en altres unitats
SELECT TIMESTAMPDIFF(MONTH, data_inici, data_fi) AS mesos
FROM projectes;
-- Sumar dies (DATE + número = DATE)
SELECT SYSDATE + 30 FROM dual; -- d'aquí a 30 dies
SELECT SYSDATE - 365 FROM dual; -- fa un any
-- ADD_MONTHS: sumar mesos (respecta el final de mes)
SELECT ADD_MONTHS(SYSDATE, 3) FROM dual;
-- Diferència entre dates (retorna número de dies)
SELECT data_fi - data_inici AS dies_entre FROM projectes;
-- MONTHS_BETWEEN: diferència en mesos
SELECT MONTHS_BETWEEN(data_fi, data_inici) FROM projectes;
-- NEXT_DAY: proper dia de la setmana
SELECT NEXT_DAY(SYSDATE, 'MONDAY') FROM dual;
-- LAST_DAY: últim dia del mes
SELECT LAST_DAY(SYSDATE) FROM dual;
Format de dates
SELECT TO_CHAR(CURRENT_DATE, 'DD/MM/YYYY'); -- '20/03/2026'
SELECT TO_CHAR(CURRENT_TIMESTAMP, 'DD-Mon-YYYY HH24:MI'); -- '20-Mar-2026 10:34'
SELECT TO_CHAR(CURRENT_DATE, 'TMDay, DD TMMonth YYYY'); -- 'Friday, 20 March 2026'
-- Conversió inversa: text a data
SELECT TO_DATE('20/03/2026', 'DD/MM/YYYY');
SELECT TO_CHAR(SYSDATE, 'DD/MM/YYYY') FROM dual;
SELECT TO_CHAR(SYSDATE, 'DD-Mon-YYYY HH24:MI') FROM dual;
SELECT TO_CHAR(SYSDATE, 'Day, DD Month YYYY') FROM dual;
-- Text a data
SELECT TO_DATE('20/03/2026', 'DD/MM/YYYY') FROM dual;
-- Text a timestamp
SELECT TO_TIMESTAMP('20/03/2026 10:34:22', 'DD/MM/YYYY HH24:MI:SS') FROM dual;
Emmagatzemar dates vs. cadenes
Mai emmagatzemeu dates com a text (VARCHAR). Useu sempre els tipus nadius de data (DATE, TIMESTAMP). Emmagatzemar '20/03/2026' com a text impedeix comparacions, ordenació correcta, aritmètica de dates i aprofitar índexos de rang. TO_CHAR i DATE_FORMAT s'usen per presentar dates, no per guardar-les.
AC0372/04/07 — Miniactivitat
RA4 · CA4.2
Amb les taules clients i comandes:
- Mostreu els clients amb el format
'Cognom, Nom (alta: DD/MM/YYYY)'en una sola columna - Calculeu l'antiguitat de cada client en anys complets des de
data_alta - Mostreu totes les comandes del mes actual, amb la data formatejada i els dies que fa que es va fer
- Quins clients van donar-se d'alta en un dilluns? (pista: useu la funció d'extracció del dia de la setmana)
Conversió de tipus (CAST)
La funció CAST converteix un valor d'un tipus a un altre. És estàndard SQL i funciona a tots els motors.
Funcions de conversió amb format
Mentre CAST fa conversions de tipus simples, les funcions TO_CHAR, TO_NUMBER i TO_DATE permeten especificar una màscara de format per controlar com es representa o interpreta el valor. Son especialment útils per formatar números amb separadors de milers, moneda o percentatge.
TO_CHAR: número a cadena
-- Separador de milers i decimals fixes
SELECT TO_CHAR(1234567.89, 'FM9,999,999.00'); -- '1,234,567.89'
-- Zeros a l'esquerra
SELECT TO_CHAR(42, 'FM000000'); -- '000042'
-- Símbol de moneda local (L)
SELECT TO_CHAR(1234.5, 'FML9,999.99');
-- Percentatge
SELECT TO_CHAR(0.1534, 'FM90.99%'); -- '15.34%'
-- TO_CHAR(número, màscara)
SELECT TO_CHAR(1234567.89, 'FM9,999,999.99') FROM dual; -- '1,234,567.89'
SELECT TO_CHAR(42, 'FM000000') FROM dual; -- '000042'
SELECT TO_CHAR(1234.5, 'FML9,999.99') FROM dual; -- símbol moneda local
SELECT TO_CHAR(0.1534, 'FM90.99%') FROM dual; -- '15.34%'
-- G i D per a separadors amb consciència de locale
SELECT TO_CHAR(1234.56, 'FM9G999D99') FROM dual; -- '1,234.56'
Màscares de format numèric Oracle
| Element | Significat | Exemple |
|---|---|---|
9 |
Dígit (espai si no és necessari) | 999 → ' 42' |
0 |
Dígit amb zero forçat | 000 → '042' |
G |
Separador de milers (locale) | 9G999 → '1,234' |
D |
Separador decimal (locale) | 99D99 → '42.50' |
FM |
Fill Mode: elimina espais i zeros superflus | FM999 → '42' |
L |
Símbol moneda local | L999 → '€42' |
$ |
Signe dòlar literal | $999 → '$42' |
S |
Signe + o - | S999 → '+42' |
TO_NUMBER: cadena a número
TO_DATE i TO_TIMESTAMP
Ja cobertes a la secció Format de dates, però aquí es resumeixen les equivalències entre motors:
SELECT TO_DATE('20/03/2026', 'DD/MM/YYYY') FROM dual;
SELECT TO_TIMESTAMP('20/03/2026 10:34:22', 'DD/MM/YYYY HH24:MI:SS') FROM dual;
-- Amb zona horaria
SELECT TO_TIMESTAMP_TZ('20/03/2026 10:34:22 +01:00',
'DD/MM/YYYY HH24:MI:SS TZH:TZM') FROM dual;
Màscares de format de data Oracle
| Màscara | Significat | Exemple |
|---|---|---|
YYYY |
Any de 4 dígits | 2026 |
MM |
Mes numèric | 03 |
DD |
Dia del mes | 20 |
HH24 |
Hora en format 24h | 10 |
MI |
Minuts | 34 |
SS |
Segons | 22 |
DY |
Nom curt del dia | FRI |
DAY |
Nom complet del dia | FRIDAY |
MON |
Mes abreujat | MAR |
MONTH |
Mes complet | MARCH |
AC0372/04/08 — Miniactivitat
RA4 · CA4.2
Practiqueu les funcions de conversió amb format:
- Formateu el preu de cada producte com a cadena amb 2 decimals, separador de milers i símbol €.
- Convertiu la cadena
'15.234,75'(format europeu) a un valor numèric de la vostra BD. - Mostreu la
data_altade cada client en el format'Divendres, 20 de Març de 2026'. - Construïu una columna calculada
referenciaque combini l'id del client amb la data en formatCLI-00042-20260320.
Conversions implícites
Alguns motors fan conversions implícites (per exemple, comparar un INTEGER amb un VARCHAR que conté un número pot funcionar). Eviteu confiar-hi: les conversions implícites poden causar comportaments inesperats, impedir l'ús d'índexos i generar errors subtils en migrar entre motors.