SQL Server select语句的新帮助

时间:2010-06-05 21:10:20

标签: sql sql-server tsql

我需要SQL Server / T-SQL中的select语句帮助

我的表格如下:

Id (int)  
QuestionId (int)  
GenreId (int)  
QuestionScore (int)

我想从此表中选择随机 N 行,以便结果集中相同GenreId的最大数量小于 X ,除了一个之外的所有GenreId-s。对于那个GenreId,我需要行计数,GenreId等于 Y

更新
我根据下面的建议编写了这个查询,它完全符合我的要求(除了一个类型,但没问题,让它成为这样,生病有2个查询)

select top @N * from
(select Id,GenreId,Rank() over (Partition BY GenreId order by newId()) as Rank,QuestionScore from Questions) t
where t.Rank <= @X
order by newId()

现在我需要选择行,以便平均QuestionScore在1.7到2.3之间 我怎样才能做到这一点?我需要在结果集中返回所有列 提前谢谢:)

2 个答案:

答案 0 :(得分:1)

对于SQL Server 2005+,请使用:

SELECT TOP (@n) c.*
  FROM (
SELECT a.id,
       a.questionid,
       a.genreid
  FROM (SELECT t.*,
               ROW_NUMBER() OVER (PARTITION BY t.genreid) AS rank
          FROM TABLE t
         WHERE t.genreid NOT IN (SELECT TOP 1 --ensure only one genre, see order by
                                        t.genreid
                                   FROM TABLE t
                               GROUP BY t.genreid
                                 HAVING COUNT(*) = @y 
                               ORDER BY t.genreid) 
      ) a
 WHERE a.rank < @x
UNION ALL
SELECT b.id,
       b.questionid,
       b.genreid
  FROM TABLE b
 WHERE b.genreid IN (SELECT TOP 1 --ensure only one genre, see order by
                            t.genreid
                       FROM TABLE t
                   GROUP BY t.genreid
                     HAVING COUNT(*) = @y
                   ORDER BY t.genreid ) ) c

答案 1 :(得分:0)

在SQL Server中,您可以使用嵌套子查询和top子句执行此操作:

select  top (@n) * 
from    (
        -- Retrieve @y rows from the special genre
        -- The prio field is used to ensure all these rows make it inside @n
        select  top (@y) 1 as prio, genreid, questionid
        from    @t
        where   genreid = @the_one

        -- And up to @x rows per non-special genre
        union all
        select  2 as prio, genreid, questionid
        from    (
                select  *
                ,       row_number() over (partition by genreid 
                                           order by newid()) as rownr
                from    @t
                where   genreid <> @the_one
                ) sub
        where rownr < @x
        ) sub2
order by
        prio, newid()

示例数据:

declare @t table (id int identity, QuestionId int, GenreId int)

insert @t (GenreId, QuestionId) values 
    (1,1),
    (2,1),(2,1),
    (3,1),(3,1),(3,1),
    (4,1),(4,1),(4,1),(4,1),
    (5,1),(5,1),(5,1),(5,1),(5,1)

declare @n int
declare @x int
declare @y int
declare @the_one int

set @n = 7 -- Total rows
set @x = 3 -- With less then 3 per genre
set @y = 3 -- Except three rows from genre @the_one
set @the_one = 3

结果(一个例子,每次运行时输出不同:

prio  genreid  questionid
1     3        1
1     3        3
1     3        2
2     4        1
2     1        1
2     5        1
2     5        4