【问题标题】:How to select one row, and then select the rest如何选择一行,然后选择其余的
【发布时间】:2020-03-05 06:46:36
【问题描述】:

我正在努力实现以下目标:

表格

    featured    product
row1    0       product1
row2    0       product2
row3    1       product3
row4    1       product4
row5    0       product5
row6    1       product6

输出(顶行始终是特色)

row4    1       product4
rowRandom
rowRandom
rowRandom
rowRandom
rowRandom

在“输出”中,第一行始终是特色。其他行是随机的(减去特色行)。

我可以用 mySQL 做到这一点,还是应该用 php 做到这一点?

感谢和问候,

尼尔。

【问题讨论】:

  • 那么顶行应该是随机选择的记录有featured = 1,还是特定记录?
  • 为什么是row4 1 product4 而不是row3 1 product3row6 1 product6 用于顶行,这些也有特色?添加到@GMB 的评论
  • @RaymondNijland 这只是我的示例输出。它可以是 featured = 1. 所在的任何行
  • @GMB 是的。正确。
  • 您使用的是哪个版本的 MySQL?

标签: mysql database random sql-order-by window-functions


【解决方案1】:

首先随机选择一个特色行,并添加一个新列,用于排序,其余行使用UNION ALL
最后group by featured, product删除第一行的重复:

select t.featured, t.product 
from (
  select f.*, 0 ordercol from (
    select * from tablename
    where featured 
    order by rand()
    limit 1
  ) f
  union all
  select *, 1 from tablename
) t
group by t.featured, t.product 
order by min(t.ordercol), rand()

请参阅demo
结果(随机):

| featured | product  |
| -------- | -------- |
| 1        | product4 |
| 0        | product1 |
| 1        | product3 |
| 0        | product5 |
| 1        | product6 |
| 0        | product2 |

【讨论】:

  • 为什么不改用UNION 呢?那么你不需要 GROUP BY ... ORDER BY ... 去重复还是我现在错过了一些非常明显的东西??
  • 因为结果集中有一个新列ordercol,union 什么都不做。
【解决方案2】:

如果您运行的是 MySQL 8.0,您可以使用 row_number()rand() 在一次扫描中执行此操作:

select 
    product, 
    featured
from tablename
order by 
    case 
        when 
            featured = 1 
            and row_number() over(partition by featured order by rand()) = 1
        then 0
        else 1
    end,
    rand()

order by 子句将随机选择一条带有featured = 1 的记录并将其放在首位,然后以随机顺序显示其他记录。

Demo on DB Fiddle

运行#1:

产品 |精选 :------- | --------: 产品4 | 1 产品6 | 1 产品1 | 0 产品5 | 0 产品2 | 0 产品3 | 1

运行#2:

产品 |精选 :------- | --------: 产品3 | 1 产品2 | 0 产品1 | 0 产品6 | 1 产品4 | 1 产品5 | 0

【讨论】:

    猜你喜欢
    • 2021-09-14
    • 2019-01-27
    • 1970-01-01
    • 2016-06-15
    • 1970-01-01
    • 1970-01-01
    • 2015-05-14
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多