как сгруппировать два определенных c элементов вместе - PullRequest
0 голосов
/ 05 августа 2020

У меня есть база данных с вопросами со столбцами «Вопрос», «Ответ», «Тип».

В настоящее время я использую инструкцию 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

Мне просто нужно, чтобы они были вместе, а сейчас я не могу этого сделать.

Ответы [ 2 ]

2 голосов
/ 05 августа 2020

Думаю, я понимаю, что вы хотите. Попробуйте этот запрос, я изменил limit 1,20 на limit 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)
1 голос
/ 05 августа 2020

Для 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 уникален.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...