Alias的Informix Group

时间:2013-03-29 07:54:54

标签: sql group-by informix

根据此查询,我错过了什么:

SELECT mymonth, Header1
FROM
(
SELECT month(startdatetime) as mymonth, (CASE WHEN MyTable.somecolumn =2 THEN count(somecolumn2) END) as Header1
FROM MyTable WHERE year(startdatetime)=2013
group by startdatetime 

) x
GROUP BY Header1

在某些地方我已经知道Informix不支持别名分组但是在尝试设置时 GROUP BY 2,也有错误 列Header1必须位于Group by子句

2 个答案:

答案 0 :(得分:3)

这是你在查询中得到的一些非常特殊的语法。我认为这是导致问题的CASE陈述。

在这个更简单的版本中没有达到的目标是什么?

SELECT MONTH(startdatetime) AS mymonth, COUNT(*) AS header1
  FROM MyTable
  WHERE YEAR(startdatetime) = 2013
    AND somecolumn = 2
GROUP BY 1

如果您尝试使用CASE声明做一些比您放入样本更加时髦的事情,那么我建议尝试这样的事情:

SELECT ...., SUM(DECODE(somecolumn, 2, 1, 0))

...但是当您使用不同的谓词执行多个SUM()s时,通常会使用这种语法。


更新

如果有多个谓词用于计数,我喜欢这样做:

SELECT ....
    SUM(CASE WHEN col1 = 1 THEN 1 ELSE 0 END) AS count1,
    SUM(CASE WHEN col3 = 7 AND col5 = 0 THEN 1
             WHEN col3 = 5 AND col5 = 1 THEN 1
             ELSE 0 END) AS count2
  FROM ....

这为您提供了很大的灵活性,可以在1个SQL语句中计算很多不同的东西,只要它们以相同的方式GROUP编辑。

答案 1 :(得分:1)

您的SQL非常不寻常。 Informix服务器对CASE表达式是否为聚合感到困惑 - 我也是如此。如上所述,您最好将查询重写为:

SELECT mymonth, Header1
  FROM (SELECT MONTH(startdatetime) AS mymonth,
               COUNT(somecolumn2)   AS Header1
          FROM MyTable
         WHERE YEAR(startdatetime) = 2013
           AND SomeColumn = 2
         GROUP BY startdatetime
       ) AS x
-- GROUP BY Header1;
;

我可以看到(注释掉的)外层GROUP BY子句没有理由。鉴于以下测试数据:

CREATE TEMP TABLE MyTable
(
    startdatetime   DATE NOT NULL,
    somecolumn      INTEGER NOT NULL,
    somecolumn2     VARCHAR(10)
);

INSERT INTO MyTable VALUES('2013-03-01', 2, NULL);
INSERT INTO MyTable VALUES('2013-03-02', 2, 'Elephant');
INSERT INTO MyTable VALUES('2013-03-03', 2, 'Rhinoceros');
INSERT INTO MyTable VALUES('2013-03-04', 1, 'Elephant');
INSERT INTO MyTable VALUES('2013-03-05', 3, 'Rhinoceros');

查询的输出是:

mymonth      header1
SMALLINT     DECIMAL(15,0)
     3               0
     3               1
     3               1

但是,我怀疑你已经做了一些查询最小化来说明问题(如果是这样,谢谢),实际上你的主要子查询会有一些类似的CASE表达式,而不仅仅是一个。在这种情况下,您应该沿着这些行重写CASE表达式和聚合:

SELECT mymonth, Header1
  FROM (SELECT MONTH(startdatetime) AS mymonth,
               COUNT(CASE WHEN MyTable.somecolumn = 2 THEN somecolumn2 END) AS Header1
          FROM MyTable
         WHERE YEAR(startdatetime) = 2013
         GROUP BY mymonth 
       ) AS x
;

对于相同的样本数据,这会产生:

mymonth     header1
SMALLINT    DECIMAL(15,0)
     3               2

鉴于您使用的是IBM Informix 11.50而不是11.70或12.10,您可能必须使用此变体来完成聚合:

SELECT MonthNum, COUNT(Header1) AS Header1
  FROM (SELECT MONTH(startdatetime) AS MonthNum,
               CASE WHEN MyTable.somecolumn = 2 THEN somecolumn2 END AS Header1
          FROM MyTable
         WHERE YEAR(startdatetime) = 2013
       ) x
 GROUP BY MonthNum;

输出:

monthnum    header1
SMALLINT    DECIMAL(15,0)
     3               2

基本思想是使用CASE表达式在子查询的Header1列中生成所需的值,然后将聚合应用于子查询的结果(而不是在子查询中聚合) )。我没有证实这将在11.50(它在11.70.FC6中)有效,但它有一个很好的机会。