基于行值MSSQL的条件内连接

时间:2014-04-16 14:13:37

标签: sql sql-server

我有一个用于消息的MSSQL表。我有客户,工作人员和用户,每个人都有自己的表。对于此消息传递组件,可以将消息发送给客户端工作者或用户。为了区分发送者/接收者是哪种类型,我在消息表中有一个列为tiny-int,1为用户,2为客户端,3为worker。

因此,当我尝试接收消息时,在不执行多个查询的情况下,从相应的表(客户端,用户或工作人员)检索发件人名称的理想方法是什么。

我知道我可以先查询类型列,然后再进行另一个查询来获取名称,但我不想这样做是为了解决性能问题。

2 个答案:

答案 0 :(得分:1)

您可以创建一个通用视图,只列出每个列中的相关列以及消息类型,然后从消息表中加入到该列中。

CREATE VIEW ExampleView
AS
begin
    SELECT 
        firstname,
        lastname,
        1 AS MessageType
    FROM 
    dbo.Users
    union ALL
    SELECT 
        firstname,
        lastname,
        2 AS MessageType
    FROM 
    dbo.Clients
    union ALL
    SELECT 
        firstname,
        lastname,
        3 AS MessageType
    FROM 
    dbo.Workers
END

查询:

SELECT 
     a.MessageText,
     isnull(b.Firstname,'')+ISNULL(b.lastname,'') AS Name
FROM Messaging a
INNER JOIN ExampleView b ON a.MessageType = b.MessageType

如果空间不是一个大问题,您可以直接在“用户”,“客户端”和“工作人员”表中存储消息类型,然后加入该列...更好的性能,但不是真正好的数据库设计。

答案 1 :(得分:0)

根据您的描述,这是对您的表结构的一个相当大的猜测。性能将降至您拥有的索引。

Select m.*,
       COALESCE(c.ClientName, w.WorkerName, u.UserName) as Name
FROM Messages m
LEFT JOIN Clients c on c.ClientId = m.UserId AND m.type = 2
LEFT JOIN Workers w on w.WorkerId = m.UserId AND m.type = 3
LEFT JOIN Users u on u.UserId = m.UserId AND m.type = 1
Where (c.ClientId is not null 
       OR
       w.WorkerId is not null
       OR
       u.UserId is not null)