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.