【问题标题】:Why does DISTINCT change case of literal string为什么 DISTINCT 会改变文字字符串的大小写
【发布时间】:2021-01-12 12:19:55
【问题描述】:

我对 Access 数据库进行了以下简化查询:

  • 构建表:CREATE TABLE test (id TEXT)
  • 填充:INSERT INTO test VALUES ('4711')
  • 查询:
SELECT
  id, 
  'value',
  'Value'
FROM 
  test

产量

id Expr1001 Expr1002
4711 value Value

现在DISTINCT 的相同查询改变了第二个文字字符串的大小写:

SELECT DISTINCT
  id, 
  'value',
  'Value'
FROM 
  test

产量

id Expr1001 Expr1002
4711 value value

无论查询是通过 OleDb 还是直接通过 MS Access,结果都是一样的。数据库引擎如何更改文字值?我知道 jet sql 有时很奇怪 - 但这在我看来就像一个错误。还是在某处描述了这种行为?

【问题讨论】:

  • Shoot - 有人知道为什么表格在草稿中正确绘制并且在发布时看起来像这样吗?
  • 表格前的换行符,如果前面没有换行符,CommonMark 不能正确处理内容。尝试询问错误时遇到错误;)

标签: ms-access oledb jet


【解决方案1】:

这主要是猜测,但我认为正在发生的事情如下:

SELECT DISTINCT x 等于 SELECT x GROUP BY x 并转换为它。

GROUP BY 中的列被去重,'value' 根据排序规则等于'Value',因此只处理第一个匹配项。

对于每一列,它可以是一个常量(计算一次)、一个聚合列(为每个组计算)或一个组列。由于'value' 在GROUP BY 中并且'Value' 等于'value',因此它们都映射到组'value'

当按单个列分组时,我们也可以看到这种行为:

SELECT
  id, 
  'value',
  'Value'
FROM 
  test
GROUP BY
  id

GROUP BY 子句中没有“值”,解析为表达式

id Expr1001 Expr1002
4711 value Value
SELECT
  id, 
  'value',
  'Value'
FROM 
  test
GROUP BY
  id, 'valuE'

'value' 和 'valuE' 相等,因此 Expr1001 是组列 'valuE,'Value' 也是如此

id Expr1001 Expr1002
4711 valuE valuE

使用来自GROUP BY 子句的字符串,即使两个字符串都没有使用该大写。

据我所知,这种行为没有记录在案。记录的是在评估组时忽略大写,例如你可以做SELECT ID, MAX(SomeColumn) FROM MyTable GROUP BY id 并且Access 不会抱怨GROUP BY 子句中没有ID 列,但这很奇怪这也适用于常量和DISTINCT。显而易见的解决方法是:不要按常量分组,当您有一个带有常量的 SELECT 子句时,使用 GROUP BY 而不是 DISTINCT。

如果我们将此行为与 T-SQL 进行比较,它不允许在 GROUP BY 部分中使用常量,因此不会遇到这种行为。 GROUP BY id, 'valuE' 不是有效的 T-SQL。

【讨论】:

  • 听起来很合理,尽管这可能只是猜测。除非有人提出有关此行为的任何文档,否则这将成为公认的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-20
  • 1970-01-01
  • 2012-02-27
  • 1970-01-01
  • 1970-01-01
  • 2014-02-04
相关资源
最近更新 更多