我有两个看起来像这样的表。一个拥有“包装”数据,另一个拥有“配方”数据。
Order# Lot# Pkg# Time
----------------------------
188688 PVB079 19 2:34
188688 PVB079 24 3:15
188688 PVB079 18 4:08
188688 PVB079 13 5:02
188688 PVB079 14 5:40
188688 PVB079 16 6:18
188688 PVB079 15 6:48
188688 PVB079 21 7:22
188688 PVB079 17 8:12
Order# Recipe Version Time
------------------------------
188688 EP01 1 2:35
188688 EP01 2 4:09
188688 EP01 3 6:49
我可以将它们联合在一起,并在时间戳之前对其进行排序,以获取类似于以下内容的内容...
Order# Lot# Pkg# Time Recipe Version
----------------------------------------------
188688 PVB079 19 2:34 -- --
188688 -- -- 2:35 EP01 1
188688 PVB079 24 3:15 -- --
188688 PVB079 18 4:08 -- --
188688 -- -- 4:09 EP01 2
188688 PVB079 13 5:02 -- --
188688 PVB079 14 5:40 -- --
188688 PVB079 16 6:18 -- --
188688 PVB079 15 6:48 -- --
188688 -- -- 6:49 EP01 3
188688 PVB079 21 7:22 -- --
188688 PVB079 17 8:12 -- --
但是,我想将它们组合在一起,以便配方数据与其前面的1个包装和后面的其他包装在同一行。我理想的结果看起来像这样...
Order# Lot# Pkg# PkgTime Recipe Version RecipeTime
---------------------------------------------------------------
188688 PVB079 19 2:34 EP01 1 2:35
188688 PVB079 24 3:15 EP01 1 2:35
188688 PVB079 18 4:08 EP01 2 4:09
188688 PVB079 13 5:02 EP02 2 4:09
188688 PVB079 14 5:40 EP02 2 4:09
188688 PVB079 16 6:18 EP02 2 4:09
188688 PVB079 15 6:48 EP02 3 6:49
188688 PVB079 21 7:22 EP02 3 6:49
188688 PVB079 17 8:12 EP02 3 6:49
操作上,输入包装(时间戳),然后他们获得配方(时间戳)。但是有时候配方不会改变。因此,他们对以下软件包使用相同的配方,直到配方更改为止。
有可能吗?我怎样才能像这样合并这两个表?
答案 0 :(得分:1)
根据Gordon Linoff的回答,这似乎与您的问题相符
select p.*, r.*
from package p
outer apply
(select top (1) r.*
from recipe r
where r.rec_order = p.pkg_order and r.rec_time < isnull((
select min(p2.pkg_time)
from package p2
where p2.pkg_order = p.pkg_order and p2.pkg_time > p.pkg_time
), convert(datetime2, '9999-12-31'))
order by r.rec_time desc
) r
order by pkg_time
答案 1 :(得分:0)
这与union
无关。您可以使用横向联接(在SQL Server中使用apply
:
select p.*, r.*
from package p outer apply
(select top (1) r.*
from recipe r
where r.order# = p.order# and r.time > p.time
order by r.time asc
) r;
横向联接就像一个相关的子查询,可以返回多列和多行(尽管在这种情况下,它只返回一行)。
答案 2 :(得分:0)
类似的事情应该起作用:
SELECT
package.`Order#`,
package.`Lot#`,
package.`Pkg#`,
package.`Time` AS PkgTime,
recipe.Recipe,
recipe.`Version`,
recipe.`Time` AS RecipeTime
FROM (
SELECT
p.`Order#` AS keyOrder,
MAX(IF(p.Time < r.Time, p.Time, NULL)) AS startTime,
COALESCE(MAX(IF(p.Time < r2.Time, p.Time, NULL)), MAX(p.Time)+1 ) AS endTime,
r.`Version` AS keyRecipeVersion,
r.Time AS r1t,
r2.Time AS r2t
FROM recipe AS r
LEFT JOIN recipe AS r2 ON r2.`Order#` = r.`Order#` AND r2.Version = 1 + r.Version
JOIN package AS p ON p.`Order#` = r.`Order#` -- all packages.
GROUP BY p.`Order#`, r.`Version`
) AS k
JOIN recipe ON keyOrder = recipe.`Order#` AND keyRecipeVersion = recipe.`Version`
JOIN package ON keyOrder = package.`Order#`
AND package.`Time` >= startTime AND package.`Time` < endTime
-- recipe start is 1 back package time.
;
这个想法是将您想要的记录提炼为一组“关键字段”,然后可以将它们重新联接回源表。在这种情况下,您的索引编制能力很弱,并且您的数据没有很好的组织,因此有点棘手,功能也不那么强大。
使用OUTER APPLY
的另一个答案可能更优雅,我只是想尽可能避免使用非ANSI SQL。
注意:这也可以通过将UNION
与GROUP BY
包装在一起来完成,但我绝对不建议这样做。 UNION
会导致混乱的查询不一致,并且主要用于快速将某些事物拍打在一起。