这是我的桌子
| prdntVrsnNum | matlNum | wrkCtrCd | ritmValFromDt | versnValFromDt | parmVldFromDt | rtgTypeCd | rtgGrpCd | rtgNodeNum | charVal |
| ------------ | ------- | -------- | ------------- | -------------- | ------------- | --------- | -------- | ---------- | ------- |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20170407 | N | 50020937 | 1 | 7 |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20170407 | N | 50020937 | 1 | 7 |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20180101 | N | 50020937 | 1 | 7 |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20180101 | N | 50020937 | 1 | 7 |
| V003 | 197774 | TOU-A16 | 20181210 | 20181207 | 20190107 | N | 50018492 | 6 | 1 |
| V003 | 197774 | TOU-A16 | 20181210 | 20181207 | 20190107 | N | 50018492 | 6 | 1 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20141211 | N | 50018966 | 1 | 5 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20151227 | N | 50018966 | 1 | 4.5 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20141211 | N | 50018966 | 1 | 5 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20151227 | N | 50018966 | 1 | 4.5 |
所需结果:
TOU-A16/V003/197774/20181210
TO-HCH2/V001/96228/20180101
LI-LIN2/V001/66850/20180101
要求/条件:
将prdntVrsnNum
,matlNum
,wrkCtrCd
作为键列,
根据rtgTypeCd
,rtgGrpCd
,rtgNodeNum
,parmVldFromDt
,charVal
如果未找到任何记录,则不执行任何操作。
如果找到一条记录,请ritmValFromDt
进行串联
如果找到多个记录,请查看有多少记录具有parmVldFromDt
> = ritmValFromDt
4.1。如果找到一条记录,则使用ritmValFromDt
进行串联。
4.2。如果找到多个记录,则使用parmVldFromDt
进行串联。
我用来解释的中间结果:
SELECT distinct * from mytable;
| prdntVrsnNum | matlNum | wrkCtrCd | ritmValFromDt | versnValFromDt | parmVldFromDt | rtgTypeCd | rtgGrpCd | rtgNodeNum | charVal |
| ------------ | ------- | -------- | ------------- | -------------- | ------------- | --------- | -------- | ---------- | ------- |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20170407 | N | 50020937 | 1 | 7 |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20180101 | N | 50020937 | 1 | 7 |
| V003 | 197774 | TOU-A16 | 20181210 | 20181207 | 20190107 | N | 50018492 | 6 | 1 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20141211 | N | 50018966 | 1 | 5 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20151227 | N | 50018966 | 1 | 4.5 |
从上表开始,现在我将其简化为以下最终表,将其用于串联。
| prdntVrsnNum | matlNum | wrkCtrCd | ritmValFromDt | versnValFromDt | parmVldFromDt | rtgTypeCd | rtgGrpCd | rtgNodeNum | charVal |
| ------------ | ------- | -------- | ------------- | -------------- | ------------- | --------- | -------- | ---------- | ------- |
| V001 | 96228 | TO-HCH2 | 20170407 | 20170407 | 20180101 | N | 50020937 | 1 | 7 |
| V003 | 197774 | TOU-A16 | 20181210 | 20181207 | 20190107 | N | 50018492 | 6 | 1 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20141211 | N | 50018966 | 1 | 5 |
| V001 | 66850 | LI-LIN2 | 20180101 | 20141211 | 20151227 | N | 50018966 | 1 | 4.5 |
编辑:进一步的解释:
V001|96228|TO-HCH2
处于条件4.2
。V003|197774|TOU-A16
处于条件4.1
。V001|66850|LI-LIN2
我认为这种情况是通过选择ritmValFromDt
来实现的,因为那是更大的条件,并且对于具有parmVldFromDt >= ritmValFromDt
的组合,我们没有任何记录,但是我不确定这一点虽然..:(DB小提琴:https://www.db-fiddle.com/f/qZLyGdyv2spYe3ZokZhYAP/1
到目前为止,我已经尝试过:
SELECT
DISTINCT
CONCAT(wrkCtrCd, '/', prdntVrsnNum , '/', matlNum , '/', ritmValFromDt)
AS outputCol
FROM mytable;
| outputCol |
| ---------------------------- |
| TO-HCH2/V001/96228/20170407 |
| TOU-A16/V003/197774/20181210 |
SELECT
DISTINCT
CONCAT(wrkCtrCd, '/', prdntVrsnNum , '/', matlNum , '/',
CASE
WHEN parmVldFromDt >= ritmValFromDt THEN parmVldFromDt
ELSE ritmValFromDt
END)
AS outputCol
FROM mytable;
| outputCol |
| ---------------------------- |
| TO-HCH2/V001/96228/20170407 |
| TO-HCH2/V001/96228/20180101 |
| TOU-A16/V003/197774/20190107 |
注意
使用SQL时,请尽可能与供应商无关。这不在我手中。我不是从来源查询,所以我的双手被绑住了。某些特定于供应商的功能可能可用,但这不是保证。
在db-fiddle中,MySQL(和使用的版本)仅用于说明目的。如前所述,我不是从RDBMS查询,而是从网格查询,因此我必须根据网格中的可用内容和可用方式进行调整。
答案 0 :(得分:1)
我认为您没有正确定义条件。特别是,对于最后一个条件,您似乎想要最新的日期。
我会为此寻求窗口功能。我认为逻辑是:
SELECT CONCAT(wrkCtrCd, '/', prdntVrsnNum , '/', matlNum , '/',
(CASE WHEN cnt = 1 OR cnt_gt = 1
THEN ritmValFromDt
ELSE parmVldFromDt
END)
) AS outputCol,
ritmValFromDt,parmVldFromDt
FROM (SELECT t.*,
COUNT(*) OVER (PARTITION BY prdntVrsnNum, matlNum, wrkCtrCd) as cnt,
SUM(gt_flag) OVER (PARTITION BY prdntVrsnNum, matlNum, wrkCtrCd) as cnt_gt,
ROW_NUMBER() OVER (PARTITION BY prdntVrsnNum, matlNum, wrkCtrCd, gt_flag ORDER BY parmVldFromDt DESC) as seqnum
FROM (SELECT DISTINCT prdntVrsnNum, matlNum, wrkCtrCd, ritmValFromDt, versnValFromDt, parmVldFromDt,
(CASE WHEN parmVldFromDt >= ritmValFromDt THEN 1 ELSE 0 END) as gt_flag
FROM mytable
) t
) t
WHERE (cnt_gt > 0 AND parmVldFromDt >= ritmValFromDt AND seqnum = 1) OR
(cnt_gt = 0);
Here是db <>小提琴。
答案 1 :(得分:0)
我想出了一个在小提琴上尝试过的答案。不知道它是否可以在我的实际系统中运行(必须立即进行测试)。我不确定这是否是实现它的最佳/唯一方法。
select
distinct
concat(distinctTable.wrkCtrCd, '/',
distinctTable.prdntVrsnNum, '/',
distinctTable.matlNum, '/',
case when countTable.cnt = 1 then min(distinctTable.ritmValFromDt)
else max(distinctTable.parmVldFromDt)
end
) as outputCol
from
(
select
tbl.prdntVrsnNum,
tbl.matlNum,
tbl.wrkCtrCd,
count(*) as cnt
from
(select distinct * from mytable) as tbl
group by
tbl.prdntVrsnNum,
tbl.matlNum,
tbl.wrkCtrCd
) as countTable
inner join (select distinct * from mytable) as distinctTable
on countTable.prdntVrsnNum = distinctTable.prdntVrsnNum
and countTable.matlNum = distinctTable.matlNum
and countTable.wrkCtrCd = distinctTable.wrkCtrCd
group by
distinctTable.prdntVrsnNum,
distinctTable.matlNum,
distinctTable.wrkCtrCd;
| outputCol |
| ---------------------------- |
| TO-HCH2/V001/96228/20180101 |
| TOU-A16/V003/197774/20181210 |