admin管理员组文章数量:1276702
I need to filter a collection of records that satisfies a single date OR satisfies a range of dates. How is this done in conjunction? For example, I need to filter records that has the date 02-FEB-24 OR within the range of 08-FEB-25 to 20-FEB-25. This is what I have:
SELECT userId, COUNT(*), TO_DATE(trans_dt, 'DD-MON-RR')
FROM msgstore
where trans_dt BETWEEN TO_DATE('08-FEB-25', 'DD-MON-RR') AND TO_DATE('20-FEB-25', 'DD-MON-RR')
OR trans_dt = TO_DATE('02-FEB-24', 'DD-MON-RR')
AND SEND_ID = 1020
GROUP BY userId, TO_DATE(trans_dt, 'DD-MON-RR')
I am getting this error message: unable to convert string value containing %s to a number: %s
If I remove one of the trans_dt conditionals in the query, it works. It fails with the error when both trans_dt conditionals are present.
I need to filter a collection of records that satisfies a single date OR satisfies a range of dates. How is this done in conjunction? For example, I need to filter records that has the date 02-FEB-24 OR within the range of 08-FEB-25 to 20-FEB-25. This is what I have:
SELECT userId, COUNT(*), TO_DATE(trans_dt, 'DD-MON-RR')
FROM msgstore
where trans_dt BETWEEN TO_DATE('08-FEB-25', 'DD-MON-RR') AND TO_DATE('20-FEB-25', 'DD-MON-RR')
OR trans_dt = TO_DATE('02-FEB-24', 'DD-MON-RR')
AND SEND_ID = 1020
GROUP BY userId, TO_DATE(trans_dt, 'DD-MON-RR')
I am getting this error message: unable to convert string value containing %s to a number: %s
If I remove one of the trans_dt conditionals in the query, it works. It fails with the error when both trans_dt conditionals are present.
Share Improve this question edited Feb 25 at 4:35 Dale K 27.4k15 gold badges58 silver badges83 bronze badges asked Feb 25 at 2:03 d1dud1du 3161 gold badge3 silver badges12 bronze badges 7 | Show 2 more comments1 Answer
Reset to default 2Assuming that the trans_dt
column is a DATE
data-type.
- Do not use
TO_DATE
on a value that is already aDATE
(i.e. in theSELECT
andGROUP BY
clauses) - that is probably the cause of your error. AND
has higher operator precedence thanOR
; to get the correct logic in theWHERE
filter you need to add brackets to change the precedence.- In Oracle, a
DATE
data-type consists of 7 bytes representing: century, year-of-century, month, day, hours, minutes and seconds. It ALWAYS has those components (even if the client you are using is setup to only show the date component and not the time component); so you probably (unless you are only storing mignight time components) want to filter on entire 24-hour periods andTRUNC
ate the date when grouping.
Like this:
SELECT userId,
COUNT(*),
TRUNC(trans_dt) AS trans_dt
FROM msgstore
WHERE ( (trans_dt >= DATE '2025-02-08' AND trans_dt < DATE '2025-02-21')
OR (trans_dt >= DATE '2024-02-02' AND trans_dt < DATE '2024-02-03')
)
AND SEND_ID = 1020
GROUP BY
userId,
TRUNC(trans_dt)
Which, for the sample data:
CREATE TABLE msgstore (userid, trans_dt, send_id) AS
SELECT 1, DATE '2024-02-01' + LEVEL * INTERVAL '1' HOUR, 1020 FROM DUAL CONNECT BY LEVEL <= 50 UNION ALL
SELECT 1, DATE '2025-02-08' + LEVEL * INTERVAL '1' HOUR, 1020 FROM DUAL CONNECT BY LEVEL <= 144 UNION ALL
SELECT 2, DATE '2025-02-12' + LEVEL * INTERVAL '1' HOUR, 1020 FROM DUAL CONNECT BY LEVEL <= 50;
244 rows affected
Outputs:
USERID | COUNT(*) | TRANS_DT |
---|---|---|
1 | 24 | 2024-02-02 00:00:00 |
1 | 23 | 2025-02-08 00:00:00 |
1 | 24 | 2025-02-09 00:00:00 |
1 | 24 | 2025-02-10 00:00:00 |
1 | 24 | 2025-02-11 00:00:00 |
1 | 24 | 2025-02-12 00:00:00 |
1 | 24 | 2025-02-13 00:00:00 |
1 | 1 | 2025-02-14 00:00:00 |
2 | 23 | 2025-02-12 00:00:00 |
2 | 24 | 2025-02-13 00:00:00 |
2 | 3 | 2025-02-14 00:00:00 |
fiddle
本文标签: sqlUse AND and OR within where clause for datesStack Overflow
版权声明:本文标题:sql - Use AND and OR within where clause for dates - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741232529a2362368.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
SEND_ID
? – PM 77-1 Commented Feb 25 at 2:09TO_DATE(trans_dt, 'DD-MON-RR')
toTO_CHAR(trans_dt, 'DD-MON-RR')
. Also put parenthesis around your OR conditions so they are grouped apart from the AND condition that follows them. Lastly, ensuresend_id
is a number in the data dictionary. If it's not, you may need to put single quotes around it as a string. – Paul W Commented Feb 25 at 2:29