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...在很多地方使用相同的子查询。

你将如何做到这一点,这样你就不必重复自己?

谢谢 !

4

6 回答 6

2

尝试将值插入临时变量并在所有 where 条件下使用相同的值。

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))
于 2013-04-02T12:32:31.947 回答
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
                      )
于 2013-04-02T12:36:36.407 回答
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 原则,因为您只需在一个地方定义查询。如果您需要更改业务逻辑,您只需更改一个查询,而不是原始代码中的 3 个查询。

于 2013-04-02T12:31:12.250 回答
0

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

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

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

于 2013-04-02T12:31:13.643 回答
0

创建表变量或临时表并存储 Select 查询数据

 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)
)
于 2013-04-02T12:32:06.183 回答
0

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

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

于 2013-04-02T12:41:47.980 回答