2016-09-21 46 views
0
A27,346467413,68723601 
A28,346467414,68723601 
A28,346467416,68723601 
A27,349454768,8908697809 
A28,349454769,8908697809 
A28,349454771,8908697809 

我從上面的示例表中我需要做一些令人難以置信的SQL上。基本上,我問到的是,對於每個A27,兩個程序A28屬於A27,並且需要將信息連接在一起。然而,我被要求爲每個A_Number創建一個表,所以A27將在它自己的表中,A28將在它自己的表中。我需要做的是在他們身上做一個Join,這樣每個A27都可以鏈接到它後面相應的A28。只是想知道如果它在單獨的表格中以及Join和SQL的外觀如何,我會怎麼做?請記住,非數據與其發票調節有關。引用完整性和複雜的連接

enter image description here

我已經上傳樣本文件附

enter image description here

+0

有點混亂請張貼預期輸出並提及列名稱。 – Susang

+0

從描述中可以看出,表格數據中除了鄰近關係之外,沒有任何關聯父母(A27)和子女(A28)。在Oracle中,數據檢索是非確定性的 - 數據檢索的順序將會更改,除非您指定順序。您沒有可用於訂購的鑰匙,因此會成爲問題。也許SQL Server是不同的。 –

+0

假設你*可以*可靠地將父母連接到孩子,那麼你需要爲每個父母分配一個ID並在孩子身上引用它。將數據插入到兩個表中,並且加入是微不足道的 –

回答

1
;WITH cte AS (
    SELECT 
     * 
     ,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber 
    FROM 
     @Table 
) 

SELECT 
    * 
    ,DENSE_RANK() OVER (ORDER BY A27.Column2) as GroupingId 
FROM 
    cte A27 
    LEFT JOIN cte A28 
    ON A28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2) 
    AND A28.Column1 = 'A28' 
WHERE 
    A27.Column1 = 'A27' 

因爲根據您的圖像Column3不是唯一的只有你想要的行號我沒有去使用它的路線。相反,我使用了基於Column2ROW_NUMBER,這似乎是一個增量主鍵,然後是LEFT SELF JOIN。這是針對每個A27行的2個A28行AFTER。如果你想「preceding」喜歡你的OP說,但當時並沒有建議通過簡單地改變JOIN條件扭轉這種局面:

ON A28.RowNumber IN (a27.RowNumber - 1, a27.RowNumber - 2) 

注意我添加了GroupingID給你的方式識別其中A27和A28的是它們可以一起用作A27表中的新主鍵和A28表中的外鍵以保持關係。

這是我使用的測試數據。

DECLARE @Table AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT) 
INSERT INTO @Table VALUES 
('A27',346467408,68723601) 
,('A28',346467409,68723601) 
,('A28',346467411,68723601) 
,('A27',346467413,68723601) 
,('A28',346467414,68723601) 
,('A28',346467416,68723601) 
,('A27',349454768,8908697809) 
,('A28',349454769,8908697809) 
,('A28',349454771,8908697809) 

編輯:根據您如何做時,在單獨的表評論。您可以使用UNION ALL組合表格:

DECLARE @A27 AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT) 
DECLARE @A28 AS TABLE (Column1 CHAR(3), Column2 BIGINT, Column3 BIGINT) 
INSERT INTO @A27 VALUES 
('A27',346467408,68723601) 
,('A27',346467413,68723601) 
,('A27',349454768,8908697809) 
INSERT INTO @A28 VALUES 
('A28',346467409,68723601) 
,('A28',346467411,68723601) 
,('A28',346467414,68723601) 
,('A28',346467416,68723601) 
,('A28',349454769,8908697809) 
,('A28',349454771,8908697809) 

;WITH cteUnion AS (
    SELECT 
     Column1, Column2, Column3 
    FROM 
     @A27 

    UNION ALL 

    SELECT 
     Column1, Column2, Column3 
    FROM 
     @A28 
) 

, cteRowNum AS (
    SELECT * ,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber 
    FROM 
     cteUnion 
) 

SELECT *, DENSE_RANK() OVER (ORDER BY a27.Column2) as GroupingId 
FROM 
    cteRowNum a27 
    LEFT JOIN cteRowNum a28 
    ON a28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2) 
    AND a28.Column1 = 'A28' 
WHERE 
    a27.Column1 = 'A27' 

如果表是較大的或者表現可能是你可能想建立一個臨時表,這樣做的一個問題。

IF OBJECT_ID('tempdb..#Combined') IS NOT NULL 
    BEGIN 
     DROP TABLE #Combined 
    END 

CREATE TABLE #Combined (
    TableName CHAR(3) 
    ,Column2 BIGINT 
) 

INSERT INTO #Combined (TableName, Column2) 
SELECT Column1, Column2 
FROM 
    @A27 

INSERT INTO #Combined (TableName, Column2) 
SELECT Column1, Column2 
FROM 
    @A28 

;WITH cteRowNum AS (
    SELECT * ,ROW_NUMBER() OVER (ORDER BY Column2) AS RowNumber 
    FROM 
     #Combined 
) 

SELECT *, DENSE_RANK() OVER (ORDER BY a27.Column2) as GroupingId 
FROM 
    cteRowNum a27 
    LEFT JOIN cteRowNum a28 
    ON a28.RowNumber IN (a27.RowNumber + 1, a27.RowNumber + 2) 
    AND a28.TableName = 'A28' 
WHERE 
    a27.TableName = 'A27' 
+0

謝謝馬特,這確實幫助很多,我試圖複製你已經做了,但A28和A27的價值分別在他們自己的表中,所以我似乎無法得到正確的結果時,你有兩個查詢兩個表。你會怎麼做呢? – abs786123

+0

@ abs786123您可以使用union all併合並表或臨時表。我已經更新了答案。如果答案滿足您的需求,請將其標記爲已接受,以便其他人知道您有解決方案並授予聲望點。謝謝 – Matt

+0

再次感謝Matt,如果表a27和a28中的列在請求顯示的列中有不同的數據類型。任何方式作爲上述兩個將取決於數據類型是相同的結果集? – abs786123

1

最佳猜測給出缺少格式化輸出...

  • 我用了一個CTE(公共表表達式)對於數據集,並且爲每個集合生成行號。
  • 我用左連接,因爲我不知道是否總會有3行。
  • 我認爲col3是每個組/分區的唯一標識符。
  • 我認爲col2值對於A27總是最低的。
  • 我使用ROW_NUMBER與數的行的每個分區

WITH dataset as (
SELECT 'A27' as Col1,346467413 as col2,68723601 as col3 UNION ALL 
SELECT 'A28' as Col1,346467414 as col2,68723601 as col3 UNION ALL 
SELECT 'A28' as Col1,346467416 as col2,68723601 as col3 UNION ALL 
SELECT 'A27' as Col1,349454768 as col2,8908697809 as col3 UNION ALL 
SELECT 'A28' as Col1,349454769 as col2,8908697809 as col3 UNION ALL 
SELECT 'A28' as Col1,349454771 as col2,8908697809 as col3), 

CTE AS 
(SELECT col1, col2, col3, row_number() over (partition by col3 order by col2) rn 
FROM dataset) 

SELECT A.Col1, A.Col3, A.Col2, B.Col2 as, C.Col2 
FROM cte A 
LEFT JOIN cte B 
on A.Col3 = B.Col3 and A.Rn= 1 and b.rn = 2 
LEFT JOIn cte C 
on A.Col3 = C.Col3 and A.RN =1 and c.RN = 3 

這將導致在一個平坦的輸出根據需要,可以接着被放置到單獨的表。