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:

ValorDia
1Domingo
2Lunes
3Martes
4Miercoles
5Jueves
6Viernes
7Sabado

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;
fechanumero_dianombre_dia
2026-02-147Saturday

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;
nombrefecha_contrataciondia_numero
Maria Garcia2023-03-154
Carlos Rodriguez2022-07-016
Ana Martinez2024-01-082
Pedro Sanchez2023-11-202
Laura Fernandez2024-06-032

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_pedidototaltipo_dia
2026-02-09445.00Laborable
2026-02-10156.40Laborable
2026-02-11278.30Laborable
2026-02-1295.80Laborable
2026-02-13342.00Laborable
2026-02-14189.50Fin de semana
2026-02-1567.90Fin 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_diatotal_pedidosticket_medioingresos_totalesdias_contadosingreso_diario_promedio
Dia laborable1650258.30426195.002611632.93
Fin de semana618232.15143468.701041379.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;
nombrefecha_turnodia_numturnotipo_tarifa
Ana Martinez2026-02-092MananaTarifa normal
Carlos Rodriguez2026-02-092TardeTarifa normal
Laura Fernandez2026-02-103MananaTarifa normal
Maria Garcia2026-02-147MananaRecargo sabatino 25%
Pedro Sanchez2026-02-147TardeRecargo sabatino 25%
Ana Martinez2026-02-151MananaRecargo dominical 75%
Carlos Rodriguez2026-02-151TardeRecargo 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_nullmes_invalidofecha_cero
NULLNULLNULL

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;
fechadayofweek_resultweekday_result
2026-02-1475

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);
numdiapedidos
1domingo98
2lunes187
3martes162
4miercoles174
5jueves195
6viernes231
7sabado145

En el siguiente articulo veremos DAYOFYEAR para obtener el dia del ano.

Escrito por Eduardo Lázaro