【发布时间】:2021-12-07 23:33:49
【问题描述】:
我正在尝试为过去 7 天内的每个日期生成 7 行,并加入来自transactions 表的查询。目的是有一个包含每个日期的表格,以及从第一个条目到该日期的 transactions 中的 quantity 列的累积总数:
| date | stockOnDate |
|---------------|---------------|
| 2021-10-15 | 10 |
| 2021-10-16 | 3 |
| 2021-10-17 | 0 |
| 2021-10-18 | 9 |
| 2021-10-19 | 15 |
| 2021-10-20 | 15 |
| 2021-10-21 | 15 |
我可以获取日期列表,并且可以加入,但无法过滤嵌套查询:
SELECT v.*, t.*
FROM ( SELECT DATE(ADDDATE(DATE_SUB(NOW(),INTERVAL 7 DAY), t3*1000 + t2*100 + t1*10 + t0)) AS `date`
FROM (SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3 ) AS v
LEFT JOIN (SELECT SUM(quantity) AS stockOnDate, DATE(timestamp) as tDate
FROM `transactions`
WHERE tDate <= v.`date`) AS t ON t.tDate = v.`date`
WHERE v.`date` >= DATE_SUB(NOW(),INTERVAL 7 DAY) AND v.`date` <= DATE(NOW())
但我收到以下错误:
#1054 - Unknown column 'tDate' in 'where clause'
如果我将 WHERE tDate <= v.date 替换为 WHERE DATE(timestamp) <= v.date,我会收到相同的 v.date 错误 - 我似乎无法访问父表的值。
我对 MySQL 不是很好,但似乎找不到解决方案,我哪里出错了?
ProGuru 的解决方案
感谢ProGuru's answer below,以下查询按预期工作(在JOIN 中使用<= 而不是= 是关键)
SELECT b.date, SUM(a.quantity) AS stockOnDate
FROM (
SELECT DATE(ADDDATE(DATE_SUB(NOW(),INTERVAL 6 DAY), t3*1000 + t2*100 + t1*10 + t0)) AS `date`
FROM (SELECT 0 t0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t0,
(SELECT 0 t1 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t1,
(SELECT 0 t2 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t2,
(SELECT 0 t3 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9) t3
) b
LEFT JOIN transactions a ON DATE(a.timestamp) <= b.date
WHERE b.date BETWEEN DATE(NOW()) - INTERVAL 6 DAY AND DATE(NOW())
AND a.organisationId = 1
GROUP BY b.date
ORDER BY b.date ASC
我还可以将 GROUP BY 更改为 GROUP BY a.itemID, b.date 以获取每个 itemId 在给定日期的库存水平。
【问题讨论】:
-
.. WHERE tDate <= v.`date` ..您不能在 WHERE 中使用输出列别名 (tDate)。要么改用它的表达式 (DATE(timestamp)),要么在 HAVING 中应用这个条件。此外,在指定 LATERAL 之前,您不能从另一个子查询 (v.date) 引用子查询列。 -
你的 MySQL 精确版本是多少?此外,我建议您使用示例数据创建在线小提琴,并提供所需的输出和详细的解释。当然,对于更短的数据范围...
-
不幸的是,与
HAVIING的结果相同,正如我所说,使用DATE(timestamp会导致与v.date相同的问题。使用 10.4.19-MariaDB,想要的结果在帖子的开头 -
不幸的是 HAVIING 的结果相同 我预测这一点 - “另外,在指定 LATERAL 之前,您不能从另一个子查询 (v.date) 引用子查询列。” 使用 10.4.19-MariaDB 对于这个版本,您的查询应该完全重写 - 使用序列或递归 CTE 生成日期列表,使用窗口函数进行累积和计算。
-
期望的结果在文章的开头你认为没有源数据的期望输出可能有意义吗?
标签: mysql sql join subquery nested-queries