2012-04-10 30 views
5

Để thiết lập xử lý tài khoản hợp nhất, tôi muốn tìm tài khoản có tập hợp chủ sở hữu chính xác.Làm thế nào tôi có thể tìm thấy các nhóm hồ sơ phù hợp với các nhóm hồ sơ khác (bộ phận quan hệ?)

Tôi nghĩ rằng nó có thể làm việc để xoay các chủ sở hữu với sql động, sau đó sử dụng chức năng xếp hạng, nhưng tôi không muốn theo đuổi cách tiếp cận đó; Tôi không có giới hạn trên về số lượng tên có thể được liên kết với tài khoản đã cho là , vì vậy tôi muốn tránh SQL động.

Dữ liệu của tôi (còn đây là tại 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') 

Tôi muốn tìm hiểu, đối với mỗi MODULE-TÀI KHOẢN, những gì DDA tài khoản thấp nhất là có cùng một chủ sở hữu chính xác liên kết với nó.

Trong dữ liệu mẫu, tôi muốn các kết quả này, cột thứ ba là tài khoản DDA thấp nhất có cùng chủ sở hữu. Các kết quả cần phải có cùng số hàng như Thereâ tái combo mô-đun/tài khoản - một hàng cho mỗi hàng trong "SELECT DISTINCT mô-đun, chiếm TỪ 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 và 16 không phù hợp với bất kỳ DDA tài khoản, do đó, không quan trọng là chúng khớp với nhau, chúng sẽ nhận được NULL cho tài khoản để hợp nhất. EDIT: SVG 17 không phù hợp với bất kỳ thứ gì, mặc dù có một khoản tiền DDA có tất cả các chủ sở hữu của nó trong SVG 17, sự kết hợp của chủ sở hữu trong SVG 17 không xảy ra đối với bất kỳ khoản phí DDA nào. Mỗi tài khoản DDA sẽ tự khớp, trừ khi tài khoản d2 dda có cùng chủ sở hữu và DDA thấp hơn tồn tại (như trường hợp của DDA 222).

Tôi có thể thấy rằng một cách tiếp cận chung là xoay quanh từng tài khoản, nhóm bảng được xoay vòng và sử dụng row_number. Với số lượng không giới hạn của chủ sở hữu được liên kết với mỗi tài khoản, tôi nghĩ việc xoay vòng sẽ mất SQL động mà tôi muốn tránh.

Dường như với tôi rằng đây là vấn đề "chia rẽ quan hệ", với bộ phận quan hệ có thể bị "cho mượn" bởi một ứng dụng CROSS. Tôi đã thử sử dụng chức năng để có một bảng chủ tài khoản được liên kết với tài khoản cụ thể và tìm tài khoản dda thấp nhất, dọc theo các dòng được hiển thị bên dưới, ý tưởng là xem tất cả số người trong một số nhất định tài khoản giống với số người khi tài khoản đó được tham gia vào tài khoản dda đã cho, nhưng tôi không thể tìm ra cách "cấp" các bảng số vào tài khoản.

-- 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; 
+0

Lưu ý rằng "Chase, Billie" trong dòng 606 DDA không đi đôi với resultset bạn nói rằng bạn muốn trở lại ; Tôi nghĩ bạn muốn điều này là "Chase, Billy", phải không? – mwigdahl

+0

Vâng, đó là chính xác, xin lỗi về điều đó và cảm ơn bạn, tôi sẽ chỉnh sửa lại ngay –

Trả lời

1

Điều này thực sự trở nên khá đơn giản, nếu tôi hiểu chính xác. Hãy thử điều này:

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 

CHỈNH SỬA: Các bước trên không hoạt động sau khi làm rõ, nhưng điều này cần. Nó thực sự là một loại phân chia quan hệ. Có lẽ không phải là kế hoạch truy vấn hiệu quả nhất trên thế giới, nhưng nó hoạt động.

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 
+0

+1; đây là điều đầu tiên xuất hiện trong đầu tôi khi tôi nhìn vào điều này. – lyrisey

+0

Nhưng ở đây bạn bảo toàn tất cả các hàng có bất kỳ kết hợp nào ở phía bên 'b' (DDA), phải không? Ví dụ: nếu tôi thêm "Welch Raquel" vào mọi tài khoản không phải DDA, kết quả cho các khoản tiền không phải là dda sẽ không thay đổi nhưng không có bất kỳ kết quả nào phù hợp, vì không có tài khoản không phải DDA nào có Raquel Welch. Tôi đã có hai lỗi chính tả trong "Walker Wilkie" trong dữ liệu mẫu của tôi đã khiến truy vấn này đưa ra kết quả tương tự như ví dụ của tôi và tôi không có bất kỳ ví dụ nào trong dữ liệu tài khoản của mình với người "phụ" không khớp. Tôi đã cập nhật sql fiddle và tôi cũng sẽ cập nhật các ví dụ ở trên. –

+0

Cảm ơn bạn đã làm rõ. Tôi đang nhìn vào nó một lần nữa. – mwigdahl

1

Tôi tin rằng đây là những gì bạn đang tìm kiếm (http://www.sqlfiddle.com/#!3/f96c5/1):

;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 
+0

Điều này trông giống như một người chiến thắng, nó nhận được trong khi tôi phải bắt đầu một số bản sao lưu và về nhà, tôi sẽ xem xét nó tối nay nhưng tôi thấy nó được kết quả chính xác trên dữ liệu thử nghiệm của tôi. Tôi không quen với FOR XML, vì vậy tôi sẽ tìm ra cách nó hoạt động trước khi chấp nhận. –

+0

@LevinMagruder Về cơ bản, nó tạo XML không có đánh dấu thực tế và được sử dụng để tạo danh sách được phân cách bằng dấu phẩy. Hãy cho tôi biết nếu bạn có bất kỳ câu hỏi. –

Các vấn đề liên quan