0

我正在尝试确定 SQL Server 中产品的第一个条目。该表是 JDE 更新的日志,添加时的记录状态为 A。

我们的产品被分组,我们对不同批次的相同产品有许多代码。无论批次如何,产品代码的前 19 个字符都是相同的。

样本数据:

样本数据

只有粗体行是我要返回的记录,因为这是该 First19 代码的第一个条目。

这是我放在一起的 SQL(请原谅日期的混乱,这是我必须做的,以使其成为 JDE 如何存储日期的真实日期):

SELECT      DATEADD(DAY,CONVERT(INT,RIGHT(F4101Z1.SZUPMJ,3))-1,DATEADD(YEAR,CONVERT(INT,LEFT(F4101Z1.SZUPMJ,3)),'01/01/1900')) Modified_Date,
        F4101Z1.SZTNAC Record_Status,
        F4101Z1.SZLITM,
        LEFT(F4101Z1.SZLITM,19) First19
  FROM  ODS.PRODDTA.F4101Z1 F4101Z1
  LEFT OUTER JOIN (
            SELECT LEFT(SZLITM,19) First19
            FROM ODS.PRODDTA.F4101Z1
            WHERE DATEADD(DAY,CONVERT(INT,RIGHT(SZUPMJ,3))-1,DATEADD(YEAR,CONVERT(INT,LEFT(SZUPMJ,3)),'01/01/1900')) = '11/12/2020'
          ) F4101Z1_2 ON LEFT(F4101Z1.SZLITM,19) = First19
  WHERE F4101Z1_2.First19 IS NULL
  AND   F4101Z1.SZTNAC = 'A'

代码返回所有 3 个结果,这不是我所期望的,我只期望粗体条目。

我实际上想在那里设置一个日期标准,这样我就可以将它纳入我为前一天运行的报告中。基本上是为了展示已经创建的任何新产品,它们是真正的新产品,现在是新批次。

4

4 回答 4

2

认为你可以使用row_number();

select f.*
from (select f.*,
             row_number() over (partition by first19 order by modified_date asc, SZLITM asc) as seqnum
      from ODS.PRODDTA.F4101Z1 f
     ) f
where seqnum = 1;

如果modified_date真的是一个字符串而不是日期——那么你应该修复数据模型。但如果需要,您可以将其转换为日期:

             row_number() over (partition by first19 order by convert(date, modified_date, 103) asc, SZLITM asc) as seqnum
于 2020-11-06T01:39:59.177 回答
1

我可能不了解您的需求,我的第一个想法是做这样的事情:

DECLARE @Data table (
    SZUPMJ varchar(6), SZTNAC varchar(1), SZLITM varchar(50)
);

INSERT INTO @Data ( SZUPMJ, SZTNAC, SZLITM ) VALUES
    ( '120286', 'A', '280080010460160100150' ),
    ( '120286', 'A', '280080010460160100151' ),
    ( '120287', 'A', '280080010460160100150' );

SELECT
    DATEADD( DAY, CONVERT( INT, RIGHT( F4101Z1.SZUPMJ, 3 ) ) -1, DATEADD( YEAR, CONVERT( INT, LEFT( F4101Z1.SZUPMJ, 3 ) ), '01/01/1900' ) ) Modified_Date,
    F4101Z1.SZTNAC AS Record_Status,
    MIN( F4101Z1.SZLITM ) AS Initial_Batch,
    LEFT( F4101Z1.SZLITM, 19 ) AS First19
FROM @Data F4101Z1
LEFT OUTER JOIN (

    SELECT
        LEFT( SZLITM, 19 ) First19
    FROM @Data d
    WHERE 
        DATEADD( DAY, CONVERT( INT, RIGHT( SZUPMJ, 3 ) ) -1, DATEADD( YEAR, CONVERT( INT, LEFT( SZUPMJ, 3 ) ), '01/01/1900' ) ) = '11/12/2020'

) F4101Z1_2 
    ON LEFT( F4101Z1.SZLITM, 19 ) = First19
WHERE
    F4101Z1_2.First19 IS NULL
    AND F4101Z1.SZTNAC = 'A'
GROUP BY
    F4101Z1.SZUPMJ, F4101Z1.SZTNAC, LEFT( F4101Z1.SZLITM, 19 )
ORDER BY
    First19;

退货

+-------------------------+---------------+-----------------------+---------------------+
|      Modified_Date      | Record_Status |     Initial_Batch     |       First19       |
+-------------------------+---------------+-----------------------+---------------------+
| 2020-10-12 00:00:00.000 | A             | 280080010460160100150 | 2800800104601601001 |
| 2020-10-13 00:00:00.000 | A             | 280080010460160100150 | 2800800104601601001 |
+-------------------------+---------------+-----------------------+---------------------+

我只需SZLITM为指定值选择 MINFirst19值。我已按修改日期分组以显示每天的结果,但您可以轻松地更改它以返回一行。我不确定你LEFT OUTER JOIN在做什么,但我保持原样。

于 2020-11-06T00:21:20.927 回答
0

也许您可以在 First19 列上区分,如果有必要按修改日期排序?

于 2020-11-06T00:13:21.560 回答
0

感谢@Critical Error 和@SMor。我现在已经开始工作了。这是代码:

SELECT  DATEADD( DAY, CONVERT( INT, RIGHT( F4101Z1.SZUPMJ, 3 ) ) -1, DATEADD( YEAR, CONVERT( INT, LEFT( F4101Z1.SZUPMJ, 3 ) ), '01/01/1900' ) ) Modified_Date,
        F4101Z1.SZTNAC AS Record_Status,
        MIN( F4101Z1.SZLITM ) AS Initial_Batch,
        LEFT( F4101Z1.SZLITM, 19 ) AS First19
FROM    ODS.PRODDTA.F4101Z1 F4101Z1
WHERE   F4101Z1.SZTNAC = 'A'
AND     DATEADD( DAY, CONVERT( INT, RIGHT( F4101Z1.SZUPMJ, 3 ) ) -1, DATEADD( YEAR, CONVERT( INT, LEFT( F4101Z1.SZUPMJ, 3 ) ), '01/01/1900' ) ) = '10/13/2020'
AND     (
        SELECT  count (LEFT(F4101Z1_2.SZLITM, 19 ))
        FROM    ODS.PRODDTA.F4101Z1 F4101Z1_2
        WHERE   F4101Z1_2.SZUPMJ < F4101Z1.SZUPMJ
        AND LEFT(F4101Z1_2.SZLITM, 19 ) = LEFT(F4101Z1.SZLITM, 19 )
        ) = 0
GROUP BY
        F4101Z1.SZUPMJ,
        F4101Z1.SZTNAC,
        LEFT( F4101Z1.SZLITM, 19 )
ORDER BY
        First19;

这个小宝石正在解决它是否以前存在并且如果记录数高于 0 则不会显示它:

AND     (
        SELECT  count (LEFT(F4101Z1_2.SZLITM, 19 ))
        FROM    ODS.PRODDTA.F4101Z1 F4101Z1_2
        WHERE   F4101Z1_2.SZUPMJ < F4101Z1.SZUPMJ
        AND LEFT(F4101Z1_2.SZLITM, 19 ) = LEFT(F4101Z1.SZLITM, 19 )
        ) = 0

你的评论帮助我解决了这个问题并摆脱了那个讨厌的左外连接

于 2020-11-06T00:48:41.363 回答