【发布时间】:2021-08-05 05:22:45
【问题描述】:
我正在尝试用 PHP 和 MySQL 编写一个具有不同级别的简单游戏。在每个关卡中,用户都可以使用提示来解决关卡。
现在我想建立一个排行榜来显示所有用户的排名,按已解决的级别、开始日期和新内容排序:基于惩罚逻辑的提示。
惩罚逻辑是:
对于用户采取的每个提示,都应该以秒/分钟为单位进行处罚。
- 对于关卡中的第一个提示,用户将获得 30 秒的惩罚
- 第二次提示 -> 1 分钟
- 第三次提示 -> 3 分钟
- 第四次提示 -> 5 分钟
- 对于第 5 次提示和之后的每一次 -> 8 分钟
此逻辑适用于每个级别,例如当用户在第一关接受 1 次提示,在第二关接受 3 次提示时,总惩罚应该是 5 分钟 =(30 秒 + 30 秒 + 1 分钟 + 3 分钟)。
我不知道如何在查询中解决这个问题以获得有序的输出。 SELECT 查询应该返回凭证,按解决的级别和所需的总时间排序。我想过从开始日期减去罚款。
你可以在这里找到我的数据库结构
CREATE TABLE `vouchers` (
`voucher_id` int(11) NOT NULL,
`voucher_started` tinyint(1) NOT NULL DEFAULT 0,
`voucher_date_started` datetime NOT NULL,
`voucher_levels_solved` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT;
INSERT INTO `vouchers` (`voucher_id`, `voucher_started`, `voucher_date_started`, `voucher_levels_solved`) VALUES
(1, 1, '2021-05-15 08:05:00', 2),
(2, 1, '2021-05-15 08:03:00', 2),
(3, 1, '2021-05-15 08:08:00', 2);
CREATE TABLE `hints_taken` (
`hint_id` int(11) NOT NULL,
`hint_voucher_id` int(11) NOT NULL,
`hint_level` int(11) NOT NULL,
`hint_category` int(11) NOT NULL,
`hint_number` int(11) NOT NULL,
`hint_date_taken` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp()
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO `hints_taken` (`hint_id`, `hint_voucher_id`, `hint_level`, `hint_category`, `hint_number`, `hint_date_taken`) VALUES
(1, 1, 1, 0, 1, '2021-05-14 12:11:46'),
(2, 1, 1, 0, 2, '2021-05-14 12:11:47'),
(3, 1, 1, 0, 3, '2021-05-14 12:11:47'),
(4, 1, 1, 0, 4, '2021-05-14 12:11:48'),
(5, 1, 2, 0, 1, '2021-05-15 09:00:33'),
(6, 1, 2, 1, 1, '2021-05-15 09:00:33'),
(7, 1, 2, 1, 2, '2021-05-15 09:00:33'),
(8, 1, 3, 0, 1, '2021-05-15 09:00:47'),
(9, 1, 3, 1, 1, '2021-05-15 09:00:47'),
(10, 2, 7, 0, 1, '2021-05-15 09:00:48'),
(11, 2, 7, 0, 2, '2021-05-15 09:00:48'),
(12, 2, 7, 1, 1, '2021-05-15 09:00:49'),
(13, 2, 7, 1, 2, '2021-05-15 09:00:49'),
(14, 2, 7, 2, 1, '2021-05-15 09:00:50'),
(15, 3, 5, 0, 1, '2021-05-15 09:01:19'),
(16, 3, 5, 0, 2, '2021-05-15 09:01:19'),
(17, 3, 5, 0, 3, '2021-05-15 09:01:20'),
(18, 3, 5, 0, 4, '2021-05-15 09:01:20'),
(19, 3, 5, 0, 5, '2021-05-15 09:01:21'),
(20, 3, 9, 0, 1, '2021-05-15 09:05:48');
或通过此链接: https://www.db-fiddle.com/f/aEs1gX1CCGFTVvb5ddkRXG/0
如果有人可以帮助我如何构建这样的查询,将非常高兴。
借助 Jayvee 的解决方案
SELECT voucher_id,
UNIX_TIMESTAMP (NOW()) - UNIX_TIMESTAMP(`voucher_date_started`) + SUM(`penalty`) as `total_time_needed`
FROM `vouchers` v
JOIN
(Select `hint_voucher_id`, `hint_level`,sum(
case when `hint_number`=1 then 30
when `hint_number`=2 then 60
when `hint_number`=3 then 180
when `hint_number`=4 then 300
when `hint_number`>4 then 480
else 0 end) as `penalty`
from `hints_taken`
group by `hint_voucher_id`,`hint_level`) as h
ON h.`hint_voucher_id`= v.`voucher_id`
GROUP BY `voucher_id`
ORDER BY `total_time_needed`
【问题讨论】: