SQL Server存储过程选择,存在,多表
Posted
技术标签:
【中文标题】SQL Server存储过程选择,存在,多表【英文标题】:SQL Server stored procedure select, exists, multiple tables 【发布时间】:2014-09-26 09:32:02 【问题描述】:有什么方法可以做到吗?
表 1
1
2
3
4
5
表2
3 (with the condition)
4 (without the condition)
我想:
-
如果表2中存在表1,则选择表1中的所有记录,其中...(条件)
如果 Table2 中不存在,则选择 Table1 中的所有记录
合并两个选择结果。按照创建日期对所有结果进行排序。
例如,结果应该是:
结果
1
2
3
5
【问题讨论】:
【参考方案1】:希望这会有所帮助。
SELECT t1.* from table1 t1
JOIN table2 t2
ON t1.ID = t2.ID
UNION ALL
SELECT t1.* from table1 t1 where ID in
(
SELECT t2.ID from table1 t1 except Select t2.ID from table2 t2
)
ORDER BY t1.CreatedDate
【讨论】:
1 - 你忘记了条件。 2 -SELECT t2.ID from table1 t1
将失败。 3 - 为什么 IN (... t1 EXCEPT ... t2)
而不是 NOT IN (... t2)
? 4 - 性能不是很好(fiddle,看执行计划)。【参考方案2】:
你可以这样做:
SELECT t1.id
FROM Table1 t1
LEFT JOIN Table2 t2 on t1.id = t2.id
WHERE condition OR t2.id IS NULL
ORDER BY t1.CreatedDate;
见fiddle(我假设条件是t2.id!=4
,但它可以是其他任何东西,具体取决于表中的其他数据)。
【讨论】:
【参考方案3】:可能有多种解决方案。 单程 我们可以使用两个不同的查询获得结果集,最后使用 UNION 组合两个结果集
另一种方式, 第一条语句是说从 TABLE1 获取所有结果集,如果它存在于 TABLE2 中以及某些条件(where 子句中的条件) 意味着使用 INNER JOIN 我们可以实现这一点 第二条语句是说从 TABLE1 中获取 TABLE2 中不存在的所有结果集 表示连同 INNER JOIN ed 查询还包括 TABLE1 的数据(如果 TABLE2 中不存在) 在这里我们可以借助 LEFT OUTER JOIN(取左侧的 TABLE1)
假设:(条件:t1.Id != 4)
让我们尝试使用上述两种方式来理解查询
---- -- --Step1 Create table and insert records
---- create table1 with Id int identity columsn
--CREATE TABLE Table1 (Id INT IDENTITY(1,1), CreatedDate smalldatetime default(getdate()));
--go
---- insert 1st 5 integers into Table1
--INSERT INTO Table1 DEFAULT VALUES
--go 5
---- create Table2 with Id int column
--CREATE TABLE Table2 (Id INT , CreatedDate smalldatetime default(getdate()));
--go
---- insert records 3,5 into Table2
--INSERT INTO Table2(Id) VALUES (3), (4);
-- -- -- Solution: one way
; WITH cteMyFirstResult AS
(
-- 2.1. Select all records from Table1 if it exists in Table 2, where...(condition)
SELECT
Id, CreatedDate
FROM Table1 AS t1
WHERE t1.Id IN (SELECT Id FROM Table2 AS t2)
AND t1.Id != 4 -- assumption it can be any condition
),cteMySecondResult AS (
-- 2.2. Select all records from Table1 if it not exists in Table2
SELECT
Id, CreatedDate
FROM Table1 AS t1 WHERE t1.Id NOT IN (SELECT Id FROM Table2 AS t2)
)
-- 2.3. Combine both select results. Sort all results with their created date.
SELECT
Id, CreatedDate
FROM cteMyFirstResult
UNION
SELECT
Id, CreatedDate
FROM cteMySecondResult
ORDER BY CreatedDate;
-- -- 解决方案:另一种方式(有bug)
SELECT t1.Id, t1.CreatedDate
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 on t1.id = t2.id
WHERE t1.Id != 4
Order by T1.CreatedDate;
-- 在这个查询中,我们在执行连接操作后使用条件。 -- 因此在根据 JOIN 条件过滤掉结果集后,将应用此条件 -- 如果 Table1 中有任何空记录,则列 Id(用于连接)将不会出现在最终结果集中
--为了避免这种情况,我们可以在我们的标准中包含 NULL 检查
-- -- 解决方法:另一种方法
SELECT t1.Id, t1.CreatedDate
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 on t1.id = t2.id
WHERE ( t1.Id != 4 ) OR t1.Id IS NULL -- include all your criteria within small-barcket)
Order by T1.CreatedDate;
【讨论】:
【参考方案4】:感谢所有回复。
我得到了我想要的答案:
SELECT *
FROM Table1 t1
WHERE NOT EXISTS(SELECT 1 FROM Table2 t2
WHERE t1.ID = t2.ID
AND t2.CIF_KEY = @CifKey
AND t2.STATUS <> ''3'')
AND (condition in where clause)
【讨论】:
以上是关于SQL Server存储过程选择,存在,多表的主要内容,如果未能解决你的问题,请参考以下文章
20180927 SQL server ProcedureT-SQL创建前删除已存在存储过程
sql server 2008,如何查看存储过程里面的内容?