Всегда возвращать указанное количество записей Sql Server - PullRequest
1 голос
/ 30 января 2012

У меня есть запрос, для которого я всегда хочу вернуть 10 записей:

set rowcount 10
select row_number() over(order by count(*) desc) row_num
    ,hist_report_id
    ,max(rpt_report_name) report_name
from utility.dbo.tbl_report_history
join utility.dbo.tbl_report_definitions
    on hist_report_id = rpt_report_id
where hist_user_id = 1038
group by hist_report_id

, который отлично работает, если у меня есть 10 или более записей.Проблема состоит в том, что когда существует менее 10 записей, мне все еще нужно вернуть поле rownumber с нулями в полях report_id и report_name.

Если было возвращено только 7 записей, результаты должны выглядеть следующим образом:

row_num report_id report_name
1       id1       name1
2       id2       name2
3       id3       name3
4       id4       name4
5       id5       name5
6       id6       name6
7       id7       name7
8       null      null
9       null      null
10      null      null

Есть предложения?

Я использую SQL Server 2008

Ответы [ 4 ]

4 голосов
/ 30 января 2012

count() никогда не может вернуть меньше нуля ... поэтому просто добавьте 10 фиктивных строк с -1 в столбце подсчета с помощью объединения

Также не используйте SET ROWCOUNT, поскольку это влияет на промежуточные результаты

SELECT TOP 10
   row_number() over(order by TheCount desc) AS row_num,
   hist_report_id,
   report_name
FROM
    (
    select 
        ,count(*) AS TheCount
        ,hist_report_id
        ,max(rpt_report_name) AS report_name
    from 
       utility.dbo.tbl_report_history
       join 
       utility.dbo.tbl_report_definitions on hist_report_id = rpt_report_id
    where hist_user_id = 1038
    group by hist_report_id
    UNION ALL
    SELECT TOP 10
         -1, NULL, NULL
    FROM sys.columns
    ) T
1 голос
/ 11 августа 2013
with
/* Create 10 dummy rows using recursion */
RowSequence as (
    select 0 Idx
    union all
    select RowSequence.Idx+1 Idx from RowSequence where RowSequence.Idx+1<10
    ),
/* Your Query */
YourQuery as(
    select row_number() over(order by count(*) desc) row_num
        ,hist_report_id
        ,max(rpt_report_name) report_name
    from utility.dbo.tbl_report_history
    join utility.dbo.tbl_report_definitions
        on hist_report_id = rpt_report_id
    where hist_user_id = 1038
    group by hist_report_id
    )
/* Now all together */
select top 10 * from (
    select * from YourQuery
    union all
    select null, null, null from RowSequence
    ) a
/* To avoid the recursion maximum level 100 */
option (maxrecursion 0)
0 голосов
/ 30 января 2012

Вы можете рассмотреть возможность использования TVF, чтобы получить для вас набор чисел, с которыми вы можете внешне соединиться:

CREATE FUNCTION SetOfValues (@beginningAt int, @endingAt int, @step int = 1)
RETURNS 
    @result TABLE (value int )
AS BEGIN
    declare @counter int set @counter = @beginningAt
    while(@counter<=@endingAt)
    begin
        insert into @result values(@counter)
        set @counter = @counter + @step
    end 
RETURN 
END
GO

-- USAGE
with cte as (
    select row_number() over (order by hist_report_Id) as row_num,
    hist_report_Id, report_name
    from tbl_report_history join tbl_report_definitions on hist_report_Id = rpt_reportId)
select value, hist_reportId, report_name 
from dbo.SetOfValues(1,10,1) as t on t.value = cte.row_num
0 голосов
/ 30 января 2012

Самый простой способ, который я помню:

  1. Insert select result в #temptable
  2. While count(*) < 10 insert строка into #temptable
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...