首页 > 解决方案 > 如何根据返回的记录数选择列?

问题描述

这是我的桌子

| 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作为关键列,

  1. 根据rtgTypeCd, rtgGrpCd, rtgNodeNum, parmVldFromDt,删除重复项charVal

  2. 如果没有找到记录,什么也不做。

  3. 如果找到一条记录,则ritmValFromDt进行连接

  4. 如果找到多条记录,查看有多少条记录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     |

编辑:进一步解释:


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 |

笔记

  1. 使用 SQL 时,请尽可能保持供应商中立。这不在我的手中。我不是从源头查询,所以我的双手被束缚了。某些供应商特定的功能可能可用,但这不是保证。

  2. 在 db-fiddle 中,MySQL(和使用的版本)仅用于说明目的。如前所述,我不是从 RDBMS 查询,而是从网格查询,所以我必须根据可用的内容以及网格中可用的方式进行调整。

标签: sql

解决方案


我认为您没有正确定义您的条件。特别是,你对于最后一个条件,你似乎想要最晚的日期。

我会为此使用窗口功能。我认为逻辑是:

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);

是一个 db<>fiddle。


推荐阅读