【问题标题】:Trying to get the min date out of set试图让最小日期超出设置
【发布时间】:2015-10-20 19:10:26
【问题描述】:

好的,所以我有一个包含以下信息的表

Company, Employee, Work Date, Job Number
ABC      1234      06/01/15    5555
ABC      1234      06/02/15    5555
ABC      1234      06/03/15    5555
ABC      1234      06/04/15    5555
ABC      1234      06/05/15    5555
ABC      1234      06/06/15    5555
ABC      1234      06/11/15    6666
ABC      1234      06/12/15    6666
ABC      1234      06/13/15    6666
ABC      1234      06/14/15    6666
ABC      1234      06/15/15    6666
ABC      1234      06/16/15    6666

我想要的记录是

ABC      1234      06/11/15    6666

我的第一步是使用此查询获取最近的工作日期

SELECT TCH.Company_Code, TCH.Employee_Code, CAST(TCH.Work_Date AS DATE) AS Work_Date, DENSE_RANK() OVER (PARTITION BY TCH.Employee_Code ORDER BY CAST(TCH.Work_Date AS DATE) DESC) AS DateRank
    FROM PR_TIME_CARD_HISTORY_MC TCH WITH (NOLOCK)
    WHERE TCH.Company_Code <> 'XYZ' 
    AND LTRIM(RTRIM(TCH.Employee_Code)) = '22164'

第二步是将其连接回原始表以获取作业,但我似乎无法获取作业的记录集以获取最小日期。

SELECT TCH.Company_Code, TCH.Employee_Code, TCH.Job_Number, CAST(TCH.Work_Date AS DATE) AS Work_Date, DENSE_RANK() OVER (PARTITION BY TCH.Job_Number ORDER BY CAST(TCH.Work_Date AS DATE) ASC) AS JobRank
    FROM PR_TIME_CARD_HISTORY_MC TCH WITH (NOLOCK)
    WHERE TCH.Company_Code <> 'XYZ' 
    AND TCH.Pay_Type = 'R'
    AND LTRIM(RTRIM(TCH.Employee_Code)) = '22164'

希望这会有所帮助,并且肯定可以使用一些指导。

【问题讨论】:

  • 因此,员工最近的工作日期是 06/16/15,工作编号是 6666。现在我需要得到他在 6666 工作的第一天,即 2015 年 6 月 11 日上面的例子。

标签: sql sql-server min dense-rank


【解决方案1】:

在 where 子句中使用嵌套查询试试这个:

SQL Fiddle

MS SQL Server 2008 架构设置

CREATE TABLE TimeCard
(
  Company VARCHAR(10),
  Employee INT,
  WorkDate Date,
  JobNumber Int
)

INSERT INTO TimeCard
VALUES
  ('ABC', 1234, '06/01/15', 5555),
  ('ABC', 1234, '06/02/15', 5555),
  ('ABC', 1234, '06/03/15', 5555),
  ('ABC', 1234, '06/04/15', 5555),
  ('ABC', 1234, '06/05/15', 5555),
  ('ABC', 1234, '06/06/15', 5555),
  ('ABC', 1234, '06/11/15', 6666),
  ('ABC', 1234, '06/12/15', 6666),
  ('ABC', 1234, '06/13/15', 6666),
  ('ABC', 1234, '06/14/15', 6666),
  ('ABC', 1234, '06/15/15', 6666),
  ('ABC', 1234, '06/16/15', 6666)

查询 1

SELECT TC.Company, TC.Employee, MIN(TC.WorkDate) AS WorkDate, TC.JobNumber
FROM TimeCard TC
WHERE   TC.Company <> 'XYZ' AND
        TC.Employee = 1234 AND
        TC.JobNumber =
        (    
            -- Get Max JobNumber for the Max Workdate 
            SELECT MAX(JobNumber) 
            FROM TimeCard TC3
            WHERE TC3.WorkDate = 
                -- Get Max WorkDate of Employee
                (
                    SELECT MAX(WorkDate) 
                    FROM TimeCard TC2 
                    WHERE TC2.Employee = TC.Employee
                )
            GROUP BY TC3.Employee
        )
GROUP BY TC.Company, TC.Employee, TC.JobNumber

Results

| Company | Employee |   WorkDate | JobNumber |
|---------|----------|------------|-----------|
|     ABC |     1234 | 2015-06-11 |      6666 |

【讨论】:

    【解决方案2】:

    编辑:

    要获得最高Job_Number 的最低日期,您需要将两者都应用于ORDER BY

    SELECT *
    FROM
     (
        SELECT TCH.Company_Code, TCH.Employee_Code, TCH.Job_Number,
           CAST(TCH.Work_Date AS DATE) AS Work_Date, 
           ROW_NUMBER() -- latest row gets 1
           OVER (PARTITION BY TCH.Employee_Code 
                 ORDER BY TCH.Job_Number DESC, CAST(TCH.Work_Date AS DATE)) AS DateRank
        FROM PR_TIME_CARD_HISTORY_MC TCH WITH (NOLOCK)
        WHERE TCH.Company_Code <> 'XYZ' 
        AND LTRIM(RTRIM(TCH.Employee_Code)) = '1234'
     ) AS dt
    WHERE DateRank = 1
    

    但如果工作数量没有增加,你需要一个不同的逻辑:

    SELECT *
    FROM
     (
        SELECT TCH.Company_Code, TCH.Employee_Code, TCH.Job_Number,
           CAST(TCH.Work_Date AS DATE) AS Work_Date, 
           ROW_NUMBER() -- latest row gets 1
           OVER (PARTITION BY TCH.Employee_Code 
                 ORDER BY CAST(TCH.Work_Date AS DATE)) AS DateRank, 
    
             -- The start date of each job
           MIN(CAST(TCH.Work_Date AS DATE))
           OVER (PARTITION BY TCH.Employee_Code, TCH.Job_Number) AS FirstWorkDate
        FROM PR_TIME_CARD_HISTORY_MC TCH WITH (NOLOCK)
        WHERE TCH.Company_Code <> 'XYZ' 
        AND LTRIM(RTRIM(TCH.Employee_Code)) = '1234'
     ) AS dt
    WHERE DateRank = 1
    

    【讨论】:

    • 我需要的是最近的工作和最近工作的第一天。我认为这会给我最近的工作,但我如何获得该工作的记录集,然后获得该工作的第一次约会?
    • @stylusnix:Job_Number 是否总是随着时间增加?然后只需更改为ORDER BY Job_Number DESC CAST(TCH.Work_Date AS DATE)。否则会更复杂,您确切的 SQL Server 版本是什么?
    • 一名员工可以从事许多工作 - 通常他们会继续工作,然后再继续工作 - 有时他们可能会在一天内同时从事两份工作,但这种情况非常罕见。 SQL 版本 - 2012
    【解决方案3】:

    我觉得下面的查询应该可以完成这项工作:

    SELECT company, employee, work_date,job_number FROM
    (
    SELECT 
     TCH.Company_Code as company, 
     TCH.Employee_Code as employee,
     TCH.Job_Number as job_number, 
     CAST(TCH.Work_Date AS DATE) AS Work_Date, 
     ROW_NUMBER() OVER (PARTITION BY TCH.Employee_Code,TCH.Company_Code ORDER BY TCH.Job_Number DESC,CAST(TCH.Work_Date AS DATE) ASC) AS DateRank
        FROM PR_TIME_CARD_HISTORY_MC TCH WITH (NOLOCK) 
    ) q
    WHERE q.DateRank=1
    

    【讨论】:

    • 使用它后 - 它不起作用。该死的,我充满希望。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多