我想创建一个相当大的基础的小备份(因此开发人员可以下载~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...
子查询。
你会如何做到这一点,所以你不必重复自己?
谢谢!
答案 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表中删除,该表将级联到所有其他表。
有大量关于级联删除的文档,所以我不会在这里重复,但它肯定值得一试。