【问题标题】:Cartesian product and WHERE clause issue笛卡尔积和 WHERE 子句问题
【发布时间】:2013-03-05 16:32:37
【问题描述】:

让我们有一个简单的表格:

CREATE TABLE dbo.test
(
    c1  INT
)

INSERT INTO test (c1) VALUES (1)
INSERT INTO test (c1) VALUES (2)
INSERT INTO test (c1) VALUES (3)

接下来计算一些 SUM:

SELECT SUM(t1.c1) FROM test AS t1 , test AS t2
WHERE t2.c1 = 1

输出为: 6 。简单易行。

但如果我跑:

SELECT SUM(t1.c1), * FROM test AS t1 , test AS t2
WHERE t2.c1 = 1

输出是:

6   2   2
6   2   3
6   2   1
6   3   2
6   3   3
6   3   1
6   1   2
6   1   3
6   1   1

我的问题是:为什么第二个输出与 WHERE 子句中的条件不匹配?

【问题讨论】:

  • 第二次查询无效。我试过了(感谢创建可执行脚本!)。
  • 你确定这是 T-SQL 吗?我尝试在 SQL Server 2008 and get an error 中运行它。
  • 您的第二个查询对 T-SQL 无效
  • 各位,我正在使用 Sybase。
  • 您没有包含 group 子句 - 看起来 Sybase 只是执行 SELECT * 但允许您添加一个非分组聚合(它只是对整个表求和),它为所有行生成 6输出列表 - 不知道为什么它不尊重 WHERE

标签: sql tsql sap-ase cartesian-product


【解决方案1】:

Looks like Sybase implements it's own extensions to GROUP BY:

通过以下扩展,Sybase 解除了对哪些内容的限制 您可以在查询的选择列表中包含或省略 分组。

  • 选择列表中的列不限于分组列 以及与向量聚合一起使用的列。

  • group by 指定的列不限于那些 选择列表中的非聚合列。

但是,扩展的结果并不总是直观的:

当您在复杂查询中使用 Transact-SQL 扩展时 包括 where 子句或连接,结果可能会变得更多 很难理解。

这与您的问题有何关系?

但是,Adaptive Server 在 select list 和 where 子句可能看起来矛盾。例如:

select type, advance, avg(price) 
from titles 
where advance > 5000
group by type

type           advance
-------------  ---------  --------
business        5,000.00      2.99
business        5,000.00      2.99
business       10,125.00      2.99
business        5,000.00      2.99
mod_cook            0.00      2.99
mod_cook       15,000.00      2.99
popular_comp    7,000.00     21.48
popular_comp    8,000.00     21.48
popular_comp        NULL     21.48
psychology      7,000.00     14.30
psychology      2,275.00     14.30
psychology      6,000.00     14.30
psychology      2,000.00     14.30
psychology      4,000.00     14.30
trad_cook       7,000.00     17.97
trad_cook       4,000.00     17.97
trad_cook       8,000.00     17.97



(17 rows affected)

似乎查询忽略了where 子句 查看高级(扩展)列的结果。自适应服务器 仍然只使用那些满足的行来计算向量聚合 where 子句,但它也显示任何扩展的所有行 select 列表中包含的列。 进一步限制这些 结果中的行,您必须使用having 子句。

因此,为了给您预期的结果,Sybase 应该允许您这样做:

SELECT SUM(t1.c1), * FROM test AS t1 , test AS t2
WHERE t2.c1 = 1
HAVING t2.c1 = 1

WHERE 将从总数中排除结果 SUMHAVING 将隐藏不符合条件的记录。

令人困惑,不是吗?

相反,您最好编写查询,这样它就不需要 Sybase 的 GROUP BY 扩展。

【讨论】:

  • 这很奇怪也很神奇:)
猜你喜欢
  • 2012-02-23
  • 1970-01-01
  • 2017-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
相关资源
最近更新 更多