确定日志条目是否是产品的第一个条目

问题描述

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

我们的产品归为一组,其中对于同一产品,我们有许多不同批次的代码。无论批次如何,产品代码的前19个字符都相同。

样本数据:

Sample Data

我要返回的记录只有加粗的行,因为那是该First19代码的第一项。

这是我组合在一起的sql(对日期周围的混乱,这是我必须要做的,以使其从JDE存储日期的日期变为真实的日期):

SELECT      DATEADD(DAY,CONVERT(INT,RIGHT(F4101Z1.SZUPMJ,3))-1,DATEADD(YEAR,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,RIGHT(SZUPMJ,LEFT(SZUPMJ,'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个结果,这与我期望的粗体输入项不符。

我实际上想在此处放置一个日期条件,以便可以将其纳入到前一天运行的报告中。基本上显示所有已创建的新产品,无论它们是真正的新产品,还是现在的新批次。

解决方法

认为,您可以使用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
,

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

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

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

SELECT
    DATEADD( DAY,CONVERT( INT,RIGHT( F4101Z1.SZUPMJ,3 ) ) -1,DATEADD( YEAR,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,RIGHT( SZUPMJ,LEFT( SZUPMJ,'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,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值选择First19的MIN值。我已经按照修改后的日期进行了分组,以显示每天的结果,但是您可以轻松地对其进行更改,以返回一行。我不确定您的LEFT OUTER JOIN在做什么,但我还是照原样保留了。

,

也许您可以在“ First19”列上区分,并在必要时按“修改日期”排序?

,

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

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#define SIZE 1024


char text[SIZE];
int main(void){

    gets(text);
    int length,letters=0,sentences=0,words=1; //word and sentence start from 1 as it's the minimum value
    length = strlen(text);
    for (int i = 0; i < length; ++i) {
        if(isalpha(text[i])){
            letters++;
        }
        if(text[i]=='.'|| text[i]=='!'||text[i]=='?') {
            sentences++;
        }
        if(isspace(text[i])) {
            words++;
        }
    }
    float L=(letters*100.0f/words);
    float S=(sentences*100.0f/words);


    double index= (0.0588*L-0.296*S-(15.8));
    index=round(index);
    if(index<0){
        printf("Before grade 1\n");
    } else if (index>16){
        printf("Grade 16+\n");
    }else{
        printf("Grade: %.f\n",index);
    }

    // printf("l: %d\ns: %d\nw: %d\n",letter,sentence,word); this was used to check if counters were correct



}

如果该小宝石先前存在,并且正在运行,并且记录数大于0则不显示,则无法显示该小宝石:

SELECT  DATEADD( DAY,19 ) AS First19
FROM    ODS.PRODDTA.F4101Z1 F4101Z1
WHERE   F4101Z1.SZTNAC = 'A'
AND     DATEADD( DAY,'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,19 )
ORDER BY
        First19;

您的评论帮助我解决了这个问题,并摆脱了令人讨厌的左外部联接