【问题标题】:ORDER BY Alias not workingORDER BY 别名不起作用
【发布时间】:2011-09-21 11:13:40
【问题描述】:

更新问题:

ERROR:  column "Fruits" does not exist

运行 Postgres 7.4(是的,我们正在升级)

为什么我不能按列别名排序? ORDER BY 中也想要 tof."TypeOfFruits",为什么?

SELECT (CASE
    WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
    WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
    WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
    ELSE 'Other' END) AS "Fruits",
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('DAY', LOCALTIMESTAMP) AND DATE_TRUNC('DAY', LOCALTIMESTAMP) + INTERVAL '1 DAY' 
        THEN 1 ELSE 0 END) AS daily, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('MONTH', LOCALTIMESTAMP) AND DATE_TRUNC('MONTH', LOCALTIMESTAMP) + INTERVAL '1 MONTH' 
        THEN 1 ELSE 0 END) AS monthly, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('YEAR', LOCALTIMESTAMP) AND DATE_TRUNC('YEAR', LOCALTIMESTAMP) + INTERVAL '1 YEAR' 
        THEN 1 ELSE 0 END) AS yearly, 
    SUM(CASE WHEN r.order_date >= '01-01-2011 00:00:00' THEN 1 ELSE 0 END) AS lifetime 
FROM reports AS r, "TypeOfFruits" AS tof 
WHERE r.id = tof."ID" 
GROUP BY "Fruits"
ORDER BY CASE 
    WHEN "Fruits" = 'Apple' THEN 1 
    WHEN "Fruits" = 'Pear' THEN 2 
    WHEN "Fruits" = 'Grapes' THEN 3 
    ELSE 4 
END

目前的结果

Fruits;daily;monthly;yearly;lifetime
"Apple";17;1174;3136;3136
"Pear";28;94;94;94
"Grapes";0;191;490;490
"Other";0;2;27;27
"Other";0;0;1;1
"Other";0;0;27;27
"Other";0;6;28;28
"Other";0;58;229;229
"Other";0;3;3;3
"Other";0;0;1;1

所需的结果是一行,总数为“其他”,所以总共四行 (x 是总数)

Fruits;daily;monthly;yearly;lifetime
"Apple";17;1174;3136;3136
"Pear";28;94;94;94
"Grapes";0;191;490;490
"Other";x;x;x;x

【问题讨论】:

  • 为什么 Fruit 被拼错为 Friut 10 次?
  • 好的,我修复了拼写问题(你复制粘贴)并稍微更新了问题
  • 干得好,我喜欢下面@Joe 的回答。

标签: sql postgresql group-by aggregate-functions


【解决方案1】:

别名是在 order by 之后分配的,因此您不能在 order by 中使用它。改用这个:

(CASE
    WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
    WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
    WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
    ELSE 'Other' END)

【讨论】:

  • 如果我删除 AS“Fruits”别名,GROUP by 现在已关闭,所以我还有多行其他。还是我错过了什么?
  • 为什么要删除它?您可以保留它,但不能在 group by 或 order by 子句中引用它
  • 我在 ORDER BY w/@Adrian GROUP BY 1 答案中使用它,但现在 ORDER BY 不是我想要的顺序。它是按字母顺序排列的,有什么想法吗? +1
【解决方案2】:

您可以尝试这样的事情......未经测试,但我看到过类似的查询。
让我知道它是否有效...

SELECT "Fruits",
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('DAY', LOCALTIMESTAMP) AND DATE_TRUNC('DAY', LOCALTIMESTAMP) + INTERVAL '1 DAY' 
        THEN 1 ELSE 0 END) AS daily, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('MONTH', LOCALTIMESTAMP) AND DATE_TRUNC('MONTH', LOCALTIMESTAMP) + INTERVAL '1 MONTH' 
        THEN 1 ELSE 0 END) AS monthly, 
    SUM(CASE WHEN r.order_date 
        BETWEEN DATE_TRUNC('YEAR', LOCALTIMESTAMP) AND DATE_TRUNC('YEAR', LOCALTIMESTAMP) + INTERVAL '1 YEAR' 
        THEN 1 ELSE 0 END) AS yearly, 
    SUM(CASE WHEN r.order_date >= '01-01-2011 00:00:00' THEN 1 ELSE 0 END) AS lifetime 
FROM reports AS r
    ,(SELECT "ID",
             CASE
                WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
                WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
                WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
                ELSE 'Other'
             END AS "Fruits" FROM "TypeOfFruits" ) AS "tof"
WHERE r.id = tof."ID" 
GROUP BY "Fruits"
ORDER BY CASE 
    WHEN "Fruits" = 'Apple' THEN 1 
    WHEN "Fruits" = 'Pear' THEN 2 
    WHEN "Fruits" = 'Grapes' THEN 3 
    ELSE 4 
END

【讨论】:

    【解决方案3】:

    您可以使用ORDER BY 1 按第一个字段“水果”进行排序。同样适用于GROUP BY

    更新

    对于订单,不要在order by 中执行case,而是在...说...第二个位置创建一个新列:

    (CASE 
        WHEN "Fruits" = 'Apple' THEN 1 
        WHEN "Fruits" = 'Pear' THEN 2 
        WHEN "Fruits" = 'Grapes' THEN 3 
        ELSE 4 ) as Order
    

    然后在你ORDER BY 2

    【讨论】:

    • 这确实对 GROUP BY 有帮助,我正在使用@Joe Philllips ORDER BY,但 ORDER BY 现在是按字母顺序排列的,而不是我想要的顺序,因此我的示例中的数值。 +1
    • 尝试这个,但现在它想要 GROUP BY tof."TypeOfFruits"
    【解决方案4】:

    考虑这样的事情:

    SELECT * FROM (SELECT (CASE
        WHEN tof."TypeOfFruits" = 'A' THEN 'Apple' 
        WHEN tof."TypeOfFruits" = 'P' THEN 'Pear' 
        WHEN tof."TypeOfFruits" = 'G' THEN 'Grapes' 
        ELSE 'Other' END) AS "Fruits", 
        (CASE 
        WHEN tof."TypeOfFruits" = 'A' THEN 1 
        WHEN tof."TypeOfFruits" = 'P' THEN 2 
        WHEN tof."TypeOfFruits" = 'G' THEN 3 
        ELSE 4 END) as NUM
    
            FROM ..... <rest of your query without group by and order by .....
        )
    
    GROUP BY Fruits
    ORDER BY NUM
    

    【讨论】:

    • 我喜欢这个想法,但它仍然想要 GROUP BY 中的 tof."TypeOfFruits"。错误:FROM 中的子查询必须有别名
    • 不知道为什么。外部查询应该只需要 Fruits 和 NUM。你能详细说明一下吗?
    【解决方案5】:

    原因可以在documentation找到:

    [在 ORDER BY 列表中] 的每个表达式可以是 output 列(SELECT 列表项)的名称或序号,也可以是由 input - 列值。

    (我的重点)

    原因是旧版本的 SQL 标准 (SQL-92) 仅允许按输出列名称或编号排序,而较新版本允许按任意表达式排序,但这些表达式是由输入列值形成的。

    其他答案已经包含适合您情况的各种解决方法。

    【讨论】:

      【解决方案6】:

      尝试使用反引号 (`) 而不是单/双引号来包裹您的别名。

      MySQL 也有同样的问题;反引号解决了这个问题。

      【讨论】:

      • MySQL 使用反引号,PostgreSQL 使用双引号,就像在 SQL 标准中一样。 MySQL 不符合标准。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-21
      • 1970-01-01
      • 2014-08-03
      • 1970-01-01
      • 2012-04-13
      • 2014-01-13
      • 1970-01-01
      相关资源
      最近更新 更多