根据条件SQL选择top n或*

时间:2014-09-10 06:50:49

标签: sql sql-server-2008 sql-server-2012

我有时会按顺序选择行,有时候随机挑选n行。

所以我试图在这样的单一查询中做到这一点

declare @rand int
set @rand = 0

select top (case @rand when 0 then 1000 else @rand end) * 
from MyQuestion  
where PackageID = 10 
order by sequence 

它在我的计划中运作良好。但如果总行数大于1000则不起作用。然后是的,如果我指定10000将在那种情况下工作。但我觉得这根本不是最优的。所以我正在寻找一个解决方案,我可以在没有指定任何数字的情况下获取所有行,或者只是忽略顶部,当@rand为0时它将获取所有行

订购问题

同一查询中的另一个问题是需要随机选择。

所以当@rand有一些值

时,我以这种方式改变了随机选择的查询
declare @rand int
set @rand=0

select top (case @rand when 0 then 1000 else @rand end) * 
from MyQuestion  
where PackageID = 10 
order by (case @rand when 0 then sequence else NEWID() end)

但它引发了一个错误说

  

操作数类型冲突:uniqueidentifier与int

不兼容

所以我的方案是基于@rand变量随机获取行,或者按照基于序列列(有序)的顺序完成。

3 个答案:

答案 0 :(得分:2)

可以指定的top的最大值是sql server 2012以后的9223372036854775807(bigint的最大值)和sql server 2008的2147483647(int的最大值)。

因此,如果您将查询修改为

declare @rand bigint
set @rand=0
select top  (case @rand when 0 then 9223372036854775807else @rand end) * from MyQuestion  where 
PackageID=10 order by sequence

当参数@rand的值为0时,它将为您提供所有行。

链接select TOP (all)

按问题排序: 在这里,您尝试按值排序,这不是有效和给出错误,因为结果可以根据选择列表中使用的列名称进行排序,或者使用表示列表在选择列表中的位置的非负整数。 / p>

点击链接了解更多详情 http://msdn.microsoft.com/en-IN/library/ms188385.aspx

来自上面的链接 order_by_expression: 指定要对查询结果集进行排序的列或表达式。排序列可以指定为名称或列别名,也可以指定非负整数,表示选择列表中列的位置。 可以指定多个排序列。列名必须是唯一的。 ORDER BY子句中的排序列的序列定义了排序结果集的组织。也就是说,结果集按第一列排序,然后该排序列表按第二列排序,依此类推。 ORDER BY子句中引用的列名必须对应于选择列表中的列,或者对应于FROM子句中指定的表中定义的列,没有任何歧义。

答案 1 :(得分:0)

TOP子句指定一个非常大的数字没有性能损失,即使行数少很多。您只需使用int数据类型2147483647的最大值,然后快乐地使用。

查询引擎一旦确定所有输入都已用尽,就会停止生成行,查询将终止并返回结果。

更新 - 完全更改的问题

由于sequence是一个int列,因此它与NewID()的结果不兼容,后者是uniqueidentifier(GUID)。试试这个:

ORDER BY
   CASE @rand WHEN 0 THEN Sequence ELSE NULL END,
   CASE @rand WHEN 0 THEN NULL ELSE NewID() END

答案 2 :(得分:0)

如果您愿意,可以使用动态查询

DECLARE @Query NVARCHAR(1000)
DECLARE @Rand int

set @Rand=0

if(@Rand=0)
BEGIN
    SET @Query='*'
END
ELSE
BEGIN
   SET @Query='top '+CAST(@Rand AS NVARCHAR)+' *'
END

SET @Query= 'SELECT '+@Query+' FROM MyQuestion WHERE PackageID=10 ORDER BY sequence' 

exec sp_executesql @Query

或者你可以这样做:

declare @rand int
set @rand=0
select top  (case @rand when 0 then (SELECT COUNT(*) FROM MyQuestion) else @rand end) *
from
MyQuestion  where 
PackageID=10 order by sequence 

就您的订购问题而言, 你可以引入一些具有常数值的随机新列,并在你的订单子句中使用它,如下面的查询,如果你不想按顺序排序:

SELECT * FROM
(
    SELECT *, your_New_Random_column=0
    FROM tbl_Securities
) d
ORDER BY (case @rand  when 0 then ID else your_New_Random_column end) DESC

同样,动态查询也可以正常工作