编辑:重新提出整个问题。第一次带错了方式。
结果应该是:
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
显示OrderNo
与StartDate
相关联的任务的第一个DateTime
。表中的Route.No
字段。
如果无法在一个JobSummary.StarDate
语句中检查CASE
和SELECT 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
答案 0 :(得分:3)
您可以PARTITION BY
与taskID
一起使用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
答案 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方法在这方面肯定会更灵活。