2014-09-23 47 views
0

在我的查询中,我返回了每周发生的天数。一切工作正常,除了我得到多行返回,我只需要最高。因此,例如在我的查询中,如果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,都可以有无限的ReportIDs,我想要返回所有这些,但仅适用于DaysofWeek最高的地方。

因此,EmployeeID 200可能会有报告1001和1002,每个报告每周2天返回。应该采取什么节目是

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 
+0

什么是您的RDBMS? – Horaciux 2014-09-23 01:43:45

+0

为什么员工上有一个CustomerID字段?我无法弄清楚你的模式。您在注释中将200称为EmployeeID,但在SQL语句中有Employees.CustomerID。 – 2014-09-23 01:44:34

+0

我认为你正在通过客户表获得某种自动加入。您正在从Customers表中选择东西,这在技术上不是您正在选择的表格之一。要更清楚地在X中包含ReportID和employeeID – 2014-09-23 01:49:34

回答

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 

而且您的加盟条款是关闭的。

+0

这里的问题是,它显示了所有值5,即使最高的为一个给定的客户ID和ReportID为1 – aantiix 2014-09-23 01:51:53

+0

@ doby48想我只是离开了一个连接的reportid,你可以尝试重新运行它编辑?同样在这种情况下,您应该更容易在内部查询中使用max,但是如果您还想要选择不起作用的附加列,而上述内容应该可以工作。 – 2014-09-23 02:02:14

+0

没有这样的运气仍然只显示5的所有值。如果我删除MAX(DaysofWeek),那么我确实再次看到所有重复项,所以我的猜测是问题在那里。 – aantiix 2014-09-23 17:41:57

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;