在SQL中显示唯一行和排名?

时间:2018-02-08 16:44:01

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

我想在SQL中显示唯一的行和排名。

以下是我对SQL查询的尝试:

SELECT
    DENSE_RANK() OVER (ORDER BY (COALESCE(s.rows, 0) / COALESCE(trgt.rows, 0) * 100) DESC) AS Ranking, 
    TM_Emp_Id, Territory, TM_Name,
    COALESCE(s.rows, 0) AS DeliveredCount,
    COALESCE(nd.rows, 0) AS NotDeliveredCount,
    COALESCE(trgt.rows, 0) AS Target
FROM
    tblEmployee e
LEFT JOIN
    (SELECT 
         EmpCode, SUM(MedToPCount) AS rows 
     FROM 
         tblMdcn 
     WHERE 
         Status = 'Delivered' 
     GROUP BY 
         EmpCode) s ON s.EmpCode = e.TM_Emp_Id
LEFT JOIN
    (SELECT 
         EmpCode, COUNT(*) AS rows 
     FROM 
         tblMdcn  
     WHERE 
         Status != 'Delivered' 
     GROUP BY 
         EmpCode) nd ON nd.EmpCode = e.TM_Emp_Id
LEFT JOIN
    (SELECT 
         EmpCode, CurrentTarget AS rows 
     FROM 
         tbl_Target) trgt ON  trgt.EmpCode = e.TM_Emp_Id

我试图根据给定目标的总和的百分比来计算排名。(像这样:(a/b)*100,排名第一的百分比最高的人。我必须在这里使用INNER JOIN。 当目标或DelieveredCount为0时,我该如何处理(在这种情况下,他应该排在最后)。

我得到的结果是这样的: -

 Ranking  TM_Emp_Id   Territory TM_Name DeliveredCount  NotDeliveredCount   Target
 ----------------------------------------------------------------------------------
    1      101        South     Bob        12               2                  20
    1      101        South     Bob        12               2                  20
    1      101        South     Bob        12               2                  20
    2      102        North     Alice       5               0                  23
    2      102        North     Alice       5               0                  23
    2      102        North     Alice       5               0                  23
    3      103        South     Joe         1               0                  15
    3      103        South     Joe         1               0                  15

我想显示如下结果: -

Ranking    TM_Emp_Id    Territory   TM_Name DeliveredCount  NotDeliveredCount   Target
--------------------------------------------------------------------------------------
   1       101          South       Bob         12                2               20
   2       102          North       Alice        5                0               23
   3       103          South       Joe          2                0               15

非常感谢任何建议或指示。

2 个答案:

答案 0 :(得分:1)

您可以使用group by对行进行分组,并在您创建的选择周围获取列的Max值。

这样的事情:

SELECT Ranking, Territory, Max(DeliveredCount), Max(Target) -- etc...
FROM (SELECT ...) --Your select here
GROUP BY Ranking, Territory, TM_Name 

答案 1 :(得分:1)

在我看来,你可以通过一些条件聚合大大简化你的逻辑。我没有对此进行测试,因为我们没有数据或表格结构,但这应该非常接近。

SELECT
  DENSE_RANK() OVER (ORDER BY (COALESCE(sum(case when Status = 'Delivered' then MedToPCount else 0 end), 0)/COALESCE(sum(case when Status = 'Delivered' then MedToPCount else 0 end), 0)*100) DESC) AS Ranking
  , TM_Emp_Id
  , Territory
  , TM_Name
  , sum(case when Status = 'Delivered' then MedToPCount else 0 end) AS DeliveredCount
  , sum(case when Status != 'Delivered' then 1 else 0 end) AS NotDeliveredCount
  , COALESCE(trgt.rows, 0) AS Target
FROM tblEmployee e
LEFT JOIN tbl_Target trgt ON trgt.EmpCode = e.TM_Emp_Id
GROUP BY TM_Emp_Id
  , Territory
  , TM_Name

我不得不问你为什么要为你的表使用tbl前缀。这是一个很好的讨论。 https://dba.stackexchange.com/questions/154251/is-adding-the-tbl-prefix-to-table-names-really-a-problem