根据列值查询另一个表中的值

时间:2016-01-12 15:50:50

标签: sql-server

我正在尝试创建一个从其他两个表中提取信息的查询,但是我只知道根据另一个表中的列从哪个表中提取信息。我目前正在尝试使用存储过程(例如构建查询然后运行它),但我想知道是否有更好的方法来执行此操作,或者我是否可以在单个查询中完成它。

就连接而言,ID在整个数据库中是唯一的,因此没有两个ID会重叠。但是我不知道ID涉及哪个子表。我可以通过拉入一个碰巧有信息的无关表(称之为对象表)来找到它。其中一列将为我提供信息的表名(在我的示例中,Person)。我在下面起草了一个简单的例子。您能在单个查询中看到我能以任何方式完成此任务吗?像这样的东西是我的目标,但我开始认为它不可能。

SELECT * FROM base_table 
LEFT JOIN object ON object.id = base_table.role 
LEFT JOIN [object.type] tmp ON tmp.entity_id = base_table.entity_id

id | role | entity_id        (Base Table)
---------------------
1  | 101  | 1000


id | type                   (Objects Table)
------------
101| person

entity_id | name | etc..    (Person Table)
------------------------
1000      | Bob  | ...

我也期望工会可能是一个可能的解决方案 - 但其他只是加入所有可能的表并解析列以便正确匹配(可能多达20个表)我不愿意。这个解决方案也有点不便,因为列不总是以一种好的方式匹配(例如,Person表没有与Address表类似的列)

2 个答案:

答案 0 :(得分:2)

您可能想要做的是:对于每个可能的详细信息表(即[object.value]中的可能值),编写一个仅与该一个详细信息表链接并且具有{{1 }}子句限制到适当的实体。然后为所有这些查询执行WHERE

假设UNION ALL中有PersonLegal PersonCounterpart作为可能的值。假设详细信息表具有相同的名称。你可以写:

[object.type]

答案 1 :(得分:2)

如果你只是忽略对象类型,我认为左连接的想法是不好的。

由于每个ID都是唯一的,因此如果使用coalesce,则根本不需要查看类型。所以以@TT模型为例:

SELECT bt.*,
  COALESCE(P.f1, L.f1, C.f1) AS f1,
  -- ...,
  COALESCE(P.fn, L.fn, C.fn) AS fn
FROM
  base_table AS bt
  LEFT JOIN Person AS P ON P.entity_id = bt.entity_id
  LEFT JOIN [Legal Person] AS L ON L.entity_id = bt.entity_id
  LEFT JOIN Counterpart AS C ON C.entity_id = bt.entity_id

根据您的数据大小和索引,这可能比TT的示例更快或更相同 - 记住只有1个选择N个连接而TT有N个选择,2N连接。这真的取决于你的数据。

如果有一些字段(fz)没有出现在所有类型中,那么你就不会在coalesce子句中包含它。

我认为这种风格可能更容易维护和理解,并且与TT代码相同或更快。