获取存储在另一个表中的列的定义而不连接两次

Posted

技术标签:

【中文标题】获取存储在另一个表中的列的定义而不连接两次【英文标题】:Get definition for columns stored in another table without joining twice 【发布时间】:2012-02-21 16:03:33 【问题描述】:

给定两个表,其中第一个表中的两列可能具有不同的值,在第二个表中引用单个列,有没有办法“定义”这些列而不将表连接两次?

例如,如果表一是

TransactionRecord( UserCreated char(3), UserModified char(3), ... , OtherData )

表二是

Users( UserID char(3), UserName varchar(50), ... , OtherData )

有没有办法得到一个结果集是

Result( TransactionData, UserNameCreated, UserNameModified )

没有将第一个表连接到第二个表两次?到目前为止,我已经能够使用以下 SQL 实现这一目标。

SELECT OtherData, uc.[UserName], uf.UserName 
FROM TransactionData
    LEFT JOIN Users uc ON TransactionData.UserCreated = uc.UserID
    LEFT JOIN Users um ON TransactionData.UserModified= um.UserID

但是这些表包含相当多的记录,并且由于连接相对昂贵,我正在寻找更好的方法。我使用的是 TSQL,数据库服务器是 SQL Server 2005。

【问题讨论】:

为了避免这种“双重”连接,您可以将用户名存储在两个单独的列中。我认为索引将解决您的性能问题 我不确定我是否理解您将用户名存储在两个单独的列中的意思。 TransactionData 还有两列:UserCreatedName, UserModifiedName 好的。我明白你的意思。在这种情况下,我不确定向表中引入两个新字段是否合理。这也是供应商提供的软件的数据库,所以我认为修改表和填充列可能必须使用触发器之类的东西来完成,而不是在应用程序代码中它可能应该在的地方。 我也不喜欢这个。我会在非常极端的情况下使用它。但是,好的索引是您的最佳选择。 【参考方案1】:

解决这个问题没有简单的方法,我认为正确的索引是唯一的方法(除非你有数千万行,否则应该没问题)。

例如,您需要一个用户 id 是聚集唯一索引的表:

CREATE UNIQUE CLUSTERED INDEX [IX_UserID] ON [dbo].[table]
(
[UserID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

聚集唯一索引在这里可以正常工作,并且肯定会比添加列或我能想到的任何其他技术便宜。

(非聚集索引会在紧要关头完成,但聚集索引会更好(因为用户 ID 将按顺序存储并且读取速度更快 - 我这样说是因为您的用户表已经在不同的列上有聚集索引(每个表只能有一个聚集索引)。

【讨论】:

【参考方案2】:

两列中的用户基本上不是第三范式。我会加入 UserID 并有一个操作位列(0 = 添加,1 = 修改)。

【讨论】:

以上是关于获取存储在另一个表中的列的定义而不连接两次的主要内容,如果未能解决你的问题,请参考以下文章

窗口函数,尝试从连接表中的列中按 created_at 排序而不分组

在另一个表的 select 子句中使用一个表中的列值

我正在尝试在另一个数据框的列中查找数据框中的列的元素,但 index() 对我不起作用

基于另一列的最大值的列上的 SQL 内连接 [重复]

使用大表连接更新 Amazon Redshift 中的列

左连接右连接交叉连接全外连接