Sql:具有动态顺序的Distinct子句

时间:2016-07-14 18:06:03

标签: sql sql-server tsql sql-order-by distinct

有没有办法运行这种类型的查询

select distinct ri.id, r.RequestDate, count(ri.id) over() as TotalRecords 
   from security.RequestItemView ri
   order by r.RequestDate asc
       case when @SortColumn='RequestDate' and @SortOrder='ASC' then r.RequestDate end asc,
       case when @SortColumn='RequestDate' and @SortOrder='DESC' then r.RequestDate end desc

动态order by子句在我使用distinct子句之前工作正常,当我使用distinct

时会出现此错误
  如果SELECT DISTINCT为,则

ORDER BY项必须出现在选择列表中   指定。

我知道我们必须将选择列表中的列用于order by子句,这就是我选择r.RequestDate列的原因,我实际上并不想选择该列而是要制作distict我正在选择它,但它仍然无法正常工作。

当我用这样的固定排序替换动态排序时

order by r.RequestDate asc

它开始工作,所以基本上动态order bydistinct子句一起工作。

有任何方法可以达到这个目的吗?

2 个答案:

答案 0 :(得分:1)

您可以使用聚合而不是distinct

select ri.id, r.RequestDate, count(ri.id) as TotalRecords 
from security.RequestItemView ri
group by ri.id, r.RequestDate
order by (case when @SortColumn = 'RequestDate' and @SortOrder='ASC' then min(r.RequestDate) end) asc,
         (case when @SortColumn = 'RequestDate' and @SortOrder='DESC' then min(r.RequestDate) end) desc;

答案 1 :(得分:0)

戈登有一个好主意,但在计算分析计数后distinct适用。 (我找了一个权威的来源并没有找到一个。虽然这是有道理的。)如果那确实是你想要的那么你会想要仔细检查那些总数。请参阅以下示例:

create table T (n int);
insert into T (n) values (1), (1);

select distinct n, count(n) from T; -- returns 2
select n, count(n) over () from T group by n; -- returns 1

http://rextester.com/SSI28665

我认为最简单的解决方法是将其包装在表格表达式中:

select id, RequestDate, TotalRecords from (
    select distinct
        ri.id, r.RequestDate, count(ri.id) over() as TotalRecords
        case when @SortColumn = 'RequestDate' and @SortOrder = 'ASC'
             then r.RequestDate end as sort1,
        case when @SortColumn = 'RequestDate' and @SortOrder = 'DESC'
             then r.RequestDate end as sort2
    from security.RequestItemView ri
) as S
order by sort1 asc, sort2 desc;

当然,新列可能会干扰不同的化合物。在这种情况下,您已经在输出中包含RequestDate,因此不会增加行数。由于您有一个@SortColumn变量,我怀疑您发布的查询并未反映您实际使用的较大结果以及我注意到此警告的原因。