我为这个神秘的标题道歉。我想我无法将我的问题浓缩为一个标题,这表明我无法回答以下问题:
我有两个表(MS SQL Server 2012)中的数据。一张桌子produced和packaged。
中的数据produced具有order number,product code和start date:
产生
pr_order | code | startdate
---------------------------------
8000009 | pr_12 | 2016-05-23
8000002 | pr_12 | 2016-04-01
8000001 | pr_12 | 2016-03-29
8000010 | pr_10 | 2016-05-26
8000008 | pr_10 | 2016-05-01
etc.
Run Code Online (Sandbox Code Playgroud)
在数据packaged为order number,produced product code,packaged product code和一个start date:
包装好的
pa_order | pr_code | pa_code | startdate
----------------------------------------------
7000100 | pr_12 | pa_999 | 2016-05-26
7000102 | pr_12 | pa_888 | 2016-05-24
7000098 | pr_12 | pa_777 | 2016-04-01
7000088 | pr_12 | pa_999 | 2016-03-31
7000104 | pr_12 | pa_808 | 2016-03-30
7000105 | pr_10 | pa_101 | 2016-05-26
7000109 | pr_10 | pa_202 | 2016-05-26
7000099 | pr_10 | pa_107 | 2016-05-26
7000095 | pr_10 | pa_202 | 2016-05-03
7000094 | pr_10 | pa_107 | 2016-05-02
7000093 | pr_10 | pa_666 | 2016-05-01
etc.
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个查询,显示produced订单号的packaged订单号。
以下适用:
packaged order pr_code==produced order codepackaged order startdate>=produced order startdate- 但a仅在以下
packaged order情况下“链接”到 aproduced order:具有相同 的两个记录
packaged order startdate之间的下降。produced order startdatesproduced order codeproduced order有一个或多个packaged order(s)packaged order有一个produced order
结果应如下所示:
pa_code | pr_code | pa_order | pr_order
--------------------------------------------------
pa_999 | pr_12 | 7000100 | 8000009
pa_999 | pr_12 | 7000088 | 8000001
pa_888 | pr_12 | 7000102 | 8000009
pa_808 | pr_12 | 7000104 | 8000001
pa_777 | pr_12 | 7000098 | 8000002
pa_202 | pr_10 | 7000109 | 8000010
pa_202 | pr_10 | 7000095 | 8000008
etc.
Run Code Online (Sandbox Code Playgroud)
基本上,考虑到生产和包装订单的开始日期,我正在尝试创建一个包装订单所属的生产订单概览。
我已经尝试过(很多变体)以下(在这里小提琴):
SELECT p.pa_code
,p.pr_code
,p.pa_order
,r.pr_order
FROM packaged p
JOIN produced r
ON p.pr_code = r.code
AND p.startdate <= r.startdate
AND p.startdate > (
SELECT ISNULL(MAX(o.startdate),r.startdate)
FROM produced o
WHERE o.code = p.pr_code
AND o.startdate < r.startdate
)
ORDER BY p.pa_order DESC;
Run Code Online (Sandbox Code Playgroud)
这导致(很多变化)这个:
pa_code | pr_code | pa_order | pr_order
--------|---------|----------|----------
pa_202 | pr_10 | 7000109 | 8000010 correct
pa_101 | pr_10 | 7000105 | 8000010 correct
pa_808 | pr_12 | 7000104 | 8000002 wrong
pa_999 | pr_12 | 7000100 | 8000009 correct
pa_107 | pr_10 | 7000099 | 8000010 correct
pa_777 | pr_12 | 7000098 | 8000002 correct
pa_202 | pr_10 | 7000095 | 8000010 wrong
pa_107 | pr_10 | 7000094 | 8000010 wrong
pa_999 | pr_12 | 7000088 | 8000002 wrong
--and order 7000093 is missing...
Run Code Online (Sandbox Code Playgroud)
我只是不明白如何根据订单的开始日期将打包订单链接到生产订单。(仅当打包开始日期等于或大于相应的生产订单并且该打包订单的开始日期低于“下一个”(如果有)生产订单的开始日期时,打包订单才“链接”到生产订单。 (我希望这是有道理的...)
基于示例数据的正确结果应该是:
pa_code | pr_code | pa_order | pr_order
--------|---------|----------|----------
pa_202 | pr_10 | 7000109 | 8000010
pa_101 | pr_10 | 7000105 | 8000010
pa_808 | pr_12 | 7000104 | 8000001
pa_999 | pr_12 | 7000100 | 8000009
pa_107 | pr_10 | 7000099 | 8000010
pa_777 | pr_12 | 7000098 | 8000002
pa_202 | pr_10 | 7000095 | 8000008
pa_107 | pr_10 | 7000094 | 8000008
pa_666 | pr_10 | 7000093 | 8000008
pa_999 | pr_12 | 7000088 | 8000001
Run Code Online (Sandbox Code Playgroud)
谁能帮助我了解如何获得正确的结果集?(抱歉问了这么长的问题!)
因此,经过大量的思考和反复试验(我必须承认大部分错误),我似乎偶然发现了我的问题的答案。
我做了以下事情:
- 创建一个临时表来保存结果,我们称之为
result。- 填写
result数据packaged。- 使用订单更新临时表
produced。
临时表:
CREATE TABLE #result
(
pa_order INT NOT NULL
,pr_code NVARCHAR(5) NOT NULL
,pa_code NVARCHAR(6) NOT NULL
,startdate DATE NOT NULL
,pr_order INT NULL
);
Run Code Online (Sandbox Code Playgroud)
我使用这个查询(还没有小提琴,因为我不断收到网关超时)(此处小提琴):
UPDATE p
SET p.pr_order =
(
SELECT MIN(r.pr_order) [pr_order]
FROM produced r
WHERE r.code = p.pr_code
AND
(
r.startdate >=
(
SELECT ISNULL(MAX(r.startdate), p.startdate)
FROM produced r
WHERE r.code = p.pr_code
AND r.startdate <= p.startdate
)
AND
r.startdate <=
(
SELECT ISNULL(MAX(pr.startdate), r.startdate)
FROM produced pr
WHERE pr.code = p.pr_code
AND pr.startdate > r.startdate
)
)
)
FROM #result p;
Run Code Online (Sandbox Code Playgroud)
这会产生以下结果:
pa_code | pr_code | pa_order | pr_order
---------|----------|-----------|----------
pa_202 | pr_10 | 7000109 | 8000010
pa_101 | pr_10 | 7000105 | 8000010
pa_808 | pr_12 | 7000104 | 8000001
pa_888 | pr_12 | 7000102 | 8000009
pa_999 | pr_12 | 7000100 | 8000009
pa_107 | pr_10 | 7000099 | 8000010
pa_777 | pr_12 | 7000098 | 8000002
pa_202 | pr_10 | 7000095 | 8000008
pa_107 | pr_10 | 7000094 | 8000008
pa_666 | pr_10 | 7000093 | 8000008
pa_999 | pr_12 | 7000088 | 8000001
Run Code Online (Sandbox Code Playgroud)
这正是我所期望的。我不确定这是否是最优雅或“最好”的解决方案,但对我来说,它有效。