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