How can I compare just the year and month of datetime in my SQL query (and ignore the day comparison)?
I have a list of id
s:
select id from id where sid = 2403
The above simply returns a list of id
s. e.g. id = 401434786, 401434787, 401434788, etc.
When I run one of these id
s in my tval
table, I get:
select * from tval where id = 401434786;
I get:
id fid ts val
401434786 3765 2019-05-14 00:00:00.000 2019-11-18 00:00:00.000
401434786 3771 2019-11-18 00:00:00.000 2019-11-18 00:00:00.000
401434786 3782 2019-05-14 00:00:00.000 2019-11-18 00:00:00.000
My aim is to filter the list of id
s to only the ones where the val
of fid = 3771
and fid = 3782
are NOT the same.
I have this query which does it:
select distinct t.id from tval t
where (select min(t1.val) from tval t1
where t1.id = t.id and t1.fid = 3771)
!=(select min(t1.val) from tval t1
where t1.id = t.id and t1.fid = 3782)
and id in (select id from id where sid = 2403);
However, I want to amend the query, or write a completely new one, to filter the list of id
s to those where only the Month
or the Year
are different, but if the Month
and Year
and the same but the Day
is different, then leave this out.
In the query above, it filters for id
s where if the Month
and Year
are the same but the Day
is different it still includes it in the output, but I do not want this. I only want id
s where the Month
or the Year
are different.
I hope the above makes sense, and I really appreciate any help!
Answers
To filter the list of IDs based on whether the Month or the Year are different, while excluding cases where only the Day is different, you can modify your query to compare the month and year parts of the val
column. You can achieve this by using date functions to extract the month and year components of the dates and then compare them. Here's how you can do it:
SELECT DISTINCT t.id
FROM tval t
JOIN id i ON t.id = i.id
WHERE i.sid = 2403
AND (
-- Check if the month or year of fid = 3771 is different from fid = 3782
EXTRACT(YEAR FROM t1.val) != EXTRACT(YEAR FROM t2.val)
OR EXTRACT(MONTH FROM t1.val) != EXTRACT(MONTH FROM t2.val)
)
AND t.fid = 3771 -- Filter for fid = 3771
AND EXISTS (
-- Subquery to check if fid = 3782 exists for the same id
SELECT 1
FROM tval t2
WHERE t2.id = t.id
AND t2.fid = 3782
);
In this query:
- We use
EXTRACT(YEAR FROM t1.val)
andEXTRACT(MONTH FROM t1.val)
to extract the year and month parts of theval
column for fid = 3771. - We compare the year and month parts of fid = 3771 with fid = 3782 to check if they are different.
- We use
EXISTS
to check if fid = 3782 exists for the same id as fid = 3771. - We join with the
id
table to filter for ids with sid = 2403.
This query will only return IDs where the month or year of fid = 3771 is different from fid = 3782, excluding cases where only the day is different. Adjust the column names and table aliases as per your actual schema.