如何按行具有特定列值的行数

时间:2014-12-17 10:57:53

标签: sql sql-server-2012 sql-order-by

我有一个SQL select语句如下:

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

我想更改结果的顺序,这样除了将所有行的CategoryID = 10放在顶部之外,行的REST将根据每个CategoryID的行数进行排序,降序。

当我尝试

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

我收到错误:列'editortemp.EditorTempID'在选择列表中无效,因为它不包含在聚合函数或GROUP BY子句中。

在线研究此错误后,看起来这意味着select语句的逻辑存在问题。

如何创建一个逻辑select语句,按上述方式对行进行排序?

编辑:当我尝试运行以下语句时:

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

我没有得到上面提到的错误,但排序并没有正确。它将所有category = 10行放在顶部,但随后根据排名开始排序,而不是根据categoryid的计数...任何想法需要更改以获得我想要的结果?

非常感谢你的帮助!

3 个答案:

答案 0 :(得分: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

case / when将强制初步排序categoryID = 10,然后是其他任何秒。 order by的次要部分是加入的预聚合表中的计数。因此,即使类别10具有3个条目的计数而类别2具有100个,类别10仍然保留在第一个位置...然后其余部分按照计数从降序排序。

根据反馈......

我不知道排名是什么,但如果给定类别计数有多个条目,则排名应该只是影响。

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。

答案 1 :(得分: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

答案 2 :(得分: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置于顶部。第二个按类别ID的数量对其余部分进行排序。第三个使用Ranking作为最终排序列。