2014-12-17 2 views
3

у меня есть SQL отборное заявление следующим образом:Как сделать заказ по количеству строк с определенным значением столбца

select * from editortemp order by case 
when CategoryID = 10 then 0 
else CategoryID end, 
Ranking 

Я хотел бы изменить порядок результата, так что в дополнение к класть все строки с CategoryID = 10 вверху, REST строк будет упорядочен в соответствии с количеством строк с каждым кодом категории в порядке убывания.

Когда я пытаюсь делать

select * from editortemp order by case 
when CategoryID = 10 then 0 
else count(CategoryID) end, 
Ranking 

Я получаю ошибку: Колонка «editortemp.EditorTempID» недопустим в списке выбора, поскольку он не содержится ни в статистической функции или предложения GROUP BY.

После изучения этой ошибки в Интернете, похоже, что это означает, что существует проблема с логикой оператора select.

Как создать оператор логического выбора, который будет упорядочивать строки, как описано выше?

EDIT: Когда я пытаюсь запустить следующее заявление:

select * from editortemp order by case 
    when CategoryID = 10 then 0 
    else (select count(CategoryID) from editortemp) end, 
    Ranking 

Я не получаю ошибку, упомянутых выше, но заказ не выходит правильно. Он помещает все категории = 10 строк вверху, но затем начинает упорядочиваться в соответствии с ранжированием, а не по счету категории. Любые идеи, что нужно изменить, чтобы получить результаты, которые я хочу?

Большое вам спасибо за помощь!

+0

Возможно, здесь не уместно, но вы всегда должны добавить тег для используемой СУБД (Postgres, Oracle, ...) –

+0

Причина, по которой последний запрос не работает, заключается в том, что вы являетесь округом ng все строки в 'EditorTemp' - у вас нет предложения о корреляции. Поэтому каждая строка получает одинаковое значение ... –

ответ

1

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

По тому, как он выглядит, ваша таблица editortemp имеет несколько записей и может содержать больше элементов данных, явно не представленных здесь. Сначала я должен получить предварительную совокупность подсчетов, а затем присоединиться к ней, чтобы включить ее в качестве части вашего заказа. Кое-что как

select 
     et.* 
    from 
     editortemp 
     JOIN (select categoryID, count(*) as CatCount 
        from editortmp 
        group by categoryID) preAgg 
      on et.categoryID = preAgg.categoryID 
    order by 
     case when CategoryID = 10 then 1 else 2 end, 
     preAgg.CatCount desc, 
     ranking 

Корпус/когда сначала будет принудительно сначала присвоен тип category = 10, затем все остальное второе. Вторичная часть заказа - это счет из таблицы с предварительным агрегатом. Таким образом, даже если в категории 10 есть счет из 3 записей, а в категории 2 - 100, категория 10 по-прежнему остается на первом месте ... только тогда остальные получат сортировку в порядке убывания по счету.

Per обратной связи ...

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

What if categories 1, 2, 3, 4, 5 all have a count of 73 entries... and 
cat 1 has a ranks of 6, 12, 15... 
cat 2 has ranks of 3, 20, 40... 
cat 3 has ranks of 9, 10, 18... 
they will be intermingled. 

Если вы хотите, чтобы все то же категории сгруппированной, то это было бы добавить до рейтинга что-то вроде

order by 
     case when CategoryID = 10 then 1 else 2 end, 
     preAgg.CatCount desc, 
     CategoryID, 
     ranking 

Таким образом, инф сценария нескольких категорий, имеющих счетчик 73, то выше по порядку будет иметь всю категорию 1 по ее ранжированию, затем по категории 2 по его рангу и т. д.

+0

Я бы, вероятно, переместил 'CASE' в подзапрос, который должен сделать вещи немного чище. О, вы также оставили «рейтинг». –

+0

@ Clockwork-Muse добавляет ранжирование, но, помещая случай в подзапрос, затем надеется, что все это выйдет в этом порядке с помощью внешнего editortemp, не может гарантировать правильный порядок дел, поэтому у меня есть это на конечный уровень запросов. – DRapp

+0

@DRapp - спасибо, это была отличная помощь! Я вижу, что вы добавили ранжирование в оговорку order by в конце. Когда я ухожу из рейтинга Ранжирование сортировки работает правильно, однако, когда я добавляю его, как и вы, исходный вид больше не работает ... Вы знаете, почему это может быть? – code2b

0
select 
    TEMP1.* 
from 
    (
     select CategoryID, 999999999 AS Ranking FROM editortemp WHERE CategoryID = 10 
     UNION ALL 
     Select CategoryID, (SELECT COUNT(*) FROM editortemp AS t1 WHERE t1.CategoryID = t2.CategoryID) AS Ranking FROM editortemp AS t2 WHERE CategoryID <> 10 
    ) TEMP1 
ORDER BY 
    TEMP1.Ranking DESC 
+0

Вам не нужна корреляция между основным запросом и подзапросом? (Чтобы убедиться, что правильный счет?) – jarlh

+0

@ user1463201 Я изменил проверку запроса сейчас – Sandeep

+0

Вы не должны зависеть от запроса 'union all', возвращающего rpws из первого запроса, а затем строки из второго. Это не гарантируется. –

0

Вы можете делать то, что вы хотите, как:

order by (case when CategoryID = 10 then 0 else 1 end), 
     (case when CategoryID <> 10 
       then (select count(*) from editortemp et2 where et2.CategoryID = editortemp.CategoryId) 
      end), 
     Ranking 

Первый пункт ставит CategoryId 10 в верхней части. Второй класс сортирует остальные по количеству идентификаторов категорий. Третий использует Ranking в качестве окончательного столбца сортировки.

+0

... Разве это не может запустить подзапрос для каждой упорядоченной строки? –

+0

@ Clockwork-Muse. , , Да, но это было предложение ОП сделать это таким образом. Кроме того, с индексом 'editortemp (CategoryId)', производительность, вероятно, будет в порядке. –

Смежные вопросы