将 PostgreSQL 转换为 MySQL
Converting PostgreSQL to MySQL
我正在学习如何在银行对账单数据集中查找经常性交易的教程。我拥有所需的所有数据,但在使用 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'
示例 table 数据:
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
我认为您的 AS 倒退了,您目前正在尝试将 table 分配给名称,而不是将名称分配给 table。
试试这个:
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
此查询在 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()
.
- 所有 table 引用都有别名
GROUP BY
和 ORDER BY
子句不使用位置符号。
NOT NULL
比较是多余的。对于 NULL
值,BETWEEN
不会 return TRUE
。
我正在学习如何在银行对账单数据集中查找经常性交易的教程。我拥有所需的所有数据,但在使用 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'
示例 table 数据:
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 |
我认为您的 AS 倒退了,您目前正在尝试将 table 分配给名称,而不是将名称分配给 table。
试试这个:
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
此查询在 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()
. - 所有 table 引用都有别名
GROUP BY
和ORDER BY
子句不使用位置符号。NOT NULL
比较是多余的。对于NULL
值,BETWEEN
不会 returnTRUE
。