【问题标题】:My query is returning duplicates我的查询返回重复项
【发布时间】:2015-08-04 21:35:45
【问题描述】:

我编写了一个 SQL 查询来过滤多个条件,并使用 distinct 来仅查找唯一记录。

具体来说,我只需要AccountID 字段是唯一的,每个AccountID 有多个AddressClientIDs

查询有效,但产生了一些重复。

进一步的警告是:

  1. 每个AccountID有多个trans
  2. YN 都可以有跨记录,AccountID

我只想返回AccountIDs,它具有指定状态以外的状态,因此我不使用,因为我不想要这两种状态。

我只想找到 AccountID 列的唯一值。

如果有人可以帮助完善下面的查询,将不胜感激。

SELECT AFS_Account.AddressClientID
    ,afs_transunit.AccountID
    ,SUM(afs_transunit.Units)
FROM AFS_TransUnit
    ,AFS_Account
WHERE afs_transunit.AccountID IN (
        -- Gets accounts which only have non post statuses
        SELECT DISTINCT accountid
        FROM afs_trans
        WHERE accountid NOT IN (
                SELECT accountid
                FROM afs_trans
                WHERE STATUS IN (
                        'POSTPEND'
                        ,'POSTWAIT'
                        )
                )
            -- This gets the unique accountIDs which only have transactions with Y status,
            -- and removes any which have both Y and N.
            AND AccountID IN (
                SELECT DISTINCT accountid
                FROM afs_trans
                WHERE IsAllocated = 'Y'
                    AND accountid NOT IN (
                        SELECT DISTINCT AccountID
                        FROM afs_trans
                        WHERE IsAllocated = 'N'
                        )
                )
        )
    AND AFS_TransUnit.AccountID = AFS_Account.AccountID
GROUP BY afs_transunit.AccountID
    ,AFS_Account.AddressClientID
HAVING SUM(afs_transunit.Units) > 100

谢谢。

【问题讨论】:

  • 设置 sqlfiddle 将有助于调试您的问题。 sqlfiddle.com
  • 另外:您使用的是哪个 DBMS?后格雷斯?甲骨文?
  • 此连接上的两个表之间是否是一对一关系:AFS_TransUnit.AccountID = AFS_Account.AccountID
  • @jpw 不用担心!我猜这两个表之间存在一对多的关系。所以,我只是想与 OP 确认这是不是真的。
  • @a_horse_with_no_name - 我正在使用 MS SQL Server。

标签: sql sql-server database duplicates


【解决方案1】:

由于您确认在 AccountID 列上的两个表之间存在一对多关系,因此您可以使用 AccountIDMax 值来获取不同的值:

SELECT afa.AddressClientID
    ,MAX(aft.AccountID)
    ,SUM(aft.Units)
FROM AFS_TransUnit aft
INNER JOIN AFS_Account afa ON aft.AccountID = afa.AccountID
GROUP BY afa.AddressClientID
HAVING SUM(aft.Units) > 100
    AND MAX(aft.AccountID) IN (
        -- Gets accounts which only have non post statuses
        -- This gets the unique accountIDs which only have transactions with Y status,
         -- and removes any which have both Y and N.
        SELECT DISTINCT accountid
        FROM afs_trans a
        WHERE [STATUS] NOT IN ('POSTPEND','POSTWAIT')
            AND a.accountid IN (
                SELECT t.accountid
                FROM (
                    SELECT accountid
                        ,max(isallocated) AS maxvalue
                        ,min(isallocated) AS minvalue
                    FROM afs_trans
                    GROUP BY accountid
                    ) t
                WHERE t.maxvalue = 'Y'
                    AND t.minvalue = 'Y'
                )
        )

【讨论】:

  • @SolilquyOfChaos 我相信您可能想要调整一些您的非查询。我会尽快发布我的建议。
【解决方案2】:
SELECT AFS_Account.AddressClientID
    ,afs_transunit.AccountID
    ,SUM(afs_transunit.Units)
FROM AFS_TransUnit
INNER JOIN AFS_Account ON AFS_TransUnit.AccountID = AFS_Account.AccountID
INNER JOIN afs_trans ON afs_trans.acccountid = afs_transunit.accountid
WHERE afs_trans.STATUS NOT IN ('POSTPEND','POSTWAIT')
    -- AND afs_trans.isallocated = 'Y'
GROUP BY afs_transunit.AccountID
    ,AFS_Account.AddressClientID
HAVING SUM(afs_transunit.Units) > 100
and max(afs_trans.isallocated) = 'Y' 
and min(afs_trans.isallocated) = 'Y'

使用 ANSI SQL 连接语法修改了您的查询。当您加入表格时,您只需要指定条件而不使用您拥有的子查询。

【讨论】:

  • 此查询在功能上与原始查询不同,不会返回相同的结果。
  • 谢谢,但是我只需要返回只有 IsAllocated 设置为 Y 的 AccountID 的结果。一个 AccountID 可以有多个交易,它们可以是 Y 和 N。
  • 所以如果一个 accountid 有一个“Y”和“N”,它不应该出现在你的结果中。对吗?
  • @vkp 没错。例如,trans 表中的 AccountID 可能有 10 条记录,9 条可能是 Y,但 1 条作为 N。我不想要这些 AccountID。
  • 修改为包含having 子句中的条件。看看它是否有效。