SQL Server 从两个可能的表之一中选择

发布于 2024-10-05 09:52:43 字数 316 浏览 3 评论 0原文

我有两个表,一个当前表和一个存档表。

搜索记录时,我不知道它将位于哪个表中,因此我有一个类似于以下内容的查询:

SELECT myThing FROM (current UNION archive)

我想知道,是否可以将上面的查询写成类似的内容

SELECT myThing FROM current

IF myThing IS NULL
BEGIN
    SELECT myThing FROM ARCHIVE
END

,如果是的话,或者这些方法可能会更高效。

I have two tables, a current table and an archive table.

When searching for a record, I don't know which table it will be in, so I have a query something like the following:

SELECT myThing FROM (current UNION archive)

I would like to know, is it possible to write the above query as something like

SELECT myThing FROM current

IF myThing IS NULL
BEGIN
    SELECT myThing FROM ARCHIVE
END

and which, if either, or these approaches is likely to be more performant.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

风流物 2024-10-12 09:52:43

您的第二个示例几乎可以按原样运行。只需要一个变量,

Declare @theThing varchar(max)

SELECT @theThing = myThing FROM current

IF (@theThing IS NULL)
BEGIN
    SELECT @theThing = myThing FROM ARCHIVE
END

-- to 'output' the value
SELECT @theThing

然后您可以将该代码粘贴到存储过程或函数或其他内容中。

请注意它是否会比 union 更快。我的预感是,如果 myThing 在两个表中都建立了索引,上面的速度会更快。但这只是猜测。

编辑:性能也会受到第一个表中找到该事物的频率的影响。如果大多数情况下在第一个表中找到目标,上面的代码可能会比union更快。

编辑:正如马丁指出的,只有在保证两个表中只有一场比赛的情况下,所有这一切都是值得的。否则,你需要一个联盟。

Your second example will almost work as it is. Just needs a variable

Declare @theThing varchar(max)

SELECT @theThing = myThing FROM current

IF (@theThing IS NULL)
BEGIN
    SELECT @theThing = myThing FROM ARCHIVE
END

-- to 'output' the value
SELECT @theThing

You could then stick that code in a stored procedure or function or something.

Note sure whether it will be faster than the union or not. My hunch would be the above would be faster if myThing is indexed in both tables. But thats just a guess.

edit: Performance will also be affected by how often the thing is found in the first table. Above code will likely be faster than a union if the target is found in the first table the majority of the time.

edit: As Martin points out, all this is only worth it if there's guaranteed to be only one match in the two tables. Otherwise, you need a Union.

混浊又暗下来 2024-10-12 09:52:43

使用 UNION 将成为性能杀手,因为这将强制对两个表进行不同的排序。 UNION ALL 的计划对我来说看起来不错。您可以添加 TOP 1 让它在找到第一行后停止查找。

CREATE TABLE #current (id INT PRIMARY KEY, DATA CHAR(10))   
CREATE TABLE #ARCHIVE (id INT PRIMARY KEY, DATA CHAR(10))   

INSERT INTO #current
SELECT 1, 'A' UNION ALL SELECT 2, 'B' 

INSERT INTO #ARCHIVE
SELECT 101, 'C' UNION ALL SELECT 102, 'D' 

DECLARE @id INT
SET @id = 102

;WITH things AS
(
SELECT * FROM #current
UNION ALL
SELECT * FROM #ARCHIVE
)

SELECT TOP (1) id,DATA 
FROM things
WHERE id = @id

Using UNION will be the performance killer as this will force a distinct sort of the two tables. The plan with UNION ALL looks OK to me. You can add a TOP 1 to get it to stop looking after the first row is found.

CREATE TABLE #current (id INT PRIMARY KEY, DATA CHAR(10))   
CREATE TABLE #ARCHIVE (id INT PRIMARY KEY, DATA CHAR(10))   

INSERT INTO #current
SELECT 1, 'A' UNION ALL SELECT 2, 'B' 

INSERT INTO #ARCHIVE
SELECT 101, 'C' UNION ALL SELECT 102, 'D' 

DECLARE @id INT
SET @id = 102

;WITH things AS
(
SELECT * FROM #current
UNION ALL
SELECT * FROM #ARCHIVE
)

SELECT TOP (1) id,DATA 
FROM things
WHERE id = @id
温折酒 2024-10-12 09:52:43

您可以创建一个视图

CREATE VIEW all_records
AS
SELECT * from current
UNION ALL
SELECT * from archive

并从中选择记录看法:

select * from all_records

You can create a view

CREATE VIEW all_records
AS
SELECT * from current
UNION ALL
SELECT * from archive

and select record from view:

select * from all_records
≈。彩虹 2024-10-12 09:52:43

我可以建议这个变体

select coalesce((select someData from One where Id = 12345), (select someData from Two where Id = 12345))

I can suggest this variant

select coalesce((select someData from One where Id = 12345), (select someData from Two where Id = 12345))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文