Sql 在多个查询中使用结果集
我想在相当大的基础上创建一个小型备份(这样开发者可以下载~1-2gb而不是15gb) 为了做到这一点,我复制了基,并运行了一些脚本来截断一些表(日志等),我想删除一些用户之外的数据(总是相同的用户) 现在我有这个:Sql 在多个查询中使用结果集,sql,sql-server,Sql,Sql Server,我想在相当大的基础上创建一个小型备份(这样开发者可以下载~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 I
-- 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
如您所见,我总是在许多地方使用相同的从用户中选择用户ID,这些用户的电子邮件ID如“%@xxx.com”或电子邮件ID如“%@yyy.com”或…
子查询
你会怎么做,这样你就不必重复了
谢谢大家! 将结果存储在临时表中
-- 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'
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
)
加载临时表
-- 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'
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
)
然后可以在其他查询中使用临时表
-- 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
)
这项技术允许您遵循,因为您只在一个地方定义了查询。如果需要更改业务逻辑,只需更改一个查询,而不必更改原始代码中的3个查询。这是一个非常好的问题。SQL不能提供很好的功能来组合SQL查询,这是不幸的 我能想到的最好的方法是视图或表值函数。您可以在脚本开始时创建它,然后在脚本结束时删除它
这是一个有点丑陋的黑客行为,在这种情况下,它似乎比动态构建SQL字符串要好。创建一个表变量或临时表并存储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)
)
尝试将值插入临时变量,并在所有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'
使用临时表
-- 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'
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
)
如果在表上设置了外键,则可以将它们设置为级联删除。如果操作正确,只需从users表中删除,这将级联到所有其他表
关于cascade delete有大量文档,因此我不在这里重复,但它确实值得一看。在这种情况下,我并不认为OP希望从Users表中删除,但cascade delete可以节省一些删除。在上面的例子中-订单详细信息可以与相册一起删除。是的。。。这是一个遗留数据库,几百个表有3个外键。很明显,添加FK会花费很长时间来清理数据库。好主意,但不可能执行:(