【问题标题】:Converting PostgreSQL to MySQL将 PostgreSQL 转换为 MySQL
【发布时间】:2021-01-11 08:59:26
【问题描述】:

我正在学习有关如何在银行对帐单数据集中查找重复交易的教程。我拥有所需的所有数据,但在让查询与 MySQL 一起使用时遇到问题。关于如何将其转换为 MySQL 的任何想法?

WITH transactions_with_date_diff AS (
SELECT  
    ROW_NUMBER() OVER(PARTITION BY description ORDER BY accounting_date),
    accounting_date - LAG(accounting_date) OVER(PARTITION BY description ORDER BY accounting_date) AS date_diff,
    LAST_VALUE(amount) OVER(PARTITION BY description ORDER BY accounting_date) AS latest_amount,
    *
FROM transactions
)

SELECT
description,
COUNT(*) AS transactions_count,
MIN(accounting_date) AS subscription_started,
MAX(accounting_date) AS latest_transaction,
SUM(amount) AS total_amount
FROM transactions_with_date_diff
WHERE
date_diff IS NOT NULL
AND date_diff BETWEEN 25 AND 35
GROUP BY 1
HAVING COUNT(*) > 1
ORDER BY 2 DESC

错误是:

Query 1 ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '*
    FROM transactions
    )

    SELECT
    description,
    COUNT(*) AS trans' at line 6

更新

我根据反馈调整了 SQL 查询,并提供了示例数据。现在我收到一条不同的错误消息。

查询:

WITH transactions_with_date_diff AS (
    SELECT
        *,
        ROW_NUMBER() OVER(PARTITION BY description ORDER BY accounting_date),
        accounting_date - LAG(accounting_date) OVER(PARTITION BY description ORDER BY accounting_date) AS date_diff,
        LAST_VALUE(amount) OVER(PARTITION BY description ORDER BY accounting_date) AS latest_amount
    FROM transactions
)

SELECT
    description,
    COUNT(*) AS transactions_count,
    MIN(accounting_date) AS subscription_started,
    MAX(accounting_date) AS latest_transaction,
    SUM(amount) AS total_amount
FROM transactions_with_date_diff
WHERE
    date_diff IS NOT NULL
    AND date_diff BETWEEN 25 AND 35
GROUP BY 1
HAVING COUNT(*) > 1
ORDER BY 2 DESC;

返回以下错误:

Query 1 ERROR: Can't group on 'transactions_count'

示例表数据:

id accounting_date description amount
1 2020-12-31 APPLE.COM/BILL -24.03
2 2021-01-05 ALIEXPRESS.COM ALIEXPRESS -33
3 2021-01-11 MICROSOFT*XBOX -399.60

【问题讨论】:

  • 如果我没记错的话 * 必须在 mysql 的选择列表中排在第一位,除非用表名限定 - 但如果你使用列名而不是 * '使用不合格的 * 与其他项目一起会更好选择列表可能会产生解析错误。为避免此问题,请使用合格的 tbl_name.* 参考:' - dev.mysql.com/doc/refman/8.0/en/select.html
  • 你用的是什么版本的mysql? ctes 和窗口函数需要 8 或更高版本。
  • 请将示例数据和预期结果作为文本添加到问题中。
  • 您最初在主查询中按描述进行分组 - 您是否误将其删除?
  • 这是一个数据问题查询,按我的编码工作并产生预期结果;

标签: mysql sql common-table-expression


【解决方案1】:

这个查询应该在 MySQL 和 Postgres 中运行:

WITH transactions_with_date_diff AS (
      SELECT t.*,
            ( t.accounting_date - LAG(t.accounting_date) OVER (PARTITION BY t.description ORDER BY t.accounting_date) ) AS date_diff,
            LAST_VALUE(t.amount) OVER (PARTITION BY t.description ORDER BY t.accounting_date) AS latest_amount
      FROM transactions t
     )
SELECT tdd.description,
       COUNT(*) AS transactions_count,
       MIN(tdd.accounting_date) AS subscription_started,
       MAX(tdd.accounting_date) AS latest_transaction,
       SUM(tdd.amount) AS total_amount
FROM transactions_with_date_diff tdd
WHERE tdd.date_diff BETWEEN 25 AND 35
GROUP BY tdd.description
HAVING COUNT(*) > 1
ORDER BY transactions_count DESC;

事实上,这是标准 SQL,应该可以在几乎任何数据库中运行(假设支持该功能。请注意更改:

  • CTE 中没有未命名的列。我刚刚删除了ROW_NUMBER()
  • 所有表引用都有别名
  • GROUP BYORDER BY 子句不使用位置符号。
  • NOT NULL 比较是多余的。 BETWEEN 不会为 NULL 值返回 TRUE

【讨论】:

    【解决方案2】:

    我认为您的 AS 倒退了,您当前正在尝试将表分配给名称,而不是将名称分配给表。

    试试这个:

    WITH (
    SELECT  
        ROW_NUMBER() OVER(PARTITION BY description ORDER BY accounting_date),
        accounting_date - LAG(accounting_date) OVER(PARTITION BY description ORDER BY accounting_date) AS date_diff,
        LAST_VALUE(amount) OVER(PARTITION BY description ORDER BY accounting_date) AS latest_amount,
        *
    FROM transactions
    ) AS transactions_with_date_diff
    

    【讨论】:

    • 谢谢,但是现在我收到以下错误:Query 1 ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(SELECT ROW_NUMBER() OVER(PARTITION BY description ORDER BY accounti' at line 1
    • 似乎问题出在WITH 关键字上。
    猜你喜欢
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-11
    • 2021-10-30
    相关资源
    最近更新 更多