简体   繁体   English

有条件地联接到SQL Server中的不同表

[英]Conditionally join to different tables in SQL Server

We have two tables with identical schemas in two different databases. 我们在两个不同的数据库中有两个具有相同架构的表。 We have a job that runs and uses data that joins to one or the other of those two tables. 我们有一项工作在运行并使用连接到这两个表中的一个或另一个的数据。 What we would ideally like to do (which I know isn't possible) is: 我们理想地希望做的(我知道这是不可能的)是:

SELECT
    *
FROM
    OtherData d
    IF (condition)
        INNER JOIN database1.Table t ON ...
    ELSE
        INNER JOIN database2.Table t ON ...

We tried building out a view that unions the two datasets and returns the condition as part of the view, so we could select where the condition is true. 我们尝试构建一个将两个数据集合并并返回条件作为视图一部分的视图,因此我们可以选择条件为true的位置。 If we just select against the view, the query plan shows that it only hits the desired database without going to the other. 如果仅针对视图进行选择,则查询计划将显示它仅命中所需的数据库,而没有其他数据库。 If we join to the view though, it goes to both. 但是,如果我们加入视图,则两者都进入。

CREATE VIEW View_Table AS
    SELECT
        1 AS Condition,
        OtherData...
    FROM...
        database1.Table
    UNION
    SELECT
        2 AS Condition,
        OtherData...
    FROM
        database2.Table
GO


-- Then use it as:
SELECT
    *
FROM
    OtherData d
    INNER JOIN View_Table vt ON vt.Condition = @Condition AND ...

So we are trying to figure out the best way (without just doing giant IF...ELSE... statements that duplicate large portions of our procs) to write this such that in execution we will only hit the desired database and not try to go to both when we know up front which to hit. 因此,我们试图找出最好的方法(而不是仅仅做巨大的IF ... ELSE ...重复大部分proc语句的语句)来编写此代码,以便在执行时我们只会命中所需的数据库,而不会尝试当我们知道要先击中哪个时,请同时访问两者。

You can use the ISNULL function: 您可以使用ISNULL函数:

SELECT      d.*,
            ISNULL(T1.Field, T2.Field) Field
FROM        OtherData d
LEFT JOIN   database1.[Table] t1
        ON  d.Field = t1.Field AND (condition)
LEFT JOIN   database2.[Table] t2
        ON  d.Field = t2.Field AND (condition)

Or the CASE statement: CASE语句:

SELECT      d.*,    
            CASE    WHEN    (condition)
                    THEN    t1.Field
                    ELSE    t2.Field
            END Field
FROM        OtherData d
LEFT JOIN   database1.[Table] t1
        ON  d.Field = t1.Field
LEFT JOIN   database2.[Table] t2
        ON  d.Field = t2.Field

You could use a staging table to simplify your stored procedure. 您可以使用登台表来简化存储过程。

Pseudosql... 伪SQL ...

truncate table stage.Table;

IF (condition)
    select * into stage.Table from database1.Table where ...
ELSE
    select * into stage.Table from database2.Table where ...

-- Then use it as:
SELECT
    *
FROM
    OtherData d
    INNER JOIN stage.Table ON ...

IMHO, I'd try to do any type of data flow with SSIS packages which would also make it easier to conditionally hit different databases (via Control Flow). 恕我直言,我将尝试使用SSIS包进行任何类型的数据流处理,这也将使得有条件地访问不同的数据库(通过Control Flow)变得更加容易。

This is a case where dynamic SQL is probably your best bet. 在这种情况下,动态SQL可能是最好的选择。

And of course when telling people to use dynamic SQL, you must refer then to the page that describes the hazards of using it and how to protect your self when you must use it. 当然,当告诉人们使用动态SQL时,您必须随后参考该页面,其中描述了使用它的危害以及在必须使用它时如何保护自己。

http://www.sommarskog.se/dynamic_sql.html http://www.sommarskog.se/dynamic_sql.html

http://www.sommarskog.se/dyn-search.html http://www.sommarskog.se/dyn-search.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM