我正在尝试教授我的 sql 并正在做 hackerrank 练习题。我遇到了奥利凡德的库存问题,其中写着以下内容:哈利·波特和他的朋友们与罗恩一起在奥利凡德,终于更换了查理旧的破损魔杖。赫敏决定最好的选择方法是确定购买每根高功率和高年龄的非邪恶魔杖所需的最小金加隆数量。编写一个查询来打印 Ron 感兴趣的魔杖的 id、年龄、coins_needed 和力量,并按力量降序排列。如果不止一根魔杖具有相同的力量,则按年龄降序对结果进行排序。 这里是更多详细信息的链接。它对我的解决方案不满意,我认为这与 group by 特别有关。我所做的有什么问题以及如何解决?我可以进行同样的小修改以使其正确(即仍然使用 group by 子句)吗?
赫敏决定最好的选择方法是确定购买每根高功率和年龄的非邪恶魔杖所需的最小金加隆数量。编写一个查询来打印 Ron 感兴趣的魔杖的 id、年龄、coins_needed 和力量,并按力量降序排列。如果不止一根魔杖具有相同的力量,请按年龄降序对结果进行排序。
select w.id, wp.age, min(w.coins_needed), w.power
from wands as w, wands_property as wp
where w.code = wp.code and wp.is_evil = 0
group by w.power, wp.age
order by w.power desc, wp.age desc;
我将不胜感激的建议!谢谢!
它对
w.id
与 group by
子句的结合感到不满意。基本上,可以有多个 w.id
对应于相同的 w.power, wp.age
配对。您知道您想要的是与 min
的条目相对应的 ID,但这不是(直接)合法的 SQL。如果您使用 avg
而不是 min
,您会让它做什么?
相反,您需要使用子查询。将问题分成两部分:
换句话说(使用
JOIN
,因为它是通常首选),
select w.id, wp.age, s.min_coins_needed, s.power
from (select code, power, min(coins_needed) as min_coins_needed
from wands
group by power, code) as s
left join wands w
on w.coins_needed = s.min_coins_needed and w.code = s.code and w.power = s.power
left join wands_property as wp
on w.code = wp.code
where wp.is_evil = 0
order by s.power desc, wp.age desc;
SELECT
w.id,
wp.age,
w.coins_needed,
w.power
FROM
Wands w
LEFT JOIN Wands_property wp ON
w.code = wp.code
WHERE
w.coins_needed =
(
SELECT
MIN(coins_needed) AS min_coins_needed
FROM
Wands w1
LEFT JOIN Wands_property wp1 ON
w1.code = wp1.code
WHERE
wp1.is_evil = 0 AND
w1.power = w.power AND
wp1.age = wp.age
)
ORDER BY
w.power DESC,
wp.age DESC;
select
id,
age,
coins_needed,
D.power
FROM (
SELECT distinct power,age,
FIRST_VALUE(id) OVER (Partition By power,age order by coins_needed asc)id
,FIRST_VALUE(coins_needed) OVER (Partition By power,age order by coins_needed asc)coins_needed
FROM WANDS W JOIN WANDS_PROPERTY WP
ON W.code = WP.code
where is_evil = 0
) AS D
Order by D.power desc,age desc
FIRST_VALUE(id) -- 指相同年龄和功率的魔杖所需硬币最低的魔杖 ID(在分区中) FIRST_VALUE(coins_needed)——计算lowest_coin_required -因为分区是按coins_needed asc排序的,所以对于具有相同年龄和功率的魔杖,成本最低的魔杖(id)将位于顶部