SQL Query以分类方式显示记录

时间:2016-01-11 13:17:12

标签: sql sql-server sql-server-2012 tabular

我的查询显示输出如下所示

`UserName   Status   Count`  
`A          Pass      32`
`A          fail      2`
`A          Hold      4`
`B          Fail      12`
`C          Pass      40`
`C          Fail      4`
`C          Hold      3`
`D          Pass      2`

我希望显示输出,第一条记录为用户名C及其详细信息,第二条,A及其详细信息。我正在尝试获得具有高通状态的前5条记录及其相关的用户名记录。如果该用户名存在于Top 5中,我不想留下第6条记录。请帮助

抱歉,我无法以表格格式进行格式化。

3 个答案:

答案 0 :(得分:0)

;WITH CTE_UserRanking AS (
    SELECT
        UserID,
        DENSE_RANK() OVER (ORDER BY COUNT(*) DESC) AS user_rank
    FROM
        dbo.User_Scores S
    WHERE
        S.Status = 'Pass'
    GROUP BY
        UserID
)
SELECT
    U.UserName,
    S.Status,
    COUNT(*)
FROM
    CTE_UserRanking R
INNER JOIN dbo.Users U ON U.UserID = R.UserID
INNER JOIN dbo.Scores S ON S.UserID = R.UserID
WHERE
    R.user_rank <= 5
GROUP BY
    U.UserID,
    U.UserName,
    S.Status
ORDER BY
    R.user_rank

答案 1 :(得分:0)

使用分析功能获得每位用户的通过率,获得前5名,并按合格率排序。

select username, status, cnt
from
(
  select top(5) username, status, cnt, sum(case when status = 'Pass' then cnt else 0 end)
                                       over (partition by username) as passed
  from mytable
  order by 4 desc
) top5
order by 
  passed desc, 
  username, 
  case status when 'Pass' then 1 when 'fail' then 2 else 3 end;

(我冒昧地调用你的计数列cnt,因为COUNT是SQL中的保留字,最好不要选择列名。)

答案 2 :(得分:0)

要实现所需的上市顺序相对简单:

select top 6 * from #tbl INNER JOIN (
  SELECT UserName u, cnt pc FROM #tbl WHERE Status='Pass'
  ) ord ON u=UserName ORDER BY pc desc,status desc

但是,如果第一个结果集不完整,将其限制为5行并不容易。我还在努力......

修改

好吧,经过几次尝试后我发现,当你将输出行限制在某个最大数量时,根据数据结构的不同,如果你坚持使用用户的所有行,你最终可能会减少两个记录总是完整列出。因此,如果我们将输出限制为6行,那么如果下一个用户将再提供3行,则列表将有可能在第4行结束。接受了,您可以使用以下内容:

;WITH cnts AS ( SELECT 
  UserName un,
  SUM(CASE Status 
           WHEN 'Pass' THEN 10000   --  weighing system
           WHEN 'Hold' THEN 100     --  to sort the results ...
                       ELSE 1 END * cnt) scr, -- --> score for sorting
  COUNT(*) ncnt                     --  row count per UserName
  FROM #tbl GROUP BY UserName
)
SELECT UserName,Status,cnt,scr,acnt FROM #tbl INNER JOIN (
 SELECT un,scr,(SELECT SUM(ncnt) FROM cnts WHERE scr>=c.scr) acnt 
 FROM cnts c WHERE (SELECT SUM(ncnt) FROM cnts WHERE scr>=c.scr) <=6 
) srt ON UserName=un
 ORDER BY scr DESC, UserName, Status desc

请参阅here

子查询(SELECT SUM(ncnt) FROM cnts WHERE scr>=c.scr)表示我在where - 子查询的srt子句中使用的累计行数,以限制输出。

与我的第一种方法相反,我现在根据scr进行内部排序,这是一个内部分数,我通过将所有通过/保持/失败计数与不同的加权因子相加来计算。如果不这样做,没有单一通行证的用户就可以通过这种方式。永远不会被列出,即使没有其他用户做得更好。