【问题标题】:Correlated MySQL subquery to Postgre将 MySQL 子查询关联到 Postgre
【发布时间】:2020-06-06 13:06:51
【问题描述】:

MySQL 支持相关子查询,并且也可以正常工作以从我的数据库中获取记录...但我需要在 AWS Redshift 上运行相同的查询以带来相同的记录,但它给出了This type of correlated subquery pattern is not supported yet 的错误

MYSQL 查询

SELECT IFNULL((SELECT IF (c.c_id,'',0) FROM customer c WHERE c.c_id = o.c_id AND DATE (c.date) >= DATE ('2020-01-24') AND DATE (c.date) <= DATE ('2020-02-22')),'BCK') AS cstatus,
   IF (o.os_id = 0,'Missing','Place') AS 'os',
   IFNULL(COUNT(DISTINCT o.c_id),0) AS 'customers',
   IFNULL(COUNT(o.o_id),0) AS 'orders',
   IFNULL(SUM(o.total),0) AS 'cell'
FROM order o
WHERE 1
AND   DATE (o.date) >= DATE ('2020-01-24')
AND   DATE (o.date) <= DATE ('2020-02-22')
GROUP BY cstatus,
     ostatus
ORDER BY cstatus,
     ostatus DESC

Postgresql 查询

SELECT COALESCE((SELECT CASE WHEN c.c_id THEN NULL ELSE 0 END FROM customer c WHERE c.c_id = o.c_id AND DATE (c.date) >= DATE ('2020-01-24') AND DATE (c.date) <= DATE ('2020-02-22')),'BCK') AS cstatus,
   CASE WHEN o.os_id = 0 THEN 'Missing' ELSE 'Place' END AS ostatus,
   COALESCE(COUNT(DISTINCT o.c_id),0) AS customers,
   COALESCE(COUNT(o.o_id),0) AS orders,
   COALESCE(SUM(o.total),0) AS cell
FROM order o
WHERE 1
AND   DATE (o.date) >= DATE ('2020-01-24')
AND   DATE (o.date) <= DATE ('2020-02-22')
GROUP BY cstatus,
     ostatus
ORDER BY cstatus,
     ostatus DESC

这个postgre 查询给了我2 错误。 1- at 'BCK'2- correlated subquery error。 (对于'BCK',如果我输入整数它可以工作,但我需要字符串)

预期的结果将如附图所示。

如何在 AWS Redshift 中处理此问题

【问题讨论】:

  • 您应该通过包含示例数据来完成您的问题。
  • 数据很简单... order_id、Order_status、customer_id、count(orders) 和 total_sale ...都是整数数据类型。
  • 您的评论对您的问题没有帮助。我们想了解输入数据的样子以及输出的样子。
  • 在订单和客户之间做一个标准的左连接

标签: mysql sql postgresql amazon-redshift


【解决方案1】:

你的代码会更容易理解,并解释它试图做什么。代码看起来很可疑,仅仅是因为它是一个标量子查询,但不能保证它永远不会返回超过一行(比如使用LIMIT 或聚合)。

但是,这似乎表明每个订单最多有一个客户。有了这个假设,您可以用某种JOIN 替换逻辑而不影响计算:

SELECT (CASE WHEN c.c_id IS NOT NULL THEN 'BCK' END) AS cstatus,
       (CASE WHEN o.os_id = 0 THEN 'Missing' ELSE 'Place' END) AS os,
       COUNT(DISTINCT o.c_id) AS customers,
       COUNT(o.o_id) AS orders,
       COALESCE(SUM(o.total), 0) AS cell
FROM order o LEFT JOIN
     customer c
     ON c.c_id = o.c_id AND
        c.date >= DATE('2020-01-24') AND
        c.date < DATE ('2020-02-23')
WHERE o.date >= DATE('2020-01-24') AND
      o.date < DATE('2020-02-23')
GROUP BY cstatus, ostatus
ORDER BY cstatus, ostatus DESC;

注意查询的其他更改:

  • 使用&lt; 进行第二次比较,日期比较适用于时间和日期。这对于优化和分区修剪可能很重要(取决于数据库)。
  • COUNT()COUNT(DISTINCT) 永远不会返回 NULL 值,因此将 NULLs 替换为 0 只是浪费代码。
  • 仅对字符串和日期常量使用单引号。不要在任何数据库中使用它们作为列别名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-22
    • 1970-01-01
    • 1970-01-01
    • 2015-04-30
    相关资源
    最近更新 更多