【问题标题】:Find how many ticket removed, added and existing with SQL query使用 SQL 查询查找删除、添加和存在的票证数量
【发布时间】:2020-12-17 06:51:07
【问题描述】:

我有不同产品的类似案例编号的表格。因此,我想根据日期查找已添加、删除和存在的案例编号。我有一个类似下面的数据

Date        CapVersion CaseNumber 
----------------------------------
2020-12-02  CAP A      1002 
2020-12-02  CAP A      1003 
2020-12-02  CAP A      1004 
2020-12-11  CAP B      1002 
2020-12-11  CAP B      1003 
2020-12-14  CAP C      1003
2020-12-14  CAP C      1004 
2020-12-14  CAP C      1005 
2020-12-15  CAP D      1005 
2020-12-15  CAP D      1007

我想要的输出

Date    CapVersion  CaseNumberAdded CaseNumberRemoved   CaseNumberExisting
--------------------------------------------------------------------------
2020-12-02  CAP A   0               0                   3
2020-12-11  CAP B   0               1                   2
2020-12-14  CAP C   2               1                   1
2020-12-14  CAP D   1               2                   1

我现在得到的输出:

Date    CapVersion  CaseNumberAdded CaseNumberRemoved   CaseNumberExisting
--------------------------------------------------------------------------
2020-12-02  CAP A   0               0                   3
2020-12-11  CAP B   0               1                   2
2020-12-14  CAP C   1               1                   2
2020-12-15  CAP D   2               3                   0

所以代码应该将 2020-12-02 的数据与 2020-12-11 的数据进行比较 然后需要将 2020-12-11 的数据与 2020-12-14 的数据进行比较 但是我当前的代码正在做的是将 2020-12-02 的数据与 2020-12-11 的数据进行比较,然后再次将 2020-12-02 与 2020-12-14 进行比较。

我将在下面提供一个小提琴和一个代码。

打开小提琴链接,您将获得对我的代码的完全访问权限 https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=426aaaf1b851462d975909e56a08d4be

--this is the my error code
WITH BaseDate AS 
(
     SELECT MIN(DataTable.Date) BaseDate
     FROM DataTable 
),
Dates AS 
(
     SELECT DISTINCT DataTable.Date, DataTable.CapVersion
     FROM DataTable 
),
BaseData AS 
(
     SELECT Dates.Date, DataTable.CapVersion, DataTable.CaseNumber
     FROM DataTable
     CROSS JOIN Dates
     JOIN BaseDate ON DataTable.Date = BaseDate.BaseDate 
),
Detailed AS 
(
     SELECT 
         COALESCE(DataTable.Date, BaseData.Date) Date, 
         COALESCE(DataTable.CaseNumber, BaseData.CaseNumber) CaseNumber,
         CASE 
            WHEN DataTable.CaseNumber IS NOT NULL AND BaseData.CaseNumber IS NULL
               THEN 1
               ELSE 0 
         END CaseNumberAdded,
         CASE 
            WHEN DataTable.CaseNumber IS NULL AND BaseData.CaseNumber IS NOT NULL
               THEN 1
               ELSE 0 
         END CaseNumberRemoved,
         CASE 
            WHEN DataTable.CaseNumber IS NOT NULL AND BaseData.CaseNumber IS NOT NULL
               THEN 1
               ELSE 0 
         END CaseNumberExisting
     FROM 
         BaseData
     FULL JOIN 
         DataTable ON DataTable.CaseNumber = BaseData.CaseNumber
                   AND DataTable.Date = BaseData.Date 
)
SELECT 
    Detailed.Date,
    Dates.CapVersion,
    SUM(Detailed.CaseNumberAdded) CaseNumberAdded,
    SUM(Detailed.CaseNumberRemoved) CaseNumberRemoved,
    SUM(Detailed.CaseNumberExisiting) CaseNumberExisting
FROM 
    Detailed
JOIN 
    Dates ON Detailed.Date = Dates.Date
GROUP BY Detailed.Date, Dates.CapVersion;

【问题讨论】:

  • CapVersion 是某种与日期相对应的自动递增 id 吗?含义...该列是否真的影响分组逻辑?
  • @ChadBaldwin 是与日期对应的自动递增 id
  • 亲爱的@ChadBaldwin,您可能会根据我的期望输出提出全新的解决方案,这对我很有帮助
  • 我认为对于2020-12-02,所有三个条目都应该被视为已添加,因为在此日期之前不存在任何内容,因此该日期的所有条目都是新的,对吗?
  • @GiorgosBetsos 不,如果您提供基于我将为我提供帮助的解决方案,我希望将最早的数据作为现有数据

标签: sql sql-server ssms


【解决方案1】:

我认为应该这样做:

;WITH DataTableBase AS 
(
    SELECT Date, CapVersion, ROW_NUMBER() OVER (ORDER BY Date) AS seq
    FROM DataTable
    GROUP BY Date, CapVersion
), DataTableSections AS 
( 
    SELECT Date, CapVersion, CaseNumber, DENSE_RANK() OVER (ORDER BY Date) AS seq   
    FROM DataTable  
), DataTableCombined AS
(
    SELECT dt1.seq, dt2.seq AS seqBefore
       , dt1.CaseNumber, dt2.CaseNumber AS CaseNumberBefore
       , dt1.Date, dt1.CapVersion, dt2.Date AS DateBefore
       , dt2.CapVersion AS CapVersionBefore
    FROM DataTableSections AS dt1
    FULL OUTER JOIN DataTableSections AS dt2 
       ON dt1.seq = dt2.seq + 1 AND dt1.CaseNumber = dt2.CaseNumber
)    
SELECT dt.seq
    , dt.Date
    , dt.CapVersion 
    , COUNT(CASE WHEN dt.seq != 1 AND CaseNumberBefore IS NULL THEN 1 END) AS CaseNumberAdded
    , COUNT(CASE WHEN CaseNumber IS NULL THEN 1 END) AS CaseNumberRemoved
    , COUNT(CASE WHEN (dt.seq = 1) OR (CaseNumber IS NOT NULL AND CaseNumberBefore IS NOT NULL) THEN 1 END) AS CaseNumberExisiting
FROM DataTableBase AS dt
INNER JOIN DataTableCombined AS dtc ON dt.seq = COALESCE(dtc.seq, dtc.seqBefore + 1)
GROUP BY dt.seq, dt.Date, dt.CapVersion

DB Fiddle Demo

猜你喜欢
  • 2011-04-18
  • 2020-09-27
  • 2020-07-15
  • 1970-01-01
  • 2012-09-22
  • 1970-01-01
  • 2014-09-07
  • 2022-12-18
  • 1970-01-01
相关资源
最近更新 更多