2012-04-06 21 views
5

Cho 2 bảng sau:Làm thế nào để hợp nhất dao động từ các bảng khác nhau

T1 
------------------ 
From | To | Value 
------------------ 
10 | 20 | XXX 
20 | 30 | YYY 
30 | 40 | ZZZ 


T2 
------------------ 
From | To | Value 
------------------ 
10 | 15 | AAA 
15 | 19 | BBB 
19 | 39 | CCC 
39 | 40 | DDD 

cách tốt nhất để có được kết quả dưới đây, sử dụng T-SQL trên SQL Server 2008 là gì?

Các Từ/Để dãy là tuần tự (không có khoảng trống) và tiếp theo Từ luôn có giá trị tương tự như trước Để

Desired result 
------------------------------- 
From | To | Value1 | Value2 
------------------------------- 
10 | 15 | XXX | AAA 
15 | 19 | XXX | BBB 
19 | 20 | XXX | CCC 
20 | 30 | YYY | CCC 
30 | 39 | ZZZ | CCC 
39 | 40 | ZZZ | DDD 

Trả lời

4

Trước tiên, tôi khai báo dữ liệu giống như dữ liệu bạn đã đăng. Vui lòng sửa tôi nếu bất kỳ giả định nào tôi đã đưa ra đều sai. Tốt hơn là đăng bài tuyên bố của riêng bạn trong câu hỏi để chúng tôi làm việc với cùng một dữ liệu.

DECLARE @T1 TABLE (
    [From] INT, 
    [To] INT, 
    [Value] CHAR(3) 
); 

INSERT INTO @T1 (
    [From], 
    [To], 
    [Value] 
) 
VALUES 
    (10, 20, 'XXX'), 
    (20, 30, 'YYY'), 
    (30, 40, 'ZZZ'); 

DECLARE @T2 TABLE (
    [From] INT, 
    [To] INT, 
    [Value] CHAR(3) 
); 

INSERT INTO @T2 (
    [From], 
    [To], 
    [Value] 
) 
VALUES 
    (10, 15, 'AAA'), 
    (15, 19, 'BBB'), 
    (19, 39, 'CCC'), 
    (39, 40, 'DDD'); 

Dưới đây là chọn truy vấn của tôi để tạo ra kết quả mong đợi của bạn:

SELECT 
    CASE 
    WHEN [@T1].[From] > [@T2].[From] 
    THEN [@T1].[From] 
    ELSE [@T2].[From] 
    END AS [From], 
    CASE 
    WHEN [@T1].[To] < [@T2].[To] 
    THEN [@T1].[To] 
    ELSE [@T2].[To] 
    END AS [To], 
    [@T1].[Value], 
    [@T2].[Value] 
FROM @T1 
INNER JOIN @T2 ON 
    (
    [@T1].[From] <= [@T2].[From] AND 
    [@T1].[To] > [@T2].[From] 
) OR 
    (
    [@T2].[From] <= [@T1].[From] AND 
    [@T2].[To] > [@T1].[From] 
); 
+0

Hàng kết quả 5 sai. Đã được khắc phục ngay bây giờ. Cảm ơn. – pvieira

+0

Tôi đã xóa nhận xét của mình về các tập hợp kết quả khác nhau, giờ đây chúng giống nhau. –

0

Các truy vấn dưới đây thấy các dãy nhỏ, sau đó chọn lại các giá trị trong các bảng:

SELECT ranges.from, ranges.to, T1.Value, T2.Value 
FROM (SELECT all_from.from, min(all_to.to) as to 
    FROM (SELECT T1.FROM 
     FROM T1 
     UNION 
     SELECT T2.FROM 
     FROM T2) all_from 
    JOIN (SELECT T1.TO 
     FROM T1 
     UNION 
     SELECT T2.FROM 
     FROM T2) all_to ON all_from.from < all_to.to 
    GROUP BY all_from.from) ranges 
JOIN T1 ON ranges.from >= T1.from AND ranges.to <= T1.to 
JOIN T2 ON ranges.from >= T2.from AND ranges.to <= T2.to 
ORDER BY ranges.from 
+1

Tôi không thể thực hiện việc biên dịch truy vấn này. Bạn đã thiết lập dữ liệu thử nghiệm của mình như thế nào? –

+0

Nó thiếu một GROUP BY, hãy thử lại, nó hoạt động ngay bây giờ. – GavinCattell

+0

Điều này vẫn không biên dịch cho tôi bằng cách sử dụng thiết lập dữ liệu của tôi. Trong một bản sao truy vấn của bạn, tôi đã thay thế tất cả các lần xuất hiện của 'T1' bằng' [@ T1] 'và tất cả các lần xuất hiện của' T2' bằng '[@ T2]' và nhận lỗi cú pháp này khi thực thi: 'Msg 156, Cấp 15 , Tiểu bang 1, Dòng 34 Cú pháp không đúng gần từ khoá 'from'.' –

0

Cảm ơn câu trả lời, nhưng tôi đã kết thúc bằng một CTE, wgich tôi nghĩ là sạch hơn.

DECLARE @T1 TABLE ([From] INT, [To] INT, [Value] CHAR(3)); 
DECLARE @T2 TABLE ([From] INT, [To] INT, [Value] CHAR(3)); 

INSERT INTO @T1 ( [From], [To], [Value]) VALUES (10, 20, 'XXX'), (20, 30, 'YYY'), (30, 40, 'ZZZ'); 
INSERT INTO @T2 ( [From], [To], [Value]) VALUES (10, 15, 'AAA'), (15, 19, 'BBB'), (19, 39, 'CCC'), (39, 40, 'DDD'); 

;with merged1 as 
(
    select 
     t1.[From] as from1, 
     t1.[to] as to1, 
     t1.Value as Value1, 
     t2.[From] as from2, 
     t2.[to] as to2, 
     t2.Value as Value2 
    from @t1 t1 
    inner join @T2 t2 
     on t1.[From] < t2.[To] 
     and t1.[To] >= t2.[From] 

) 
,merged2 as 
(
    select 
      case when from2>=from1 then from2 else from1 end as [From] 
     ,case when to2<=to1 then to2 else to1 end as [To] 
     ,value1 
     ,value2 
    from merged1 
) 
select * from merged2 
3

Trộm cắp thiết lập dữ liệu @ ISME, tôi đã viết như sau:

;With EPs as (
    select [From] as EP from @T1 
    union 
    select [To] from @T1 
    union 
    select [From] from @T2 
    union 
    select [To] from @T2 
), OrderedEndpoints as (
    select EP,ROW_NUMBER() OVER (ORDER BY EP) as rn from EPs 
) 
select 
    oe1.EP, 
    oe2.EP, 
    t1.Value, 
    t2.Value 
from 
    OrderedEndpoints oe1 
     inner join 
    OrderedEndpoints oe2 
     on 
      oe1.rn = oe2.rn - 1 
     inner join 
    @T1 t1 
     on 
      oe1.EP < t1.[To] and 
      oe2.EP > t1.[From] 
     inner join 
    @T2 t2 
     on 
      oe1.EP < t2.[To] and 
      oe2.EP > t2.[From] 

Đó là, bạn tạo một tập chứa tất cả các điểm cuối có thể có của dấu chấm câu (EPs), sau đó bạn "loại" và gán cho mỗi người một số hàng (OrderedEPs).

Sau đó, truy vấn cuối cùng tập hợp từng cặp "liền kề" các hàng lại với nhau và tham gia lại các bảng gốc để tìm các hàng từ mỗi hàng chồng lên nhau trong phạm vi đã chọn.

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