在多个查询中使用结果集

时间:2013-04-02 12:27:03

标签: sql sql-server

我想创建一个相当大的基础的小备份(因此开发人员可以下载~2ggb而不是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...子查询。

你会如何做到这一点,所以你不必重复自己?

谢谢!

6 个答案:

答案 0 :(得分: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))

答案 1 :(得分: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
                      )

答案 2 :(得分: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个查询。

答案 3 :(得分:0)

这是一个非常好的问题。 SQL不提供编写SQL查询的好功能,这是不幸的。

我能想到的最好的是视图或表值函数。您可以在脚本的开头创建它,并在最后删除它。

在这种情况下,这似乎有点丑陋,它似乎仍然比动态构建SQL字符串更好。

答案 4 :(得分: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)
)

答案 5 :(得分:0)

如果您在表上设置了外键,则可以将它们设置为级联删除。如果操作正确,您只需要从users表中删除,该表将级联到所有其他表。

有大量关于级联删除的文档,所以我不会在这里重复,但它肯定值得一试。