Как найти группы записей, соответствующие другим группам записей (реляционное деление?)

Для настройки обработки консолидированных счетов я хочу найти счета, которые имеют «точно такой же» набор владельцев.

Я думаю, что может сработать поворот владельцев с помощью динамического sql, а затем использовать функции ранжирования, но я не хочу следовать этому подходу; Я не имеют верхний предел количества имен, которые могут быть связаны с данной учетной записи, поэтому я хочу избежать динамического SQL.

Мои данные (также находятся вhttp://www.sqlfiddle.com/#!3/1d36e)

 CREATE TABLE allacctRels
 (account INT NOT NULL,
 module CHAR(3) NOT NULL,
 custCode CHAR(20) NOT NULL)


 INSERT INTO allacctrels
 (account, module, custCode)
 VALUES
 (1, 'DDA', 'Wilkie, Walker'),
 (1, 'DDA', 'Houzemeal, Juvy'),
 (2, 'CDS', 'Chase, Billy'),
 (2, 'CDS', 'Norman, Storm'),
 (3, 'CDS', 'Chase, Billy'),
 (3, 'CDS', 'Norman, Storm'),
 (7, 'CDS', 'Perkins, Tony'),
 (15, 'SVG', 'Wilkie, Walker'), --typo in name before mwigdahl's response
 (16, 'SVG', 'Wilkie, Walker'), -- corrected typo here too
 (606, 'DDA', 'Norman, Storm'),
 (606, 'DDA', 'Chase, Billy'),-- corrected 2nd typo found 
 (4, 'LNS', 'Wilkie, Walker'),
 (4, 'LNS', 'Houzemeal, Juvy'),
 (44, 'DDA', 'Perkins, Tony'),
 (222, 'DDA', 'Wilkie, Walker'),
 (222, 'DDA', 'Houzemeal, Juvy'),
 (17, 'SVG', 'Wilkie, Walker'), -- added these three rows in edit, SVG 17 doesn't match any dda 
 (17, 'SVG', 'Welch, Raquel'),
 (17, 'SVG', 'Houzemeal, Juvy')

Я хочу выяснить для каждого МОДУЛЯ-АККАУНТ, какой самый низкий DDA аккаунт, у которого одни и те же владельцы связанные с ним.

В примере данных мне нужны эти результаты, третий столбец самая низкая учетная запись DDA, имеющая тех же владельцев. В результатах должно быть столько же строк, сколько и в комбинациях модуль/учетная запись -по одной строке на каждую строку в «SELECT DISTINCT module, account FROM allAcctRels»)

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, поэтому это не имеет значения они соответствуют друг другу, они получают NULL для учетной записи, к которой нужно консолидироваться. РЕДАКТИРОВАТЬ :SVG 17 ничего не соответствует, даже если есть счет DDA, в котором все держатели включены в SVG 17, комбинация держателей в SVG 17 не происходит ни для одного счета DDA. Каждая учетная запись DDA будет соответствовать самой себе, если только Учетная запись dda с теми же владельцами и более низким DDA существует (, как и в случае DDA 222).

Я вижу, что один общий подход состоит в том, чтобы сводную таблицу и используйте номер строки _. Учитывая неограниченное количество владельцев, связанных с каждой учетной записью, я думаю, что поворот займет динамический 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;

6
задан Levin Magruder 10 April 2012 в 22:07
поделиться