假设我有以下MySQL表(假设表名为't'
:
|-----|------------------------------|--------|------------|
| ID | Movie | Rating | Purchased |
|-----|------------------------------|--------|------------|
| 1 | Big Adventure | G | 2002-03-06 |
| 2 | Shiny Things, The | PG | 2002-03-06 |
| 3 | End of the Line | R | 2001-02-05 |
| 4 | A Rat named Darcy | G | 2003-04-19 |
| 5 | Head First Rules | R | 2003-04-19 |
| 6 | Mad Clowns | R | 1999-11-20 |
| 7 | Greg: The Untold Story | PG | 2001-02-05 |
| 8 | Potentially Habitable Planet | PG | 2001-02-05 |
| 9 | Weird Things from Space | PG | 2003-04-19 |
| 10 | Shark Bait | G | 1999-11-20 |
| 11 | Take it Back | R | 2001-02-05 |
| 12 | The White Mare | PG | 2006-08-15 |
| 13 | Simuduck Exposed | PG | 2001-05-06 |
|-----|------------------------------|--------|------------|
我想要做的是从表中获取项目并满足以下条件:
如果这对您来说很困惑,请不要担心,确实如此。为了更好地解释,以下是我从上表中得到的结果:
|-----|------------------------------|--------|------------|
| ID | Movie | Rating | Purchased |
|-----|------------------------------|--------|------------|
| 4 | A Rat named Darcy | G | 2003-04-19 |
| 12 | The White Mare | PG | 2006-08-15 |
| 5 | Head First Rules | R | 2003-04-19 |
| 1 | Big Adventure | G | 2002-03-06 |
| 9 | Weird Things from Space | PG | 2003-04-19 |
| 11 | Take it Back | R | 2001-02-05 |
| 10 | Shark Bait | G | 1999-11-20 |
| 2 | Shiny Things, The | PG | 2002-03-06 |
| 3 | End of the Line | R | 2001-02-05 |
| 13 | Simuduck Exposed | PG | 2001-05-06 |
| 6 | Mad Clowns | R | 1999-11-20 |
| 7 | Greg: The Untold Story | PG | 2001-02-05 |
| 8 | Potentially Habitable Planet | PG | 2001-02-05 |
|-----|------------------------------|--------|------------|
如果您检查上面的结果表,您会注意到以下内容:
选择的第一张电影是"一只名叫达西的老鼠"。选择此电影是因为
a)它是G评级电影的第一(评级按升序排列)
b)并且G评级电影中的最高日期(日期按降序排列)
选择的第二张电影是" The White Mare"。选择此电影是因为
a)它是PG评级电影的第一(评级按升序排列)
b)并且PG评分电影中的最高日期(日期按降序排列)
选择的第三张电影是" Head First Rules"。选择此电影是因为
a)它是R评级电影的第一(评级按升序排列)
b)并且R评级电影中的最高日期(日期按降序排列)
选择的第四部电影是" Big Adventure"。选择此电影是因为
a)它是G评级电影的第二(评级按升序排列)
b)并且G评级电影中的第二高日期(日期按降序排列)
选择的第五张电影是#34;来自Space"的奇怪事物。选择此电影是因为
a)它是PG评级电影的第二(评级按升序排列)
b)并且PG评级影片中的第二高日期(日期按降序排列)
等等。我希望你现在能想出这个模式。
所以,我的问题是,有没有办法在一个sql语句中这样做?如果没有,或者解决方案是性能密集型的,那么您对包含mysql和编程语言解决方案(php)的解决方案有何建议?
非常感谢。
答案 0 :(得分:1)
您可以通过枚举每个评级的值,然后在外部查询中执行order by
来执行此操作:
select ID, Movie, Rating, Purchased
from (select t.*,
(@rn := if(@r = rating, @rn + 1,
if(@r := rating, 1, 1)
)
) as rn
from t cross join
(select @r := '', @rn := 0) params
order by rating, Purchased desc
) r
order by rn, rating;
答案 1 :(得分:1)
我会使用MySQL用户定义的变量。
请注意,MySQL参考手册警告以这种方式使用的用户定义变量的行为是 undefined 。 (此声明取决于MySQL执行的特定操作顺序,但不保证。)
SELECT r.id
, r.movie
, r.rating
, r.purchased
FROM ( --
SELECT @rownum := IF(t.rating = @rating, @rownum + 1, 1) AS seq
, t.id
, t.movie
, @rating := t.rating AS rating
, t.purchased
FROM ( SELECT @rating := NULL, @rownum := 0) i
CROSS
JOIN t t
ORDER BY t.rating ASC, t.purchased DESC
) r
ORDER BY r.seq ASC, r.rating ASC
内联视图我初始化用户定义的变量,因此语句执行不会受当前变量中的值的影响。
内联视图r对指定序列中的行进行排序,然后将当前行与上一行的值进行比较,以确定@rownum是否应增加1(当评级与前一个相同时),或者在遇到新的评级时重置为1.
当前行的rating列的值被“保存”到用户定义的变量@rating中,因此可以将其与下一行的rating列的值进行比较(处理下一行时)。 )
对于每一行,分配给@rownum的值将在名为seq。
的列中返回外部查询首先根据seq列(已分配的rownum值)重新排序集合,然后是评级。