Microsoft SQL 服务器:select 每台机器上生产的每个零件号的前 N 个,union 和 unpivot
Microsoft SQL Server : select top N of each part number produced on each machine, union, and unpivot
我有两台机器,每台机器都生产相同的零件号。每台机器都有三个参数。数据存储在一行中。我想 select 根据下降时间在每台机器上生产的每个零件号的前 N 个结果(即机器 1 和 2 上生产的零件 1、2、3 和 4 的最新 5 个结果),unpivot结果并用每个新的行号显示它们。环境是 Microsoft SQL Server 2016.
示例数据:
id PartNumber WorkCenter UniquePartID Measurement1 Measurement2 Measurement3 transactionDT
--------------------------------------------------------------------------------------------------------------
1 1 1 78 24.2 20.6 24.6 2018-08-10 11:03:34.000
2 1 2 135 24.3 20.7 24.7 2018-08-10 11:03:28.000
3 2 2 45 58.7 49.9 59.6 2018-08-09 11:03:22.000
4 2 2 32 58.6 49.8 59.5 2018-08-09 11:03:16.000
5 3 1 65 42.2 35.9 42.8 2018-08-07 11:03:10.000
6 3 2 96 42.2 35.9 42.8 2018-08-07 11:03:04.000
7 4 1 12 108.2 92 109.8 2018-08-06 11:02:57.000
8 4 2 54 108.4 92.1 110.2 2018-08-06 11:02:50.000
9 1 1 77 24.2 20.6 24.6 2018-08-05 11:02:43.000
10 1 1 76 24.2 20.6 24.6 2018-08-05 11:02:36.000
所需结果的前几行:
ROWID PARTNUMBER TIMESTAMP WORKCENTER UniquePartID PARAMETER MEASUREMENT
------------------------------------------------------------------------------------------------
1 1 2018-08-10 11:03:34.000 1 78 Measurement 1 24.2
2 1 2018-08-10 11:03:34.000 1 78 Measurement 2 20.6
3 1 2018-08-10 11:03:34.000 1 78 Measurement 3 24.6
4 1 2018-08-10 11:03:28.000 2 135 Measurement 1 24.3
5 1 2018-08-05 11:02:43.000 2 135 Measurement 2 20.7
6 1 2018-08-05 11:02:36.000 2 135 Measurement 3 24.7
T-SQL 使用的语句:
SELECT
ROW_NUMBER() OVER (ORDER BY TIMESTAMP DESC) ROWID,
*
FROM
(SELECT DISTINCT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement1' AS PARAMETER,
measurement1 AS MEASUREMENT
FROM
parts.dbo.data
UNION
SELECT DISTCINT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement2' AS PARAMETER,
measurement2 AS MEASUREMENT
FROM
parts.dbo.data
UNION
SELECT DISTCINT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement3' AS PARAMETER,
measurement3 AS MEASUREMENT
FROM
parts.dbo.data) a
ORDER BY
TIMESTAMP DESC, PARAMETER ASC
谢谢!
******已更新 t-SQL 代码
SELECT ROW_NUMBER() OVER(PARTITION BY PARTNUMBER, WORKCENTER ORDER BY
TIMESTAMP DESC) ROWID, *
FROM (
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE
WHEN WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement1' AS PARAMETER,
Measurement1 AS MEASUREMENT, Measurement1Min AS
SPEC_MIN, Measurement1Nominal AS NOMINAL, Measurement1Max AS SPEC_MAX
FROM parts.dbo.data
UNION ALL
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE
WHEN WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement2' AS PARAMETER,
Measurement2 AS MEASUREMENT, Measurement2Min AS
SPEC_MIN, Measurement2Nominal AS NOMINAL, Measurement2Max AS SPEC_MAX
FROM parts.dbo.data
UNION ALL
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE WHEN
WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement3' AS PARAMETER,
Measurement3 AS MEASUREMENT, Measurement3Min AS
SPEC_MIN, Measurement3Nominal AS NOMINAL, Measurement3Max AS SPEC_MAX
FROM parts.dbo.data) a
order by TIMESTAMP DESC, PARAMETER ASC
挑战 - 这 returns 每条记录 3 行...我想要 3 行用于每个零件号/工作中心组合的前 N 个。
你的语句的问题是你在 UNION
查询的每一部分都使用了 TOP 10
而没有排序。
我猜你想要这样的东西:
SELECT ROW_NUMBER() OVER (ORDER BY transactionDT DESC, MEASUREMENT) ROWID,
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, WorkCenter AS WORKCENTER,
UniquePartID, PARAMETER, MEASUREMENT
FROM
(SELECT TOP (10) PartNumber, WorkCenter, UniquePartID,
transactionDT, Measurement1, Measurement2, Measurement3
FROM parts.dbo.data
ORDER BY transactionDT DESC) AS pvt
UNPIVOT (MEASUREMENT FOR PARAMETER IN (Measurement1, Measurement2, Measurement3)) AS upvt;
已更新...
在要求扩展到 4 列而不是 1 列之后,我似乎找不到与使用 UNION ALL
方法不同的方法来解决这个问题。与我对原始问题的回答中的 TOP N
一样,我对扩展要求的解决方案中带有 ROW_NUMBER()
的编号必须完成 "early",在这种情况下,这意味着它必须UNION
查询的每个部分都已经发生了。 TOP 10
将在末尾使用 WHERE
子句找到:
WITH
NumberedRecords (ROWID, PARTNUMBER, TIMESTAMP, WORKCENTER, UniquePartID, PARAMETER, MEASUREMENT, SPEC_MIN, NOMINAL, SPEC_MAX) AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 1', Measurement1, Measurement1Min, Measurement1Nominal, Measurement1Max
FROM parts.dbo.data
UNION ALL
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 2', Measurement2, Measurement2Min, Measurement2Nominal, Measurement2Max
FROM parts.dbo.data
UNION ALL
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 3', Measurement3, Measurement3Min, Measurement3Nominal, Measurement3Max
FROM parts.dbo.data
)
SELECT * FROM NumberedRecords WHERE ROWID <= 10;
简单的方法:
现在知道这将是一个使用 UNION
的查询,有一个简单的解决方案,只需对您已经执行的操作稍作改动,即可同时适用于您的原始查询和更新后的查询:
在外部查询中 ROW_NUMBER
函数的 OVER
子句中,添加用于分区的字段 PARAMETER
。
当然,最后使用 WHERE
子句:
WHERE ROWID <= 10
我有两台机器,每台机器都生产相同的零件号。每台机器都有三个参数。数据存储在一行中。我想 select 根据下降时间在每台机器上生产的每个零件号的前 N 个结果(即机器 1 和 2 上生产的零件 1、2、3 和 4 的最新 5 个结果),unpivot结果并用每个新的行号显示它们。环境是 Microsoft SQL Server 2016.
示例数据:
id PartNumber WorkCenter UniquePartID Measurement1 Measurement2 Measurement3 transactionDT
--------------------------------------------------------------------------------------------------------------
1 1 1 78 24.2 20.6 24.6 2018-08-10 11:03:34.000
2 1 2 135 24.3 20.7 24.7 2018-08-10 11:03:28.000
3 2 2 45 58.7 49.9 59.6 2018-08-09 11:03:22.000
4 2 2 32 58.6 49.8 59.5 2018-08-09 11:03:16.000
5 3 1 65 42.2 35.9 42.8 2018-08-07 11:03:10.000
6 3 2 96 42.2 35.9 42.8 2018-08-07 11:03:04.000
7 4 1 12 108.2 92 109.8 2018-08-06 11:02:57.000
8 4 2 54 108.4 92.1 110.2 2018-08-06 11:02:50.000
9 1 1 77 24.2 20.6 24.6 2018-08-05 11:02:43.000
10 1 1 76 24.2 20.6 24.6 2018-08-05 11:02:36.000
所需结果的前几行:
ROWID PARTNUMBER TIMESTAMP WORKCENTER UniquePartID PARAMETER MEASUREMENT
------------------------------------------------------------------------------------------------
1 1 2018-08-10 11:03:34.000 1 78 Measurement 1 24.2
2 1 2018-08-10 11:03:34.000 1 78 Measurement 2 20.6
3 1 2018-08-10 11:03:34.000 1 78 Measurement 3 24.6
4 1 2018-08-10 11:03:28.000 2 135 Measurement 1 24.3
5 1 2018-08-05 11:02:43.000 2 135 Measurement 2 20.7
6 1 2018-08-05 11:02:36.000 2 135 Measurement 3 24.7
T-SQL 使用的语句:
SELECT
ROW_NUMBER() OVER (ORDER BY TIMESTAMP DESC) ROWID,
*
FROM
(SELECT DISTINCT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement1' AS PARAMETER,
measurement1 AS MEASUREMENT
FROM
parts.dbo.data
UNION
SELECT DISTCINT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement2' AS PARAMETER,
measurement2 AS MEASUREMENT
FROM
parts.dbo.data
UNION
SELECT DISTCINT TOP 10
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP,
CASE
WHEN WorkCenter = 1 THEN 'WC 1'
WHEN WorkCenter = 2 THEN 'WC 2'
END AS WORKCENTER,
UniquePartID, 'Measurement3' AS PARAMETER,
measurement3 AS MEASUREMENT
FROM
parts.dbo.data) a
ORDER BY
TIMESTAMP DESC, PARAMETER ASC
谢谢!
******已更新 t-SQL 代码
SELECT ROW_NUMBER() OVER(PARTITION BY PARTNUMBER, WORKCENTER ORDER BY
TIMESTAMP DESC) ROWID, *
FROM (
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE
WHEN WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement1' AS PARAMETER,
Measurement1 AS MEASUREMENT, Measurement1Min AS
SPEC_MIN, Measurement1Nominal AS NOMINAL, Measurement1Max AS SPEC_MAX
FROM parts.dbo.data
UNION ALL
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE
WHEN WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement2' AS PARAMETER,
Measurement2 AS MEASUREMENT, Measurement2Min AS
SPEC_MIN, Measurement2Nominal AS NOMINAL, Measurement2Max AS SPEC_MAX
FROM parts.dbo.data
UNION ALL
SELECT PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, CASE WHEN
WorkCenter = 1 THEN 'Work Center 1' WHEN WorkCenter = 2 THEN 'Work
Center 2' END AS WORKCENTER, UniquePartID, 'Measurement3' AS PARAMETER,
Measurement3 AS MEASUREMENT, Measurement3Min AS
SPEC_MIN, Measurement3Nominal AS NOMINAL, Measurement3Max AS SPEC_MAX
FROM parts.dbo.data) a
order by TIMESTAMP DESC, PARAMETER ASC
挑战 - 这 returns 每条记录 3 行...我想要 3 行用于每个零件号/工作中心组合的前 N 个。
你的语句的问题是你在 UNION
查询的每一部分都使用了 TOP 10
而没有排序。
我猜你想要这样的东西:
SELECT ROW_NUMBER() OVER (ORDER BY transactionDT DESC, MEASUREMENT) ROWID,
PartNumber AS PARTNUMBER, transactionDT AS TIMESTAMP, WorkCenter AS WORKCENTER,
UniquePartID, PARAMETER, MEASUREMENT
FROM
(SELECT TOP (10) PartNumber, WorkCenter, UniquePartID,
transactionDT, Measurement1, Measurement2, Measurement3
FROM parts.dbo.data
ORDER BY transactionDT DESC) AS pvt
UNPIVOT (MEASUREMENT FOR PARAMETER IN (Measurement1, Measurement2, Measurement3)) AS upvt;
已更新...
在要求扩展到 4 列而不是 1 列之后,我似乎找不到与使用 UNION ALL
方法不同的方法来解决这个问题。与我对原始问题的回答中的 TOP N
一样,我对扩展要求的解决方案中带有 ROW_NUMBER()
的编号必须完成 "early",在这种情况下,这意味着它必须UNION
查询的每个部分都已经发生了。 TOP 10
将在末尾使用 WHERE
子句找到:
WITH
NumberedRecords (ROWID, PARTNUMBER, TIMESTAMP, WORKCENTER, UniquePartID, PARAMETER, MEASUREMENT, SPEC_MIN, NOMINAL, SPEC_MAX) AS (
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 1', Measurement1, Measurement1Min, Measurement1Nominal, Measurement1Max
FROM parts.dbo.data
UNION ALL
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 2', Measurement2, Measurement2Min, Measurement2Nominal, Measurement2Max
FROM parts.dbo.data
UNION ALL
SELECT
ROW_NUMBER() OVER(PARTITION BY PartNumber, WorkCenter ORDER BY transactionDT DESC)
, PartNumber, transactionDT, 'Work Center ' + CAST(WorkCenter AS varchar(10)), UniquePartID
, 'Measurement 3', Measurement3, Measurement3Min, Measurement3Nominal, Measurement3Max
FROM parts.dbo.data
)
SELECT * FROM NumberedRecords WHERE ROWID <= 10;
简单的方法:
现在知道这将是一个使用 UNION
的查询,有一个简单的解决方案,只需对您已经执行的操作稍作改动,即可同时适用于您的原始查询和更新后的查询:
在外部查询中 ROW_NUMBER
函数的 OVER
子句中,添加用于分区的字段 PARAMETER
。
当然,最后使用 WHERE
子句:
WHERE ROWID <= 10