PHP / MYSQL - 计算有多少连续的前一周结果与当前一周具有相同的价值(音乐图表)
Posted
技术标签:
【中文标题】PHP / MYSQL - 计算有多少连续的前一周结果与当前一周具有相同的价值(音乐图表)【英文标题】:PHP / MYSQL - Counting How Many Consecutive Previous Weeks Results Have Same Value As Current Week (Music Charts) 【发布时间】:2021-11-30 10:32:42 【问题描述】:我正在苦苦尝试(但失败了)想出一个 mysql 查询来计算一首歌曲在之前连续几周内出现在同一图表位置的次数。例如,给定下面的数据集,我将如何编写一个查询(基于提供日期)返回:
歌曲名称 日期 图表位置 之前处于同一位置的周数(如果答案为 0 表示它在图表中上升或下降,则额外加分)id | song_name | date | chart_position |
---|---|---|---|
1 | Dancing Queen | 2020-01-19 | 1 |
2 | Wannabe | 2020-01-19 | 2 |
3 | Dancing Queen | 2020-01-12 | 1 |
4 | Shape Of You | 2020-01-12 | 2 |
5 | Blinding Light | 2020-01-05 | 1 |
6 | Wannabe | 2020-01-05 | 2 |
7 | Blinding Light | 2019-12-29 | 1 |
8 | Shape Of You | 2019-12-29 | 2 |
9 | Blinding Light | 2019-12-22 | 1 |
10 | Wannabe | 2019-12-22 | 2 |
所以给定一个简单的选择:
SELECT song_name, date, chart_position FROM table WHERE date = '2019-12-29' ORDER BY chart_position ASC
我们应该得到以下结果:
song_name | date | chart_position |
---|---|---|
Blinding Light | 2019-12-29 | 1 |
Shape Of You | 2019-12-29 | 2 |
但是需要添加额外的信息来制作它:
song_name | date | chart_position | weeks_in_position | movement (optional - same / new / up / down) |
---|---|---|---|---|
Blinding Light | 2019-12-29 | 1 | 2 | same |
Shape Of You | 2019-12-29 | 2 | 1 | new |
非常感谢任何帮助,因为我在过去的 6 个小时里一直在尝试自己通过大量在线搜索来解决问题,但无法解决!感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:很可能仍然可以进行一些优化,但以下内容将为您提供您所要求的所有输出。第一部分(CTE)基本上是用来计算一首歌曲在歌曲位置的连续周数。第二部分用于计算与前一周相比的位置,方法是将表连接到前一周。
WITH RECURSIVE cte AS (
SELECT id, song_name, 1 as weeks_in_position, chart_position, dt
FROM charts WHERE dt='2019-12-29'
UNION ALL
SELECT charts.id, charts.song_name, cte.weeks_in_position+1, charts.chart_position, charts.dt
FROM cte
INNER JOIN charts ON charts.song_name = cte.song_name
AND charts.chart_position = cte.chart_position
AND cte.id <> charts.id
AND DATEDIFF(cte.dt, charts.dt) <= 7
AND DATEDIFF(cte.dt, charts.dt) > 0
)
SELECT * FROM (
SELECT cte.song_name, cte.dt,
MAX(cte.weeks_in_position) OVER(PARTITION BY song_name) weeks_in_position,
CASE
WHEN charts.dt IS NULL THEN 'new'
WHEN cte.chart_position > charts.chart_position THEN 'up'
WHEN cte.chart_position < charts.chart_position THEN 'down'
ELSE 'same'
END AS movement
FROM cte
LEFT JOIN charts
ON cte.song_name = charts.song_name
AND DATE_ADD(charts.dt, INTERVAL 7 DAY)=cte.dt
) AS DATA
WHERE dt='2019-12-29'
你可以在这个db fiddle查看结果。
【讨论】:
感谢这与一些调整完美地工作(加入更多的表格)。我非常感谢您的帮助@vixducis【参考方案2】:您可以向表中添加新列以便于查询,例如 previous_chart_position 类型整数(相同/新/向上/向下的简单比较)和 chart_position_updatedat 日期时间以计算 week_in_position 的时间差。
【讨论】:
关系数据库的重点是不要有任何冗余数据。尽管 OP 的数据模型中已经存在冗余数据(最好将歌曲移动到单独的表中),但当您可以通过查询获得所需数据时,添加更多冗余并不是一个好的解决方案。 感谢@vixducis 的评论——我的数据实际上被分成了 2 个表(歌曲名称和信息在一个表中,而这个图表数据在另一个表中用 id 代替名称链接)。然而,为了便于理解这篇文章,我只是结合了这些信息(并计划根据需要自己稍微修改答案)。 :)以上是关于PHP / MYSQL - 计算有多少连续的前一周结果与当前一周具有相同的价值(音乐图表)的主要内容,如果未能解决你的问题,请参考以下文章
sql函数--07---Mysql取前一天,前一周,后一天等时间函数