仅显示具有最高值的行

时间:2014-09-23 01:36:56

标签: sql

在我的查询中,我每周都会返回一些事情。一切都运行正常,除了我得到多行返回,我只需要最高。因此,例如在我的查询中,如果TotalDays是3,我有一行1,2和3.如果它是4然后我有1,2,3和4的行,等等。我需要做什么,所以我只获得最高的一个?我尝试使用ROW_NUMBER和MAX,但似乎无法弄清楚如何使用CASES完成此操作。

SELECT Employees.CustomerID, X.*, Customers.ReportID
FROM 
    (
    SELECT
        CASE WHEN [M] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Tu] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [W] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Th] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [F] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Sa] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Su] = '1' THEN 1 ELSE 0 END AS DaysofWeek
    FROM
        Customers
    ) X, Employees INNER JOIN ON Employees.EmployeesID = Customers.EmployeesID
GROUP BY Employees.CustomerID, Customers.ReportID, X.DaysofWeek

关于此的更多细节。对于任何给定的EmployeeID,可以有无限的ReportID,我想要返回所有这些,但仅限于DaysofWeek最高的位置。

因此,EmployeeID 200可能具有每周2天返回的报告1001和1002。应该显示的是

200     2     1001
200     2     1002

但是,目前显示的是:

200     1     1001
200     2     1001
200     1     1002
200     2     1002

修改了查询并添加了几个表,尽管所有表都返回值为5。

WITH sub AS(
SELECT Shift1.EmployeeID, X.*, Schedule.Services, Schedule.ReportID
FROM 
    (
    SELECT
        CASE WHEN [M] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Tu] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [W] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Th] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [F] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Sa] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Su] = '1' THEN 1 ELSE 0 END AS DaysofWeek
    FROM
        Schedule
    ) X, Shift1 INNER JOIN (Shift2 INNER JOIN Schedule ON Shift2.Shift2ID = Schedule.Shift2ID) ON Shift1.Shift1ID = Shift2.Shift1ID
GROUP BY Shift1.EmployeeID, Schedule.Services, Schedule.ReportID, X.DaysofWeek
)
SELECT X.*
  FROM sub X
  JOIN (SELECT EmployeeID, ReportID, MAX(DaysofWeek) AS DaysofWeek
          FROM sub
         GROUP BY EmployeeID, ReportID) Y
   ON X.DaysofWeek = Y.DaysofWeek
   and X.EmployeeID = Y.EmployeeID
   and X.ReportID = Y.ReportID

2 个答案:

答案 0 :(得分:0)

查询本身可能会得到更好的清理,但是如果您当前的查询正在运行并向您显示您已指示的输出,但是您希望将其减少到您指示的所需输出,则应该能够使用with子句执行如下操作:

with sub as(
SELECT Employees.CustomerID, X.*, Customers.ReportID
FROM 
    (
    SELECT
        CASE WHEN [M] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Tu] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [W] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Th] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [F] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Sa] = '1' THEN 1 ELSE 0 END +
        CASE WHEN [Su] = '1' THEN 1 ELSE 0 END AS DaysofWeek
    FROM
        Customers
    ) X INNER JOIN Employees ON Employees.EmployeesID = Customers.EmployeesID
GROUP BY Employees.CustomerID, Customers.ReportID, X.DaysofWeek
)
select x.*
  from sub x
  join (select customerid, reportid, max(daysofweek) as daysofweek
          from sub
         group by customerid, reportid) y
    on x.daysofweek = y.daysofweek
   and x.customerid = y.customerid
   and x.reportid = y.reportid

你的加入条款也已关闭。

答案 1 :(得分:0)

首先,您的查询应如下所示:

SELECT e.CustomerID, c.DaysOfWeek, c.ReportId
FROM (SELECT c.*,
             (CASE WHEN [M] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [Tu] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [W] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [Th] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [F] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [Sa] = '1' THEN 1 ELSE 0 END +
              CASE WHEN [Su] = '1' THEN 1 ELSE 0 END
             ) AS DaysofWeek
      FROM Customers c
     ) c JOIN
     Employees e
     ON e.EmployeesID = c.EmployeesID
GROUP BY e.CustomerID, c.ReportID, c.DaysofWeek;

我对连接提出质疑(为什么Employee.CustomerId不会加入Customers表?),但这就是你拥有它的方式。要获取一周中最大日期的报告,请使用DENSE_RANK()

SELECT e.CustomerID, c.DaysOfWeek, c.ReportId
FROM (SELECT c.*, DENSE_RANK() OVER (PARTITION BY c.EmployeesId ORDER BY DaysOfWeek DESC) as seqnum
      FROM (SELECT c.*,
                   (CASE WHEN [M] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [Tu] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [W] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [Th] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [F] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [Sa] = '1' THEN 1 ELSE 0 END +
                    CASE WHEN [Su] = '1' THEN 1 ELSE 0 END
                    ) AS DaysofWeek
            FROM Customers c
           ) c
     ) c JOIN
     Employees e
     ON e.EmployeesID = c.EmployeesID
WHERE seqnum = 1
GROUP BY e.CustomerID, c.ReportID, c.DaysofWeek;