DAYOFWEEK
La funcion DAYOFWEEK() devuelve un entero que representa el dia de la semana de una fecha, siguiendo el estandar ODBC donde 1 corresponde al domingo y 7 al sabado. A diferencia de DAYNAME() que devuelve el nombre del dia como texto, DAYOFWEEK() devuelve un valor numerico que resulta mas practico para filtrar, ordenar y realizar calculos condicionales en tus consultas.
Sintaxis
DAYOFWEEK(fecha)El parametro fecha acepta valores de tipo DATE o DATETIME. La funcion devuelve un entero entre 1 y 7 segun esta correspondencia:
| Valor | Dia |
|---|---|
| 1 | Domingo |
| 2 | Lunes |
| 3 | Martes |
| 4 | Miercoles |
| 5 | Jueves |
| 6 | Viernes |
| 7 | Sabado |
Es importante recordar esta numeracion porque sigue el estandar ODBC (Open Database Connectivity), no la convencion ISO donde el lunes es el primer dia de la semana. Si necesitas la convencion ISO (lunes = 0), usa WEEKDAY() en su lugar.
Comportamiento basico
Para obtener el dia de la semana de una fecha especifica:
SELECT DAYOFWEEK('2026-02-14') AS dia_semana;| dia_semana |
|---|
| 7 |
El 14 de febrero de 2026 es sabado, que corresponde al valor 7 en la escala ODBC. Puedes verificarlo combinandolo con DAYNAME():
SELECT
'2026-02-14' AS fecha,
DAYOFWEEK('2026-02-14') AS numero_dia,
DAYNAME('2026-02-14') AS nombre_dia;| fecha | numero_dia | nombre_dia |
|---|---|---|
| 2026-02-14 | 7 | Saturday |
Cuando aplicas DAYOFWEEK() sobre una columna, obtienes el numero correspondiente para cada fila:
SELECT
nombre,
fecha_contratacion,
DAYOFWEEK(fecha_contratacion) AS dia_numero
FROM empleados
LIMIT 5;| nombre | fecha_contratacion | dia_numero |
|---|---|---|
| Maria Garcia | 2023-03-15 | 4 |
| Carlos Rodriguez | 2022-07-01 | 6 |
| Ana Martinez | 2024-01-08 | 2 |
| Pedro Sanchez | 2023-11-20 | 2 |
| Laura Fernandez | 2024-06-03 | 2 |
Caso practico: filtrar dias laborables y fines de semana
Uno de los usos mas frecuentes de DAYOFWEEK() es separar datos entre dias laborables y fines de semana. Los fines de semana corresponden a los valores 1 (domingo) y 7 (sabado):
SELECT
fecha_pedido,
total,
CASE
WHEN DAYOFWEEK(fecha_pedido) IN (1, 7) THEN 'Fin de semana'
ELSE 'Laborable'
END AS tipo_dia
FROM pedidos
WHERE fecha_pedido BETWEEN '2026-02-09' AND '2026-02-15'
ORDER BY fecha_pedido;| fecha_pedido | total | tipo_dia |
|---|---|---|
| 2026-02-09 | 445.00 | Laborable |
| 2026-02-10 | 156.40 | Laborable |
| 2026-02-11 | 278.30 | Laborable |
| 2026-02-12 | 95.80 | Laborable |
| 2026-02-13 | 342.00 | Laborable |
| 2026-02-14 | 189.50 | Fin de semana |
| 2026-02-15 | 67.90 | Fin de semana |
Para obtener solo los pedidos realizados en dias laborables, filtra directamente en el WHERE:
SELECT
fecha_pedido,
COUNT(*) AS total_pedidos,
SUM(total) AS ingresos
FROM pedidos
WHERE YEAR(fecha_pedido) = 2025
AND DAYOFWEEK(fecha_pedido) BETWEEN 2 AND 6
GROUP BY fecha_pedido
ORDER BY fecha_pedido
LIMIT 5;La condicion BETWEEN 2 AND 6 incluye de lunes (2) a viernes (6), excluyendo domingo (1) y sabado (7).
Caso practico: comparar rendimiento entre dias laborables y fines de semana
Para un analisis comercial, resulta valioso comparar las ventas entre dias laborables y fines de semana:
SELECT
CASE
WHEN DAYOFWEEK(fecha_pedido) IN (1, 7) THEN 'Fin de semana'
ELSE 'Dia laborable'
END AS tipo_dia,
COUNT(*) AS total_pedidos,
ROUND(AVG(total), 2) AS ticket_medio,
ROUND(SUM(total), 2) AS ingresos_totales,
COUNT(DISTINCT DATE(fecha_pedido)) AS dias_contados,
ROUND(SUM(total) / COUNT(DISTINCT DATE(fecha_pedido)), 2) AS ingreso_diario_promedio
FROM pedidos
WHERE YEAR(fecha_pedido) = 2025
GROUP BY CASE
WHEN DAYOFWEEK(fecha_pedido) IN (1, 7) THEN 'Fin de semana'
ELSE 'Dia laborable'
END;| tipo_dia | total_pedidos | ticket_medio | ingresos_totales | dias_contados | ingreso_diario_promedio |
|---|---|---|---|---|---|
| Dia laborable | 1650 | 258.30 | 426195.00 | 261 | 1632.93 |
| Fin de semana | 618 | 232.15 | 143468.70 | 104 | 1379.51 |
Este analisis revela que aunque los dias laborables generan mas ingresos en total (logico, son mas dias), el ticket medio entre semana tambien es ligeramente superior.
Caso practico: programacion de turnos
En aplicaciones de gestion de personal, DAYOFWEEK() sirve para asignar turnos segun el dia de la semana:
SELECT
e.nombre,
t.fecha_turno,
DAYOFWEEK(t.fecha_turno) AS dia_num,
t.turno,
CASE DAYOFWEEK(t.fecha_turno)
WHEN 1 THEN 'Recargo dominical 75%'
WHEN 7 THEN 'Recargo sabatino 25%'
ELSE 'Tarifa normal'
END AS tipo_tarifa
FROM empleados e
JOIN turnos t ON e.id = t.empleado_id
WHERE t.fecha_turno BETWEEN '2026-02-09' AND '2026-02-15'
ORDER BY t.fecha_turno, e.nombre
LIMIT 7;| nombre | fecha_turno | dia_num | turno | tipo_tarifa |
|---|---|---|---|---|
| Ana Martinez | 2026-02-09 | 2 | Manana | Tarifa normal |
| Carlos Rodriguez | 2026-02-09 | 2 | Tarde | Tarifa normal |
| Laura Fernandez | 2026-02-10 | 3 | Manana | Tarifa normal |
| Maria Garcia | 2026-02-14 | 7 | Manana | Recargo sabatino 25% |
| Pedro Sanchez | 2026-02-14 | 7 | Tarde | Recargo sabatino 25% |
| Ana Martinez | 2026-02-15 | 1 | Manana | Recargo dominical 75% |
| Carlos Rodriguez | 2026-02-15 | 1 | Tarde | Recargo dominical 75% |
Manejo de NULL
DAYOFWEEK() devuelve NULL cuando recibe un valor nulo o una fecha invalida:
SELECT
DAYOFWEEK(NULL) AS resultado_null,
DAYOFWEEK('2025-13-01') AS mes_invalido,
DAYOFWEEK('0000-00-00') AS fecha_cero;| resultado_null | mes_invalido | fecha_cero |
|---|---|---|
| NULL | NULL | NULL |
En consultas con columnas que pueden contener nulos, protegete con IFNULL o una condicion en el WHERE:
SELECT
nombre,
fecha_baja,
IFNULL(DAYOFWEEK(fecha_baja), 0) AS dia_baja
FROM empleados
WHERE fecha_baja IS NOT NULL;Combinacion con otras funciones
La diferencia entre DAYOFWEEK() y WEEKDAY() es una fuente habitual de confusion. Ambas devuelven el dia de la semana como numero, pero con escalas diferentes:
SELECT
'2026-02-14' AS fecha,
DAYOFWEEK('2026-02-14') AS dayofweek_result,
WEEKDAY('2026-02-14') AS weekday_result;| fecha | dayofweek_result | weekday_result |
|---|---|---|
| 2026-02-14 | 7 | 5 |
DAYOFWEEK() devuelve 7 (sabado en escala 1-7 empezando en domingo), mientras que WEEKDAY() devuelve 5 (sabado en escala 0-6 empezando en lunes). La relacion entre ambas es: DAYOFWEEK(fecha) = WEEKDAY(fecha) + 2 cuando el resultado no excede 7, o mas formalmente DAYOFWEEK(fecha) = MOD(WEEKDAY(fecha) + 1, 7) + 1.
Puedes usar DAYOFWEEK() junto con DAYNAME() para reportes que combinen el numero y el nombre:
SET lc_time_names = 'es_ES';
SELECT
DAYOFWEEK(fecha_pedido) AS num,
DAYNAME(fecha_pedido) AS dia,
COUNT(*) AS pedidos
FROM pedidos
WHERE YEAR(fecha_pedido) = 2025
GROUP BY DAYOFWEEK(fecha_pedido), DAYNAME(fecha_pedido)
ORDER BY DAYOFWEEK(fecha_pedido);| num | dia | pedidos |
|---|---|---|
| 1 | domingo | 98 |
| 2 | lunes | 187 |
| 3 | martes | 162 |
| 4 | miercoles | 174 |
| 5 | jueves | 195 |
| 6 | viernes | 231 |
| 7 | sabado | 145 |
En el siguiente articulo veremos DAYOFYEAR para obtener el dia del ano.
Escrito por Eduardo Lázaro
