【问题标题】:SQL Statement to eliminate duplicates based on value in another columnSQL 语句根据另一列中的值消除重复项
【发布时间】:2014-02-28 03:05:19
【问题描述】:

我有两个表中的数据,我有一个查询组合数据,如下所示。我正在尝试根据 Id 列消除重复项,在该列中我选择了具有最早拆分日期的记录。任何人都可以帮助我使用 SQL 语句来实现这一点吗?

|ID     |SecID  |ReportingDate  |SplitDate  |Adjustor|  
|1465   |2      |31-Dec-09      |01-Nov-10  |0.1     |  
|1465   |2      |31-Dec-09      |27-Dec-12  |0.2     |  
|1466   |2      |31-Dec-10      |27-Dec-12  |0.2     |   
|1468   |2      |31-Dec-11      |27-Dec-12  |0.2     |  
|1469   |2      |31-Dec-08      |01-Nov-10  |0.1     |  
|1469   |2      |31-Dec-08      |27-Dec-12  |0.2     | 

结果应该如下:

|ID     |SecId  |ReportingDate  |Adjustor  |  
|1469   |2      |31-Dec-08      |0.1       |  
|1465   |2      |31-Dec-09      |0.1       |  
|1466   |2      |31-Dec-10      |0.2       |  
|1468   |2      |31-Dec-11      |0.2       |  

更多信息:
让我解释一下我想在这里做什么。

在基本面表中,我有一行具有唯一的行 ID、secId(产品标识符)和该行的报告日期。
此信息需要使用 splitdetails 表中的信息进行调整,该表具有适用日期、它影响的 secId(product) 以及要使用的调整器比率。

对于基本面表中的每一行:
- 在拆分表中没有条目的任何 secId 处,调整器应为 1。
- 如果 secId 存在于拆分表中,则要使用的拆分是最旧的拆分,其日期早于所检查的基本面表报告日期。

我希望从上面的示例中得到的结果最终看起来像这样:
| ID |SecId |ReportingDate |调整器 |
|1469 2 08 年 12 月 31 日 0.1
|1465 2 09 年 12 月 31 日 0.1
|1466 2 2010 年 12 月 31 日 0.2
|1468 2 2011 年 12 月 31 日 0.2
|1467 2 2012 年 12 月 31 日 1

我使用的查询是
选择 Gotten.ID、Gotten.SecID、Gotten.ReportingDate、Gotten.SplitDate、调整器
来自
(选择 tblFundamentalsDetails.id、tblFundamentalsDetails.SecId、tblFundamentalsDetails.ReportingDate、tblSplitDetails.SplitDate、tblSplitDetails.Adjustor FROM tblFundamentalsDetails
左连接 tblSplitDetails
开(tblFundamentalsDetails.ReportingDate

【问题讨论】:

  • 两张表有关系吗?我认为删除第一个表中的重复行需要这种关系。
  • @NaserE 对于延迟回复我深表歉意。我不是要删除,而是要过滤掉重复项。

标签: sql ms-access group-by aggregate-functions


【解决方案1】:

用于名为 [Source] 的表(或保存的查询)中的测试数据

ID    SecID  ReportingDate  SplitDate   Adjustor
----  -----  -------------  ----------  --------
1465      2  2009-12-31     2010-11-01       0.1
1465      2  2009-12-31     2012-12-27       0.2
1466      2  2010-12-31     2012-12-27       0.2
1468      2  2011-12-31     2012-12-27       0.2
1469      2  2008-12-31     2010-11-01       0.1
1469      2  2008-12-31     2012-12-27       0.2

以下查询已经过测试,实际上可以在 Access 中工作

SELECT 
    Source.ID,
    Source.SecID,
    Source.ReportingDate,
    Source.Adjustor
FROM
    Source
    INNER JOIN
    (
        SELECT ID, MIN(SplitDate) AS MinOfSplitDate
        FROM Source
        GROUP BY ID
    ) AS MinDate
        ON MinDate.ID = Source.ID
            AND MinDate.MinOfSplitDate = Source.SplitDate

返回

ID    SecID  ReportingDate  Adjustor
----  -----  -------------  --------
1465      2  2009-12-31          0.1
1466      2  2010-12-31          0.2
1468      2  2011-12-31          0.2
1469      2  2008-12-31          0.1

【讨论】:

  • 这按照我的例子工作,非常感谢。每当 splitdate 为空时,这是否可以扩展到为调整器显示 1?
【解决方案2】:

我可以在 MySQL 服务器上执行此操作,如果我理解您,这就是您所需要的:

DELETE t1 FROM mytable t1, mytable t2 WHERE t1.ID = t2.ID 
AND t1.ReportingDate < t2.ReportingDate

这只会保留 mytable 中具有最新日期和相同 ID 的行

请注意,具有相同 ID 的三行将变为一。每个 ID 只能保留一行。

【讨论】:

    【解决方案3】:

    一种方法,在 Access SQL 中应该没问题(尽管您可能需要更改别名):

    SELECT a.*
    FROM Table1 a
    INNER JOIN
    (
    SELECT ID, sdate = min(SplitDate)
    FROM Table1
    GROUP BY ID
    ) b
    ON a.ID = b.ID
    AND a.SplitDate = b.sdate
    

    您也可以采用内部查询并在 Access 中创建自己的 qry。

    【讨论】:

    • Access 不支持列列表中的sdate = min(SplitDate) 语法。
    • 因此别名评论:)
    • @cjb110 这按照我的例子工作,非常感谢。每当 splitdate 为空时,这是否可以扩展到为调整器显示 1?
    • @GordThompson 我尝试了 'sdate = min(SplitDate)' ,没有用,我想我会将它作为别名作为占位符运行,然后我看到了最后一点建议 :-)
    • 一列像:iif(isnull([SplitDate]), 1, [Adjustor]) as [Adjustor] 应该这样做。
    猜你喜欢
    • 2023-01-19
    • 2021-07-03
    • 2018-05-27
    • 2021-12-02
    • 2017-07-28
    • 2018-12-01
    • 2017-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多