SQL存储过程将参数传递给"order by"

lem*_*unk 5 sql stored-procedures sql-order-by

使用Microsoft SQL Server Manager 2008.

制作一个"最终"选择Pareto列表中前10名的存储过程.但是我也希望再次运行它来找到底部10.

现在,我不是重新复制查询,而是试图查看是否有办法将参数传递给查询,该参数将从asc更改为desc.

有没有办法做到这一点,这将节省我复制代码?

CREATE PROCEDURE [dbo].[TopVRM]
@orderby varchar(255)
AS
SELECT Peroid1.Pareto FROM dbo.Peroid1
GROUP by Pareto ORDER by Pareto @orderby
Run Code Online (Sandbox Code Playgroud)

Dam*_*ver 7

只是略显愚蠢:

CREATE PROCEDURE [dbo].[TopVRM]
@orderby varchar(255)
AS
SELECT Peroid1.Pareto FROM dbo.Peroid1
GROUP by Pareto
ORDER by CASE WHEN @orderby='ASC' THEN Pareto END,
         CASE WHEN @orderby='DESC' THEN Pareto END DESC
Run Code Online (Sandbox Code Playgroud)

你不严格需要把第二类条件的CASE表达在所有(*),如果Pareto是数字,你可以决定只是做CASE WHEN @orderby='ASC' THEN 1 ELSE -1 END * Pareto

(*)第二个排序条件仅在第一个排序条件认为两行相等时才有效.这是两个行都具有相同的Pareto值(因此反向排序也会认为它们相等),因为第一个CASE表达式返回NULLs(所以@orderby不是'ASC',所以我们要执行DESC排序.


您可能还想考虑一次检索两个结果集,而不是两次调用:

CREATE PROCEDURE [dbo].[TopVRM]
@orderby varchar(255)
AS

SELECT * FROM (
    SELECT
       *,
       ROW_NUMBER() OVER (ORDER BY Pareto) as rn1,
       ROW_NUMBER() OVER (ORDER BY Pareto DESC) as rn2
    FROM (
        SELECT Peroid1.Pareto
        FROM dbo.Peroid1
        GROUP by Pareto
    ) t
) t2
WHERE rn1 between 1 and 10 or rn2 between 1 and 10
ORDER BY rn1
Run Code Online (Sandbox Code Playgroud)

这将按从上到下的顺序为您提供前10名和后10名.但是,如果总共少于20个结果,那么与当前计划不同,您将不会获得重复项.