Oracle PIVOT 中 COUNT() 缺失数据

标签 oracle count pivot literals

我正在对历史表中的事件进行计数,并希望以事件发生的月份为中心。基本查询是这样的:

SELECT TO_CHAR(Date_Entered, 'MONTH') AS Month, Userid FROM Customer_Order_History

实现 PIVOT 的完整查询如下所示:

SELECT * FROM
(SELECT TO_CHAR(Date_Entered, 'MONTH') AS Month, Userid FROM Customer_Order_History) 
PIVOT
(
    COUNT(*) AS Events
    FOR Month 
    IN ('JANUARY' AS Jan, 'FEBRUARY' AS Feb, 'MARCH' AS Mar, 'APRIL' AS Apr,
        'MAY' AS May, 'JUNE' AS Jun, 'JULY' AS Jul, 'AUGUST' AS Aug,
        'SEPTEMBER' AS Sep, 'OCTOBER' AS Oct, 'NOVEMBER' AS Nov, 'DECEMBER' AS Dec)
)

此查询有效并且运行良好。除了结果中,我应该有 7 月、8 月和 9 月的事件进行计数,除了 9 月之外,一切都是零。

问题出在 PIVOT 的 IN() 子句中的文字值。我来自 FoxPro 背景,其中字符串数据列的长度不可变,因此 "JULY""JULY " 不同(JULY 加五个空格) 。然后,我凭直觉将 IN() 中的文字更改为长度全部为 9 个字符(月份名称可以是最长的),然后 7 月和 8 月开始报告计数。

当然,更好的方法是使用更一致的月份格式,例如仅使用前三个字符或使用月份索引。但上述行为对我来说似乎很奇怪。毕竟,如果我将 VARCHAR(100) 与 VARCHAR(2000) 进行比较,并且它们都是“JULY”,那么在 WHERE 子句或 JOIN 中,它们将被视为相等。在 FoxPro 中进行比较时,我习惯将字符串填充到一定的宽度,而不是在 Oracle 中。

还有其他人在 PIVOT 中看到过这一点吗?我在 Oracle 中是否遗漏了一些更大的概念,其中 VARCHAR 列的大小突然开始变得重要(我应该注意的其他情况)?

最佳答案

这与旋转或一般字符串比较无关;这是关于月份名称是如何产生的。 From the documentation :

The character elements MONTH, MON, DAY, and DY are padded with trailing blanks to the width of the longest full month name, the longest abbreviated month name, the longest full date name, or the longest abbreviated day name, respectively, among valid names determined by the values of NLS_DATE_LANGUAGE and NLS_CALENDAR parameters. For example, when NLS_DATE_LANGUAGE is AMERICAN and NLS_CALENDAR is GREGORIAN (the default), the largest element for MONTH is SEPTEMBER, so all values of the MONTH format element are padded to nine display characters. ...

...这正是您所看到的。与数据透视子句中的文字的比较仍然使用 nonpadded character semantics - 但是 to_char() 生成的字符串被填充为九个字符,而您的文字则没有,因此它们不匹配。

如果您更改基本查询以添加 FM 格式修饰符,则它不会填充名称:

TO_CHAR(Date_Entered, 'FMMONTH')

由于您的数据透视子句依赖于英文名称,因此您可能还想强制使用该名称,从而覆盖运行代码的人的 session NLS 设置:

TO_CHAR(Date_Entered, 'FMMONTH', 'NLS_DATE_LANGUAGE=ENGLISH')

它总是会给你“MAY”、“JUNE”等,没有填充;或

TO_CHAR(Date_Entered, 'FMMonth', 'NLS_DATE_LANGUAGE=ENGLISH')

它总是会给你“五月”、“六月”等,仍然没有填充,但在数据透视表列表中看起来不那么喧闹。

关于Oracle PIVOT 中 COUNT() 缺失数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73829558/

相关文章:

MySQL : issue with GROUP BY and COUNT clauses

R 如何计算数据框多列中值的出现次数,并将特定值的按列计数保存为新行?

c# - 如何在 C# 中的枢轴后创建两个暗数组

database - 我可以通过数据库链接编译大型存储过程吗?

显示工资变化的 SQL 触发器

oracle - 确定使用 Oracle utl_http 执行 https post 需要哪个证书

r - 计算每组的完整个案

sql - 查询以水平显示输出

python - 具有两列列表的旋转数据框

java - 多个键和值