笛卡尔积和WHERE子句问题

www*_*www 1 sql t-sql cartesian-product sybase-ase

我们有简单的表格:

CREATE TABLE dbo.test
(
    c1  INT
)

INSERT INTO test (c1) VALUES (1)
INSERT INTO test (c1) VALUES (2)
INSERT INTO test (c1) VALUES (3)
Run Code Online (Sandbox Code Playgroud)

接下来计算一些SUM:

SELECT SUM(t1.c1) FROM test AS t1 , test AS t2
WHERE t2.c1 = 1
Run Code Online (Sandbox Code Playgroud)

输出为:6.简单易行.

但如果我跑:

SELECT SUM(t1.c1), * FROM test AS t1 , test AS t2
WHERE t2.c1 = 1
Run Code Online (Sandbox Code Playgroud)

输出是:

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
Run Code Online (Sandbox Code Playgroud)

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

Mic*_*son 6

看起来Sybase实现了它自己的扩展GROUP BY:

通过以下扩展,Sybase解除了对包含group by的查询的选择列表中可包含或省略的内容的限制.

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

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

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

在包含where子句或联接的复杂查询中使用Transact-SQL扩展时,结果可能变得更加难以理解.

这与你的问题有什么关系?

但是,Adaptive Server处理select列表中的额外列的方式 和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)
Run Code Online (Sandbox Code Playgroud)

where当您查看advance(扩展)列的结果时,似乎只是查询忽略了该子句.Adaptive Server仍然仅使用满足where子句的那些行来计算向量聚合,但它还会显示select列表中包含的任何扩展列的所有行.要从结果中进一步限制这些行,必须使用having子句.

因此,为了给您提供您期望的结果,Sybase应该允许您:

SELECT SUM(t1.c1), * FROM test AS t1 , test AS t2
WHERE t2.c1 = 1
HAVING t2.c1 = 1
Run Code Online (Sandbox Code Playgroud)

WHERE会排除从总的结果SUM; 在HAVING将隐藏不符合条件的记录.

令人困惑,不是吗?

相反,您可能最好不要编写查询,以便它不需要Sybase的GROUP BY扩展.