使用按日期分组的 sql 查询
Posted
技术标签:
【中文标题】使用按日期分组的 sql 查询【英文标题】:using sql query with group by date 【发布时间】:2013-12-08 22:07:05 【问题描述】:我正在尝试编写此查询来检索按日期分组的记录数:
SELECT system_date,count (is_paid)
FROM TPWEB.TP_CLIENT_TENDER_TRANS
where system_date between '1-DEC-12' and '31-DEC-12'
group by system_date
但是,我得到了没有分组的结果,例如:
01-DEC-12 1
01-DEC-12 1
01-DEC-12 1
01-DEC-12 1
怎么了……
【问题讨论】:
显示原始数据 那将提出这个查询SELECT system_date, is_paid FROM TPWEB.TP_CLIENT_TENDER_TRANS where system_date between '1-DEC-12' and '31-DEC-12'
不清楚您的表架构是什么,但我怀疑 system_date 是日期时间字段,而不是日期字段,这意味着您的分组不正确并且还包括该字段的时间部分.
【参考方案1】:
这对我有用:
select DT_FECHA_DESDE,DT_FECHA_HASTA
from (SELECT TRUNC(DT_FECHA_DESDE)as DT_FECHA_DESDE,TRUNC(DT_FECHA_HASTA) as DT_FECHA_HASTA
FROM TBL1
WHERE run='3456'
order by DT_FECHA_DESDE)
group by DT_FECHA_DESDE,DT_FECHA_HASTA
【讨论】:
【参考方案2】:使用 trunc 函数,DATE 数据类型保存时间,所以使用 trunc 我们可以截断时间。下面的查询有效!
SELECT trunc(system_date),count (is_paid)
FROM TPWEB.TP_CLIENT_TENDER_TRANS
where system_date between '1-DEC-12' and '31-DEC-12'
group by trunc(system_date);
【讨论】:
【参考方案3】:Oracle 中的DATE
列包含精确到毫秒的精度,而不仅仅是日期。如果您只对日期本身感兴趣,您应该TRUNC
删除小时、分钟等:
SELECT system_date,COUNT (is_paid)
FROM TPWEB.TP_CLIENT_TENDER_TRANS
WHERE system_date BETWEEN '1-DEC-12' AND '31-DEC-12'
GROUP BY TRUNC(system_date, 'DD-MON-YY')
【讨论】:
【参考方案4】:与documented 一样,DATE 数据类型是日期时间,因此除了您更合理地期望的属性之外,还存储小时、分钟和秒,以具有此名称的数据类型。如果要计算一天,则需要删除日期的时间部分。这是TRUNC()
的默认行为,因此您只需要这样做trunc(<date>)
。
此时有两点值得注意:
我假设system_date
是您表中的一列,而不是对SYSDATE 的误解
您的 between 子句完全不正确,非常危险。
根据您的日期表示方式,您的 NLS_DATE_FORMAT 似乎是 DD-MON-YYYY(有关详细信息,请参阅 another answer of mine)。这意味着当您将日期隐式转换为字符时,它会以这种格式进行转换。
您没有使用要比较的值的datetime literal 或explicit conversion,这意味着您的日期被隐式转换为字符。但是,当您进行比较时,您会发现事情并不总是像看起来那样。字符比较通常是二进制的;这意味着二月 10th 不在 1 月 10th 和 3 月 10th 之间; “三月”小于“一月”。
总是明确地转换日期并且总是在进行日期比较时使用日期。
将所有这些放在一起,您的查询就变成了:
select trunc(system_date), count(is_paid)`
from TPWEB.TP_CLIENT_TENDER_TRANS
where system_date between date '2012-12-01' and date '2012-12-31'
group by trunc(system_date)
【讨论】:
以上是关于使用按日期分组的 sql 查询的主要内容,如果未能解决你的问题,请参考以下文章