SQL-计算记录和提取最小日期

时间:2018-12-05 23:02:58

标签: sql

我有两个工作表。一个用于合同(CNT),并具有ID#,管理员,到期日期等所有相关信息。另一个用于修订(AMD),具有类似的信息,但显然仅涉及合同修订。它们看起来像这样:

CNTRCT_ID | CNTRCT_ADMIN | CNTRCT_START_DT | .....
12345       J. Bloggs      01-01-2018        .....
54321       A. Nonymous    02-01-2018        .....
12121       B. Atman       03-01-2018        .....

REF_ID    | AMEND_ID     | AMEND_DT        | .....
12345       A00123         06-06-2018        .....
12345       A00265         09-09-2018        .....
54321       A02451         05-04-2018        .....

我想要做的是将两个表连接在一起(CNT.Contract_ID = AMD.Ref_Id是键),这很好,但是我遇到的问题是计数和最小日期。加入后,您会得到一个输出,合同信息将重复(对于Amd 1、2等),因为每个修订都有唯一的Amendment_ID(不是与合同ID关联的Ref_ID)。这样我们得到:

CNTRCT_ID | CNTRCT_ADMIN | CNTRCT_START_DT | REF_ID    | AMEND_ID     | AMEND_DT |
12345       J. Bloggs      01-01-2018        12345       A00123         06-06-2018
12345       J. Bloggs      01-01-2018        12345       A00265         09-09-2018
54321       A. Nonymous    02-01-2018        54321       A02451         05-04-2018

合同12121的条目被删除,因为不存在AMD.REF_ID ='12121'。

基本上,我想提取合同信息,然后将其与修订信息联系起来(如果适用),但a)计算每个合同的修订数量(注意:仅在此处获取最大修订数量是行不通的,因为有些修订有一个或多个为此必须计算的第0次修订)。我正在尝试的是该样式的输出:

CNTRCT_ID | AMD_COUNT | FIRST_AMD_DT
12345       2           06-06-2018
54321       1           05-04-2018
12121       0           N/A

我会写

COUNT(*) over (partition by CNT.CNTRCT_ID) AS AMD_COUNT 

,这将汇总所有合同条目并在新列中输出计数,我可以将它与Select子句中的DISTINCT(CNT.CNTRCT_ID)结合使用,这样可以删除重复项,但我还需要最早的修订日期在那里,我很难把它扔进去而又不会丢掉任何东西。如果我使用

select min(AMEND_DT) from dbo.AMENDMENTS AMD1 where AMD1.REF_ID = AMD.REF_ID

我似乎失去了修正案。如果我删除了“最小日期”字段和子句,我知道的一个合同有11个修正输出11,但只有2个。我正在寻找对上述输出具有准确结果的任何帮助。

这是我所拥有的骨骼。我确定我显然缺少一些东西,但是任何帮助将不胜感激。

SELECT   DISTINCT(CNT.CNTRCT_ID), CNT.CNTRCT_TYP_CD (& various CNT fields), AMD.AMEND_DT,
         COUNT(*) over (partition by CNT.CNTRCT_ID) AS AMD_COUNT
FROM     dbo.AMENDMENTS AMD, 
         dbo.CONTRACTS CNT 
WHERE    CNT.CNTRCT_ID=AMD.REF_ID 
AND      AMD.AMEND_DT = (select min(AMEND_DT) from dbo.AMENDMENTS AMD1 where AMD1.REF_ID=AMD.REF_ID)

2 个答案:

答案 0 :(得分:0)

由于您已经使用了窗口功能,因此我建议您在最短日期之前执行相同的操作:

SELECT /* DISTINCT */
    CNT.CNTRCT_ID
  , CNT.CNTRCT_TYP_CD
  , COUNT( * ) OVER (PARTITION BY CNT.CNTRCT_ID)      AS AMD_COUNT
  , AMD.AMEND_DT
  , MIN( AMEND_DT ) OVER (PARTITION BY CNT.CNTRCT_ID) AS AMD_DT_MIN
FROM dbo.AMENDMENTS AMD
INNER JOIN dbo.CONTRACTS CNT ON CNT.CNTRCT_ID = AMD.REF_ID

我真的不知道您是否需要select distinct,但请注意,distinct是select的限定词,即select有2个选项:select allselect distinct但{ {1}}是默认设置,通常只是省略。

我建议您使用“显式联接”。在25年前,ANSI标准对该语法进行了形式化。

要在加入之前删除all组修正数据:

distinct

答案 1 :(得分:0)

也许这对您有用:

 WITH CTE AS (SELECT MIN(AMEND_DT) AS FIRST_AMD_DT,  COUNT(*) AS AMD_COUNT, REF_ID FROM AMENDMENTS GROUP BY REF_ID)
 SELECT CNTRCT_ID, COALESCE(AMD_COUNT,0) AS AMD_COUNT, FIRST_AMD_DT AS  FIRST_AMD_DT FROM CONTRACTS LEFT JOIN CTE ON CNTRCT_ID = REF_ID

希望有帮助。