I hope the answer is simple and I'm silly.
So I've two tables: day
(with PK id_day
) and hour
(with PK id_hour
).
I've an another table tilt_time
which has id_day
, id_hour
fields and a plus FK field (which has prohibited times). E.g. tilt_time
has the following rows (id_day
, id_hour
, id_target
):
1,1,1
1,2,1
1,3,1
1,1,2
1,2,2
In table day
id_day
is between 1 and 5 (monday to friday) and hour
id_hour
is between 1 and 6 (so you can imagine a day_hour
table with 5*6=30 values).
So I want query id_target=1
's free periods and id_target=2
's free periods (everbody's free periods). So I want similar:
1,4,1
1,5,1
1,6,1
2,*,1
3,*,1
4,*,1
5,*,1
// id_target=2
1,3,2
1,4,2
1,5,2
1,6,2
2,*,2
3,*,2
4,*,2
5,*,2
(* means all valid id_hour
values, so every line with * represents 6 different lines)
How can I do this query?
If you have a target
table with all id_target
, the answer is simple:
SELECT
d.id_day, h.id_hour, t.id_target
FROM
day AS d
CROSS JOIN
hour AS h
CROSS JOIN
target AS t
WHERE
(d.id_day, h.id_hour, t.id_target) NOT IN
( SELECT id_day, id_hour, id_target
FROM tilt_time
)
;
or the (probably more efficient):
SELECT
d.id_day, h.id_hour, t.id_target
FROM
day AS d
CROSS JOIN
hour AS h
CROSS JOIN
target AS t
LEFT JOIN
tilt_time AS tt
ON tt.id = d.id_day
AND tt.id_hour = h.id_hour
AND t.t.id_target = t.id_target
WHERE
tt.id_target iS NULL ;
If you don't have a target
table, replace the target AS t
in the code above with:
( SELECT DISTINCT id_target FROM tilt_time ) AS t