2013-04-02 23 views
3

我想創建一個相當大的基礎的小備份(所以開發人員可以下載1-2gb而不是15gb)。在幾個查詢中使用結果集

爲了做到這一點,我複製了基礎,我運行截斷某些表(原木等)的幾個劇本,我想除了一些用戶(總是相同的用戶)刪除數據。

現在我有這樣的:

-- delete order details not in test accounts 
DELETE FROM order_details WHERE Album_ID NOT IN (
    SELECT Album_ID FROM albums WHERE User_ID IN (
     SELECT User_ID FROM users 
      WHERE Email_ID LIKE '%@xxx.com' 
      OR Email_ID LIKE '%@yyy.com' 
      OR Email_ID LIKE '%@zzz.com' 
    ) 
) 
DELETE FROM orders WHERE User_ID NOT IN (
    SELECT User_ID FROM users 
     WHERE Email_ID LIKE '%@xxx.com' 
     OR Email_ID LIKE '%@yyy.com' 
     OR Email_ID LIKE '%@zzz.com' 
) 

-- delete albums not in test accounts 
DELETE FROM albums WHERE User_ID NOT IN (
    SELECT User_ID FROM users 
     WHERE Email_ID LIKE '%@xxx.com' 
     OR Email_ID LIKE '%@yyy.com' 
     OR Email_ID LIKE '%@zzz.com' 
) 
-- snip a few more of the same 

正如你所看到的,我總是用在好幾個地方同SELECT User_ID FROM users WHERE Email_ID LIKE '%@xxx.com' OR Email_ID LIKE '%@yyy.com' OR...子查詢。

你會怎麼做,所以你不必重複自己?

謝謝!

回答

2

嘗試插入值到一個臨時變量,並使用相同的所有地方的條件。

DECLARE @table as TABLE(User_ID Nvarchar(50)) 

INSERT INTO @table (User_ID) 
SELECT User_ID FROM users 
     WHERE Email_ID LIKE '%@xxx.com' 
     OR Email_ID LIKE '%@yyy.com' 
     OR Email_ID LIKE '%@zzz.com' 

DELETE FROM order_details WHERE Album_ID NOT IN (
    SELECT Album_ID FROM albums WHERE User_ID IN (
     SELECT User_ID FROM @table)) 
0

。結果存儲在一個臨時表

-- create temporary table to keep track of users 
    CREATE TABLE #users 
    (
     user_id BIGINT 
    ) 

裝入臨時表

INSERT INTO #users (user_id) 
SELECT User_ID FROM users 
     WHERE Email_ID LIKE '%@xxx.com' 
     OR Email_ID LIKE '%@yyy.com' 
     OR Email_ID LIKE '%@zzz.com' 

然後你可以用臨時表中的其他查詢。

-- delete order details not in test accounts 
DELETE FROM order_details WHERE Album_ID NOT IN (
    SELECT Album_ID FROM albums WHERE User_ID IN (
     SELECT User_ID FROM #users 
    ) 
) 
DELETE FROM orders WHERE User_ID NOT IN (
    SELECT User_ID FROM #users 
) 

-- delete albums not in test accounts 
DELETE FROM albums WHERE User_ID NOT IN (
    SELECT User_ID FROM #users 
) 

這種技術可以讓您按照DRY principle,因爲你只需要在一個地方定義的查詢。如果您需要更改業務邏輯,則只需更改該查詢,而不是像原始代碼那樣更改3個查詢。

0

這是一個非常好的問題。 SQL不提供良好的功能來編寫SQL查詢,這是不幸的。

我能想到的最好的是一個視圖或表值函數。您可以在腳本的開頭創建它,並在最後刪除它。

這是一個有點醜陋的黑客攻擊位的仍似乎比在這種情況下,動態構建SQL字符串更好。

0

創建一個表變量或臨時表和存儲選擇查詢數據

Declare @User table 
(User_Id int) 

Insert into @User 
    SELECT User_ID FROM users 
     WHERE Email_ID LIKE '%@xxx.com' 
     OR Email_ID LIKE '%@yyy.com' 
     OR Email_ID LIKE '%@zzz.com' 

DELETE FROM order_details WHERE Album_ID NOT IN (
SELECT Album_ID FROM albums WHERE User_ID IN (
    Select User_Id from @User) 
) 
1

使用臨時表

IF OBJECT_ID('tempdb.dbo.#tmpUserID') IS NOT NULL DROP TABLE dbo.#tmpUserID 
SELECT User_ID 
INTO dbo.#tmpUserID 
FROM users 
WHERE Email_ID LIKE '%@xxx.com' 
    OR Email_ID LIKE '%@yyy.com' 
    OR Email_ID LIKE '%@zzz.com' 

-- delete order details not in test accounts 
DELETE FROM order_details 
WHERE Album_ID NOT IN (
         SELECT Album_ID 
         FROM albums 
         WHERE User_ID IN (
             SELECT User_ID FROM #tmpUserID 
             ) 
         )  
DELETE FROM orders 
WHERE User_ID NOT IN (
         SELECT User_ID FROM #tmpUserID 
        ) 

-- delete albums not in test accounts 
DELETE FROM albums 
WHERE User_ID NOT IN (
         SELECT User_ID FROM #tmpUserID 
        ) 
0

如果你有外鍵設置你的表,那麼你可以設置它們的級聯刪除。如果正確完成,您只需從用戶表中刪除,該用戶表將級聯到所有其他表。

有關於級聯刪除一噸的文檔,所以我就不在這裏重複了,但它一定是值得仔細研究的。

+0

我並不認爲OP在這種情況下想從Users表中刪除,但級聯刪除可以節省一些刪除操作。在上面的例子中,order_details可以在專輯中刪除。 –

+0

是的......這是一個傳統的數據庫,有幾百個表格就有3個外鍵。顯然,添加FK將永遠需要清理數據庫。所以,好主意,但不可能執行:( – thomasb

相關問題