You're trying to use an alias of expiration_date from your CASE statement in your WHERE clause.
Two problems with this:
- You cannot use column aliases in the
WHERE clause. Refer to this post here.
WHERE happens before SELECT in the execution chain.
- Your alias matches an actual column name in your table, so your
WHERE clause is not throwing an error regarding your alias, its
comparing the current date to the expiration_date column in the table,
thus, throwing off your expected result.
Solutions:
If you want to use the alias in your WHERE clause, there are a few options for you to force SQL to handle the SELECT before the WHERE clause.
- You can use a subquery (or subselect) to force logical order of
operation by using parentheses:
SELECT
a.entry_id,
a.title,
a.expiration_date
FROM
(SELECT
entry_id,
title,
(CASE WHEN expiration_date = 0 THEN CURDATE() + INTERVAL 1 DAY ELSE FROM_UNIXTIME(expiration_date, '%Y-%m-%d') END) AS expiration_date
FROM channel_titles
) a
WHERE CURDATE() < a.expiration_date
- You can declare your alias in a Common Table Expression (CTE), then
SELECT it FROM the CTE:
WITH cte AS (SELECT
entry_id,
title,
(CASE WHEN expiration_date = 0 THEN CURDATE() + INTERVAL 1 DAY ELSE FROM_UNIXTIME(expiration_date, '%Y-%m-%d') END) AS expiration_date
FROM channel_titles)
SELECT
entry_id,
title,
expiration_date
FROM cte
WHERE CURDATE() < expiration_date
- You can disregard using your alias entirely in your
WHERE clause and plug in the logic from your SELECT statement directly into your WHERE clause. However, this may appear redundant from a readability perspective; also, extra processing should be considered when using this approach as well, but if you have a small data set this method will work just fine:
SELECT
entry_id,
title,
(CASE WHEN expiration_date = 0 THEN CURDATE() + INTERVAL 1 DAY ELSE FROM_UNIXTIME(expiration_date, '%Y-%m-%d') END) AS expiration_date
FROM channel_titles
WHERE CURDATE() < (CASE WHEN expiration_date = 0 THEN CURDATE() + INTERVAL 1 DAY ELSE FROM_UNIXTIME(expiration_date, '%Y-%m-%d') END)
Input:
| entry_id |
title |
expiration_date |
expiration_date_date |
| 1 |
test1 |
1695513600 |
2023-09-24 |
| 2 |
test2 |
0 |
2022-09-15 |
| 3 |
test3 |
1662768000 |
2022-09-10 |
Output:
| entry_id |
title |
expiration_date |
| 1 |
test1 |
2023-09-24 |
| 2 |
test2 |
2022-09-15 |
db<>fiddle here.