问题描述
我正在尝试确定sql Server中产品的第一个条目。该表是JDE更新的日志,添加后的记录状态为A。
我们的产品归为一组,其中对于同一产品,我们有许多不同批次的代码。无论批次如何,产品代码的前19个字符都相同。
样本数据:
我要返回的记录只有加粗的行,因为那是该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;
您的评论帮助我解决了这个问题,并摆脱了令人讨厌的左外部联接