笛卡尔积和WHERE子句问题

时间:2013-03-05 16:32:37

标签: sql tsql sybase-ase cartesian-product

让我们有简单的表格:

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子句中的条件不匹配?

1 个答案:

答案 0 :(得分:6)

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

  

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

     
      
  • 选择列表中的列不限于分组列   和用于向量聚合的列。

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

  •   

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

  

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

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

  

但是,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)
     

当您查询时,似乎只是忽略了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

WHERE将从总SUM中排除结果; HAVING将隐藏与条件不匹配的记录。

令人困惑,不是吗?

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