使用不同的JOIN语句时,是否可以使用UNION / UNION ALL?

时间:2019-08-06 23:30:53

标签: sql sql-server

我正在SQL Server中建立一个视图,但不确定是否要以正确的方式进行操作。有问题的表就像一个Changelog / Audit表,该表记录了对记录的所有更改,例如更改的字段,值是什么,更改为什么,更改的人以及更改的时间。

问题在于值通常是代码,要知道更改是什么,需要将其连接到其他表才能看到文本字段。要知道将其联接到哪个表,您必须使用表中的字段名称。到目前为止,我见过的唯一方法是通过具有不同联接的多个SELECT语句,然后是UNION ALL。我不确定是否有更聪明的方法可以做到这一点,因为这似乎影响很大。

如果我的解释不够好,这是我正在做的事情的简化版本:

SELECT
    TICKETID,
    FIELDNAME,
    SO.TEXT AS OLD,
    SN.TEXT AS NEW,
    USER,
    DATE
FROM
    CHANGELOG C
INNER JOIN STATUS SO
    ON SO.STATUSID = C.OLD
INNER JOIN STATUS SN
    ON SN.STATUSID = C.NEW
WHERE
    FIELDNAME = 'STATUS'
UNION ALL
SELECT
    TICKETID,
    FIELDNAME,
    UO.TEXT AS OLD,
    UN.TEXT AS NEW,
    USER,
    DATE
FROM
    CHANGELOG C
INNER JOIN USER UO
    ON SO.USERID= C.OLD
INNER JOIN STATUS UN
    ON SN.USERID = C.NEW
WHERE
FIELDNAME = 'ASSIGNEDTOUSER' 

这可以满足我的需求,但是我可能必须加入30多个字段。该查询将变得非常大,并且看起来不直观。感谢您的任何帮助,如果之前曾问过这样的问题,对不起。

1 个答案:

答案 0 :(得分:3)

您可以先将所有引用表合并在一起,然后再连接一次:

with ref as (
      select 'STATUS' as fieldname, statusid as refid, text
      from status
      union all
      select 'USER' as fieldname, userid, text
      from user
      union all
      . . .
    )
select c.ticketid, c.fieldname,
       ro.TEXT as OLD,
       rn.TEXT as NEW,
       c.user, c.date
from changelog c join
     ref ro
     on ro.refid = c.old and ro.fieldname = c.fieldname join
     ref rn
     on ro.refid = c.new and ro.fieldname = c.fieldname