выберите n образцов из каждой категории - PullRequest
0 голосов
/ 11 июня 2018

У меня есть столбец, оценка, это целые числа от 1 до 5 включительно.Я пытаюсь выбрать n (2000 в данном случае) образцов из каждого балла.Мой собственный взлом и другой вопрос SO привели меня к созданию следующего запроса:

select * from (select text, score from data where score= 1 and LENGTH(text) > 45 limit 2000)
union
select * from (select text, score from data where score= 2 and LENGTH(text) > 45 limit 2000)
union
select * from (select text, score from data where score= 3 and LENGTH(text) > 45 limit 2000)
union
select * from (select text, score from data where score= 4 and LENGTH(text) > 45 limit 2000)
union
select * from (select text, score from data where score= 5 and LENGTH(text) > 45 limit 2000)

Это похоже на худший способ сделать это, более того, когда я запускаю каждый запрос отдельно, он дает мне 2kрезультаты, как и ожидалось, но когда я запускаю это объединение, я получаю менее 10 тыс. строк, которые я ищу, чтобы немного оптимизировать этот запрос, но что более важно, я хочу понять, почему объединение возвращает неправильное количество результатов

Ответы [ 2 ]

0 голосов
/ 11 июня 2018

По умолчанию UNION сравнивает все строки и возвращает только отдельные.Вот почему вы получаете менее 10 КБ.Как говорит sgeddes, используйте UNION ALL вместо того, чтобы всегда получать все 10k строк, включая дубликаты.Вы хотите дубликаты строк, не так ли?

0 голосов
/ 11 июня 2018

Что касается того, почему ваш запрос возвращает неправильное количество результатов, я бы поспорил, что ваши данные не равны distinct в наборе результатов, который возвращается с каждым отдельным запросом.При использовании union он возвращает строки distinct по всему набору результатов.

Попробуйте изменить его на union all:

select * from (select text, score from data where score= 1 and LENGTH(text) > 45 limit 2000)
union all
select * from (select text, score from data where score= 2 and LENGTH(text) > 45 limit 2000)
union all
select * from (select text, score from data where score= 3 and LENGTH(text) > 45 limit 2000)
union all
select * from (select text, score from data where score= 4 and LENGTH(text) > 45 limit 2000)
union all
select * from (select text, score from data where score= 5 and LENGTH(text) > 45 limit 2000)

Если у вас есть первичный ключ, такой как автоинкремент, то есть другой подход, генерирующий row_number для каждой группы оценок (это предполагает id первичный ключ):

select text, score
from (
  select text, score, 
         (select count(*) from data b 
          where a.id >= b.id and 
                a.score = b.score and 
                length(b.text) > 45) rn
  from data a
  where length(text) > 45
  ) t
where rn <= 2000
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...