T-SQL CASE检查最年轻的日期,然后检查其他值

时间:2015-06-03 12:50:23

标签: sql-server sql-server-2008 tsql datetime case

编辑:重新提出整个问题。第一次带错了方式。

结果应该是:

MachineName | OrderNo | TaskID | Code | NettoProd | BrutoProd | DiffProd
=========================================================================
F1            123456    101      O      100000      125000      25000
F1            123456    102      P8     1000000     1250000     250000
F1            123456    103      P1     10000       12500       2500
F1            123456    104      P4     100000      125000      25000

JobSummary包含以下列:

StartDate 
TaskID

Route包含以下列:

OrderNo 
TaskID

Resource保存有关机器的数据

MachineID

如果我首先提供了所有细节,我已经添加了Kyle Gobel的部分,这是正确的答案。

我想要实现的是O根据taskID显示OrderNoStartDate相关联的任务的第一个DateTime。表中的Route.No字段。

如果无法在一个JobSummary.StarDate语句中检查CASESELECT Resource.DESCRIPTION AS MachineName ,Route.OrderNo ,Route.TaskID ,CASE WHEN JobSummary.StartDate = (SELECT MIN(cr.StartDate) FROM JobSummary cr) THEN 'O' WHEN Route.No = 1 OR Route.No = 2 THEN 'P1' WHEN Route.No = 4 THEN 'P4' WHEN Route.No >= 8 THEN 'P8' ELSE '*FP*' END AS Code ,JobSummary.GoodProd As NettoProd ,JobSummary.GoodProd + JobSummary.SetupProd + JobSummary.WasteProd As BrutoProd ,(JobSummary.SetupProd + JobSummary.WasteProd) As DiffProd FROM Route JOIN Resource ON Resource.MachineID = Route.MachineID JOIN JobSummary ON JobSummary.TaskID = Route.TaskID AND JobSummary.MachineID = Route.MachineID ,那么两者的单独列也会这样做。

查询

_x

3 个答案:

答案 0 :(得分:3)

您可以PARTITION BYtaskID一起使用StartDate根据OrderNo ROW_NUMBER()OVER(PARTITION BY Route.OrderNo ORDER BY JobSummary.StartDate ASC来识别第一条记录CREATE TABLE [JobSummary] (MachineID INT,TaskID INT,StartDate DATETIME,GoodProd NUMERIC(18,0),SetupProd NUMERIC(18,0),WasteProd NUMERIC(18,0)); CREATE TABLE [Route] (OrderNo INT,MachineID INT,TaskID INT,[No] INT); CREATE TABLE [Resource] (MachineID INT,DESCRIPTION CHAR(2)); INSERT INTO [Resource] VALUES(1,'F1'); INSERT INTO [Route] VALUES(123456,1,101,1); INSERT INTO [Route] VALUES(123456,1,102,9); INSERT INTO [Route] VALUES(123456,1,103,2); INSERT INTO [Route] VALUES(123456,1,104,4); INSERT INTO [JobSummary] VALUES(1,101,'20150101',100000,20000,5000); INSERT INTO [JobSummary] VALUES(1,102,'20150103',1000000,200000,50000); INSERT INTO [JobSummary] VALUES(1,103,'20150102',10000,2000,500); INSERT INTO [JobSummary] VALUES(1,104,'20150103',100000,20000,5000); ;WITH CTE AS ( SELECT Route.No ,Resource.[DESCRIPTION] AS MachineName ,Route.OrderNo ,Route.TaskID ,JobSummary.GoodProd As NettoProd ,JobSummary.GoodProd + JobSummary.SetupProd + JobSummary.WasteProd As BrutoProd ,(JobSummary.SetupProd + JobSummary.WasteProd) As DiffProd ,ROW_NUMBER()OVER(PARTITION BY Route.OrderNo ORDER BY JobSummary.StartDate ASC) rn FROM Route JOIN Resource ON Resource.MachineID = Route.MachineID JOIN JobSummary ON JobSummary.TaskID = Route.TaskID AND JobSummary.MachineID = Route.MachineID ) SELECT MachineName, OrderNo, TaskID, CASE WHEN rn = 1 THEN 'O' WHEN No IN (1,2) THEN 'P1' WHEN No = 4 THEN 'P4' WHEN No >= 8 THEN 'P8' ELSE '*FP*' END AS Code, NettoProd, BrutoProd, DiffProd FROM CTE ORDER BY OrderNo,TaskID < / p>

示例数据和结构

MachineName OrderNo TaskID  Code    NettoProd   BrutoProd   DiffProd
F1  123456  101 O   100000  125000  25000
F1  123456  102 P8  1000000 1250000 250000
F1  123456  103 P1  10000   12500   2500
F1  123456  104 P4  100000  125000  25000

<强>查询

this

<强>输出

undefined

ROW_NUMBER()

答案 1 :(得分:2)

通过阅读您的问题,您可能正在寻找min聚合函数。

case 
   when route.startDate = (select min(r.startdate) from table r) then 'O'
   when route.no = 1 or route.no = 2 then 'P1'
   ....
end as code

答案 2 :(得分:1)

使用ROW_NUMBER可能是一个很好的起点,但由于您只想检查第一个StartDate,因此最好使用MIN() OVER。您发布的查询只需要进行一些小改动(强调):

SELECT Resource.DESCRIPTION AS MachineName
    ,Route.OrderNo
    ,Route.TaskID
    ,CASE
        WHEN JobSummary.StartDate = MIN(JobSummary.StartDate) OVER (PARTITION BY Route.OrderNo) THEN 'O'
        WHEN Route.No = 1 OR Route.No = 2 THEN 'P1'
        WHEN Route.No = 4 THEN 'P4'
        WHEN Route.No >= 8 THEN 'P8'
        ELSE '*FP*'
    END AS Code
    ,JobSummary.GoodProd As NettoProd
    ,JobSummary.GoodProd + JobSummary.SetupProd + JobSummary.WasteProd As BrutoProd
    ,(JobSummary.SetupProd + JobSummary.WasteProd) As DiffProd

FROM Route
JOIN Resource ON Resource.MachineID = Route.MachineID
JOIN JobSummary ON JobSummary.TaskID = Route.TaskID AND JobSummary.MachineID = Route.MachineID
;

也许PARTITION BY需要包含Resource.DESCRIPTION - 很难从一个小例子中说出来。

上述查询可能比ROW_NUMBER方法更快。这是因为ROW_NUMBER子集需要完全排序,而MIN()OVER只能查找每个子集中的单个值。

另一方面,如果有可能您稍后需要第二行,第三行等特殊条件,那么ROW_NUMBER方法在这方面肯定会更灵活。