2

根据此查询,我缺少什么:

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 时,也出现错误 Column Header1 must be in a Group by 子句

4

2 回答 2

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编辑方式相同。

于 2013-03-29T08:56:12.843 回答
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 中工作),但它很有可能会。

于 2013-03-29T09:06:46.360 回答