Sql server 如何找到与其他记录组匹配的记录组(关系部门?)

Sql server 如何找到与其他记录组匹配的记录组(关系部门?),sql-server,sql-server-2008,relational-division,Sql Server,Sql Server 2008,Relational Division,对于设置合并账户处理,我想找出 拥有完全相同的所有者 我认为用动态sql来引导所有者,然后使用 排名功能,但我不想追求这种方法;我不 有一个上限,限制有多少个名字可以与一个 给定帐户,因此我希望避免使用动态SQL 我的数据也在这里 我想找出每个模块账户的最低DDA 帐户的所有者完全相同 与之相关的 在示例数据中,我希望得到这些结果,第三列是 拥有相同所有者的最低DDA帐户。结果的行数应与re模块/帐户组合的行数相同-在SELECT DISTINCT module、account FROM ALA

对于设置合并账户处理,我想找出 拥有完全相同的所有者

我认为用动态sql来引导所有者,然后使用 排名功能,但我不想追求这种方法;我不 有一个上限,限制有多少个名字可以与一个 给定帐户,因此我希望避免使用动态SQL

我的数据也在这里

我想找出每个模块账户的最低DDA 帐户的所有者完全相同 与之相关的

在示例数据中,我希望得到这些结果,第三列是 拥有相同所有者的最低DDA帐户。结果的行数应与re模块/帐户组合的行数相同-在SELECT DISTINCT module、account FROM ALACCRELS中,每行一行

1, DDA, 1
2, CDS, 606
3, CDS, 606
15, SVG, NULL
16, SVG, NULL
606, DDA, 606
4, LNS, 1
7, CDS, 44
44, DDA, 44
222, DDA, 1
17, SVG, NULL -- added to original post.
SVG 15和16与任何DDA帐户都不匹配,所以这并不重要 如果它们相互匹配,则要合并到的帐户将为空。编辑:SVG 17不匹配任何内容,即使存在一个在SVG 17中有其所有持有人的DDA账户,但任何一个DDA账户都不会出现SVG 17中持有人的组合。除非 与dda 222的情况一样,存在拥有相同所有者和较低dda的dda账户

我可以看出,一种通用的方法是以每个客户、组为中心 数据透视表,并使用行号。给定无限数量的 与每个账户相关联的持有人,我认为旋转将需要 我宁愿避免使用动态SQL

在我看来,这是一个关系划分问题,与 关系划分可能由交叉应用程序提供。我试过了 编写一个函数,该函数将包含一个与 使用特定帐户,并找到最低的dda帐户 如下图所示,这个想法是为了看看在一个给定的时间内所有的人 帐户与加入该帐户时的人数相同 到给定的dda帐户,但我不知道如何为 函数中的帐号

-- this is what I tried but I'm not sure it the logic would work
-- and I can't figure out how to pass the account holders for each
-- account in.  This is a bit changed from the function I wrote, some
    -- extraneous fields removed and cryptic column names changed.  So it 
    -- probably won't run as is.

    -- to support a parameter type to a tape
-- CREATE type VisionCustomer as Table
-- (customer varchar(30))

CREATE FUNCTION  consolidatable 
(@custList dbo.VisionCustomer READONLY)
RETURNS char(10)
AS  
BEGIN
DECLARE @retval Varchar(10)
DECLARE @howmany int
select @howmany=Count(*) FROM @custlist;

SELECT @retval = min (acct) FROM allAcctRels
    JOIN @custlist
        On VendorCustNo = Customer
            WHERE acctType = 'DDA'
            GROUP BY acct
            HAVING (count(*) = @howmany)
            and
            COUNT(*) = (select Count(*) FROM allAcctRels X
    WHERE X.acctType = 'DDA'
    AND X.account = AllAcctRels.account) ;
RETURN @retval
END;

如果我没弄错的话,这其实很简单。试试这个:

SELECT a.account, a.module, MIN(b.account) 
FROM allacctRels a
    LEFT JOIN allacctRels b ON a.custCode = b.custCode AND b.module = 'DDA'
GROUP BY a.account, a.module
编辑:澄清后,上述内容不起作用,但这应该是正确的。这确实是一种关系划分。可能不是世界上最有效的查询计划,但它可以工作

SELECT a.account, a.module, MIN(b.account)
FROM allacctRels a
    LEFT JOIN allacctRels b ON b.module = 'DDA'
    AND
    -- first test is to confirm that the number of matching names for this combination equals the number of names for the DDA set...
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
            INNER JOIN allacctRels a2 ON b2.custCode = a2.custCode 
        WHERE a.account = a2.account AND b.account = b2.account
    ) = 
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
        WHERE b.account = b2.account
    )
    AND 
    -- second test is to confirm that the number of names for the DDA set equals the number of names for the base set...
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
        WHERE b.account = b2.account
    ) = 
    (
        SELECT COUNT(*) 
        FROM allacctRels a2 
        WHERE a.account = a2.account
    )
GROUP BY a.account, a.module

我相信这就是你想要的:


+1; 这是我第一次想到这一点,但在这里,你保留了所有在“b”DDA端有任何匹配的行,不是吗?例如,如果我将Welch-Raquel添加到每个非DDA账户,非DDA账户的结果不会改变,但不应该有任何匹配项,因为没有非DDA账户有Raquel-Welch。我的示例数据中有两处Walker Wilkie的输入错误,这使得这个查询给出了与我的示例相同的结果,并且我的账户数据中没有任何不匹配的示例。我已经更新了SQLFiddle,也将更新上面的示例。感谢您的澄清。我又看了一遍。更新的答案,应该是您现在正在寻找的。我必须向where子句引入模块,以避免SQLFIDLE.com/中显示的错误!3/cbb1b/1。结果看起来不错,我想我了解了它的工作原理,但现在还不清楚minb.account是如何与a.account关联的,因为左连接只是将所有DDA账户和每条记录放在左侧莱文·马格鲁德6分钟后注意到,606 DDA排的比利不同意你说的你想要回来的结果;我想你希望这是蔡斯,比利,对吧?是的,没错,很抱歉,谢谢你,我现在会重新编辑这看起来是个赢家,它进来了,就在我必须开始一些备份和回家的时候,我今晚会看得更多,但我看到它在我的测试数据上得到了正确的结果。我不熟悉FOR XML,所以在接受之前,我想弄清楚它是如何工作的。@LevinMagruder它基本上是使XML没有实际的标记,用于创建逗号分隔的列表。如果你有任何问题,请告诉我。
SELECT a.account, a.module, MIN(b.account)
FROM allacctRels a
    LEFT JOIN allacctRels b ON b.module = 'DDA'
    AND
    -- first test is to confirm that the number of matching names for this combination equals the number of names for the DDA set...
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
            INNER JOIN allacctRels a2 ON b2.custCode = a2.custCode 
        WHERE a.account = a2.account AND b.account = b2.account
    ) = 
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
        WHERE b.account = b2.account
    )
    AND 
    -- second test is to confirm that the number of names for the DDA set equals the number of names for the base set...
    (
        SELECT COUNT(*) 
        FROM allacctRels b2 
        WHERE b.account = b2.account
    ) = 
    (
        SELECT COUNT(*) 
        FROM allacctRels a2 
        WHERE a.account = a2.account
    )
GROUP BY a.account, a.module
;WITH AccountsWithOwners AS
(
  SELECT DISTINCT
    DA.module
    , DA.account
    , STUFF((SELECT 
                 ',' + AAR.custCode
               FROM allacctRels AAR 
               WHERE AAR.module = DA.module 
                 AND AAR.account = DA.account
               ORDER BY AAR.custCode
               FOR XML PATH(''))
              , 1, 1, '') AS Result
  FROM allacctRels DA
) 
, WithLowestDda AS
(
    SELECT
        AWO.module
        , AWO.account
        , MatchingAccounts.account AS DdaAccount
        , ROW_NUMBER() OVER(PARTITION BY AWO.module, AWO.account ORDER BY MatchingAccounts.account) AS Row
    FROM AccountsWithOwners AWO
    LEFT JOIN AccountsWithOwners MatchingAccounts
        ON MatchingAccounts.module = 'DDA'
        AND MatchingAccounts.Result = AWO.Result
)
SELECT
    account
    , module
    , DdaAccount
FROM WithLowestDda
WHERE Row = 1