2009-03-02 46 views
13

Trong biểu đồ bên dưới có mối quan hệ 1: 1 giữa 'DodgyOldTable' và 'MainTable'. Bảng 'Tùy chọn' chứa các bản ghi với 'OptionVal1', 'OptionVal2' và 'OptionVal3' trong trường 'OptionDesc'. Tôi cần phải chèn một chèn vào MainTable_Option với một lựa chọn từ DodgyOldTable. Một cái gì đó như thế này:Thực hiện INSERT với SELECT để chèn nhiều bản ghi

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN 
    (SELECT OptionID 
    FROM Option 
    WHERE OptionDesc = 'OptionVal1') END 
FROM DodgyOldTable 

Nếu có thể, tôi muốn tránh sử dụng một số câu lệnh chọn khác nhau để thực hiện thao tác chèn.

alt text http://www.freeimagehosting.net/uploads/863f10bf5f.jpg

+0

Có thể đó chỉ là tôi nhưng tôi không thể nhìn thấy ảnh đính kèm. – Learning

+0

@Learning: Proxy công ty của tôi tự động chặn trang web lưu trữ hình ảnh. Có lẽ đó là một cái gì đó như thế này cho bạn là tốt. – Tomalak

Trả lời

27
INSERT 
    MainTable_Option 
    (
    MainTableID, 
    OptionID 
) 
SELECT 
    d.ID, 
    o.OptionId 
FROM 
    DodgyOldTable d 
    INNER JOIN Option o ON 
    (d.OptionVal1 = 'Y' AND o.OptionDesc = 'OptionVal1') OR 
    (d.OptionVal2 = 'Y' AND o.OptionDesc = 'OptionVal2') OR 
    (d.OptionVal3 = 'Y' AND o.OptionDesc = 'OptionVal3') 
+0

Rực rỡ! Tôi biết phải có một cách tốt hơn! –

+0

Rất vui được giúp đỡ. ;-) – Tomalak

0

Tôi muốn nói rằng một kịch bản di chuyển bằng tay sẽ dễ dàng hơn để sử dụng sau đó cố gắng để làm điều đó trong một truy vấn sql duy nhất, nếu đó là một lựa chọn.

1

có lẽ không phải là giải pháp hiệu quả nhất nhưng bằng cách sử dụng một liên minh, điều này sẽ hoạt động.

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1') 
FROM DodgyOldTable dot 
WHERE OptionVal1 = 'y' 
UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2') 
FROM DodgyOldTable dot 
WHERE OptionVal2 = 'y' 
UNION SELECT ID, (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal3') 
FROM DodgyOldTable dot 
WHERE OptionVal3 = 'y' 
+0

@ Lieven: Không có hành vi phạm tội, nhưng tôi không nghĩ rằng đó là một nhu cầu để bao gồm một lời chào và đóng cửa trong câu trả lời của bạn. – Tomalak

+0

@Tomalak, không phạm tội. Tôi đã không nhận thức được điều đó. Tôi coi đó là lịch sự tiêu chuẩn trong các cuộc hội thoại qua thư. Lần cuối cùng, liên quan, Lieven :) –

+0

@ Lieven: Một lần nữa không có hành vi phạm tội, nhưng tôi đã tự do loại bỏ các lời chào và đóng cửa để cải thiện khả năng đọc. –

0

Bạn có thể UNION tất cả các Selects với nhau để cung cấp cho một tập hợp kết quả nhưng nó phụ thuộc vào lý do của bạn vì không muốn các nhiều Selects - nếu có quá nhiều hoặc số Selects có thể thay đổi thường xuyên nó vẫn sẽ có một nỗi đau để sửa đổi truy vấn với các lựa chọn bổ sung. Thật không may tôi nghĩ bạn sẽ phải đặt logic ở đâu đó để xác định bit (s) của bản đồ DodgyOldTable đến cấu trúc mới và viết một kịch bản di chuyển (hoặc gói SSIS) để di chuyển hàng loạt (nếu đây là một công việc) hoặc UNION kết quả của bạn với nhau ...

INSERT MainTable_Option ([MainTableID],[OptionID]) 
SELECT ID, (CASE WHEN OptionVal1 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal1') END 
FROM DodgyOldTable 
WHERE OptionVal1 = 'y 
UNION 
SELECT ID, (CASE WHEN OptionVal2 = 'y' THEN (SELECT OptionID FROM Option WHERE OptionDesc = 'OptionVal2') END 
FROM DodgyOldTable 
WHERE OptionVal2 = 'y 
... 
1

Kinh nghiệm của tôi là nó thường dễ dàng hơn và dễ đọc hơn để phân chia nó ra thành các bit nhỏ hơn. Vì vậy, đừng cố gắng làm mọi thứ trong một truy vấn đơn lẻ. Đặc biệt là khi bạn đang tạo kịch bản di chuyển, đây không phải là vấn đề.

Viết ra các bước, có thể giới thiệu một bảng tạm thời, viết kịch bản để di chuyển dữ liệu của bạn và bạn tốt để đi!

1

Còn giải pháp CROSS JOIN thì sao?

DECLARE @DodgyOldTable TABLE (ID INT, OptionVal1 CHAR, OptionVal2 CHAR, 
    OptionVal3 CHAR) 
INSERT INTO @DodgyOldTable 
SELECT 1, 'y', 'n', 'y' UNION 
SELECT 2, 'y', 'n', 'n' UNION 
SELECT 3, 'n', 'n', 'y' UNION 
SELECT 4, 'y', 'y', 'y' UNION 
SELECT 5, 'n', 'n', 'n' 

DECLARE @Option TABLE (OptionID INT, OptionDesc VARCHAR(100)) 
INSERT INTO @Option 
SELECT 1, 'OptionVal1' UNION 
SELECT 2, 'OptionVal2' UNION 
SELECT 3, 'OptionVal3' 

SELECT ID, OptionID FROM 
(
    SELECT 
     ID, 
     CASE  
      WHEN (OptionVal1 = 'y' AND OptionDesc = 'OptionVal1') 
      OR (OptionVal2 = 'y' AND OptionDesc = 'OptionVal2') 
      OR (OptionVal3 = 'y' AND OptionDesc = 'OptionVal3') 
      THEN OptionID 
      ELSE NULL 
     END AS OptionID 
    FROM @DodgyOldTable DOT CROSS JOIN @Option O 
)CRS 
WHERE OptionID IS NOT NULL 
Các vấn đề liên quan