-1

我有一个包含问题、答案、类型列的问题的数据库。

目前,这是我正在运行的 sql 语句:

SELECT Question, Answer, Type FROM goodquestions ORDER BY RAND() LIMIT 0,20

如您所见,我从表中选择随机值,我希望它是那样的。但是,当类型为 12 时,我想访问该条目之前的表格行并将它们一起打印出来

像这样

RANDOM
RANDOM
RANDOM
Question before 12 type
12 type question
RANDOM
RANDOM
RANDOM

它也可以是这样的:

Question before 12 type
12 type question
RANDOM
RANDOM
RANDOM
RANDOM
RANDOM
RANDOM

我只需要他们在一起,我现在无法做到这一点。

4

2 回答 2

2

我想我明白你想要什么了。请尝试此查询,我更改limit 1,20limit 1, 10

select @next_line_id:=0, @next_line_type:=0;
select g.*, tt.is_property
from
    (select * from
         (select *,
           rand() as rand_val,
           case
               when @next_line_type= 12 or Type = 12 then 1
               else 0
           end is_property,
           @next_line_id as next_line_id,
           @next_line_id:=id as current_id,
           @next_line_type:=Type as current_type
         from goodquestions order by id desc
         ) t
    where t.Type <> 12
    order by rand_val limit 0,10) tt
join goodquestions g on g.id = tt.id or (g.id = tt.next_line_id and tt.is_property = 1 and tt.Type <> 12)
group by g.id, g.Question, g.Answer, g.Type, tt.is_property
order by is_property desc, id
limit 0, 10;

以下是创建测试表的查询:

create table goodquestions (
    id int unsigned auto_increment primary key,
    Question varchar(255) not null,
    Answer varchar(255) not null,
    Type int unsigned,
    index idx_type (Type)
) engine=innodb DEFAULT CHARSET=latin1;

insert into goodquestions (Question, Answer, Type)
values ('q1', 'a1', 1),
       ('q2', 'a2', 2),
       ('q3', 'a3', 3),
       ('q4', 'a4', 4),
       ('q5', 'a5', 5),
       ('q6', 'a6', 6),
       ('q7', 'a7', 7),
       ('q8', 'a8', 8),
       ('q9', 'a9', 9),
       ('q10', 'a10', 10),
       ('q11', 'a11', 11),
       ('q12', 'a12', 12),
       ('q13', 'a13', 13),
       ('q14', 'a14', 14),
       ('q15', 'a15', 15),
       ('q16', 'a16', 16),
       ('q17', 'a17', 17),
       ('q18', 'a18', 18);

请注意,rand()对于大表,使用函数可能会导致性能不佳。如果存在性能问题,我可以提供另一种解决方案以获得更好的性能。


以下查询结果列出must have and only have了一条类型为 12 的记录:

select @total_type_12:=(select count(*) from goodquestions where Type=12);
select @random_type_12:=(floor(rand()*@total_type_12) + 1) * 2;
select @next_line_id:=0, @next_line_type:=0, @is_property:=0;
select g.*, tt.is_property
from
    (select * from
         (select *,
           case
               when (@next_line_type= 12 or Type = 12) and @random_type_12 > 0 and @random_type_12 <= 2 then @is_property:=1
               else @is_property:=0
           end is_property,
           rand() as rand_val,
           @random_type_12 as cur_random_type_counter,
           case
               when (@next_line_type= 12 or Type = 12) and @random_type_12 > 0 then @random_type_12:=@random_type_12-1
               else @random_type_12
           end as next_rand_type_counter,
           @next_line_id as next_line_id,
           @next_line_id:=id as current_id,
           @next_line_type:=Type as current_type
         from goodquestions order by id desc
         ) t
    where t.Type <> 12
    order by is_property desc, rand_val limit 0,10) tt
join goodquestions g on g.id = tt.id or (g.id = tt.next_line_id and tt.is_property = 1 and tt.Type <> 12)
group by g.id, g.Question, g.Answer, g.Type, tt.is_property
order by is_property desc, id
limit 0, 10;

测试数据集如下:

mysql> select * from goodquestions;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:    84
Current database: test

+----+----------+--------+------+
| id | Question | Answer | Type |
+----+----------+--------+------+
|  1 | q1       | a1     |    1 |
|  2 | q2       | a2     |    2 |
|  3 | q3       | a3     |    3 |
|  4 | q4       | a4     |    4 |
|  5 | q5       | a5     |    5 |
|  6 | q6       | a6     |    6 |
|  7 | q7       | a7     |    7 |
|  8 | q8       | a8     |    8 |
|  9 | q9       | a9     |    9 |
| 10 | q10      | a10    |   10 |
| 11 | q11      | a11    |   11 |
| 12 | q12      | a12    |   12 |
| 13 | q13      | a13    |   13 |
| 14 | q14      | a14    |   14 |
| 15 | q15      | a15    |   15 |
| 16 | q16      | a16    |   16 |
| 17 | q17      | a17    |   17 |
| 18 | q18      | a18    |   18 |
| 19 | q21      | a21    |   12 |
| 20 | q22      | a22    |   22 |
| 21 | q23      | a23    |   12 |
+----+----------+--------+------+
21 rows in set (0.34 sec)
于 2020-08-05T04:29:30.317 回答
1

对于 MySQL 8+,它可能类似于

WITH
-- SELECT 20 random rows
cte AS ( SELECT Question, Answer, Type 
         FROM goodquestions 
         ORDER BY RAND() LIMIT 0,20 )
( SELECT Question, Answer, Type
  FROM cte )
-- add pre-row if Type=12 row is selected and pre-row is not selected
UNION DISTINCT
( SELECT Question, Answer, Type
  FROM goodquestions 
  WHERE Type = 'pre-type for type 12'
  AND EXISTS ( SELECT NULL
               FROM cte
               WHERE Type = 12 ) )
-- sort placing pre-row and type=12 row at the top
ORDER BY Type = 'pre-type for type 12' DESC,
         Type = 12 DESC,
         RAND()
-- remove excess row if Type=12 row was selected in CTE
-- and pre-row was not selected in CTE but added in UNION 
LIMIT 0, 20

该查询假定它goodquestions.Type是唯一的。

于 2020-08-05T05:17:06.387 回答