SQL连接两个表,使用一个值作为其他的列名

时间:2014-12-12 23:56:19

标签: sql oracle

我有点难以接受我需要为工作而写的查询。我有以下两个表:

|===============Patterns==============|
|type       | bucket_id | description |
|-----------------------|-------------|
|pattern a  | 1         |  Email      |
|pattern b  | 2         |  Phone      |


|==========Results============|
|id     | buc_1     | buc_2   |
|-----------------------------|
|123    | pass      |         |
|124    | pass      |fail     |

在结果表中,我可以看到实体124在buc_2中未通过验证检查。查看模式表,我可以看到存储桶2属于模式b(bucket_id对应于结果表中的列名),因此实体124未通过电话验证。但是,如何编写一个将这两个表连接到其中一个列的值的查询?如何调用此查询的限制很可能会阻止我使用任何游标。

3 个答案:

答案 0 :(得分:1)

一些原油解决方案:

SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_1" = 'fail' AND "bucket_id" = 1

union all 

SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_2" = 'fail' AND "bucket_id" = 2

或者,有一个非常可能更好的执行计划:

SELECT "id", "description" FROM
Results JOIN Patterns
ON "buc_1" = 'fail' AND "bucket_id" = 1
OR "buc_2" = 'fail' AND "bucket_id" = 2;

这将报告存储桶1或2中具有失败案例的每个id所有失败说明。

有关实例,请参阅http://sqlfiddle.com/#!4/a3eae/8


话虽这么说,正确的解决方案可能会将您的架构更改为更易于管理的架构。比如使用association table来存储每个失败的测试 - 实际上这里有一个many to many relationship

答案 1 :(得分:0)

在我看来,您真正想知道的是在条件存储桶失败的情况下,模式条目的描述(在您的示例中为Phone)。无论具体示例如何,您都需要满足该条件的解决方案,而不仅仅是您的特定示例。

我同意上述评论。您的存储桶条目应该是元组(行)而不是参数,并且您还应该在每个表上共享ID,以便您可以实际加入它们。例如,考虑添加一个存储桶列并索引其编号,然后只需添加一个结果列来存储状态。像这样:

  |===============Patterns==============|
  |type       | bucket_id | description |
  |-----------------------|-------------|
  |pattern a  | 1         |  Email      |
  |pattern b  | 2         |  Phone      |


  |==========Results====================|
  |entity_id     | bucket_id    |status |
  |-------------------------------------|
  |123           | 1            |pass   |
  |124           | 1            |pass   |
  |123           | 2            |       |
  |124           | 2            |fail   |

1.使用内部联接:http://www.w3schools.com/sql/sql_join_inner.asp和WHERE子句仅过滤那些失败的桶:

2.-这个例子会有帮助吗?

 SELECT Patterns.type, Patterns.description, Results.entity_id,Results.status
 INNER JOIN Results
 ON
 Patterns.bucket_id=Results.bucket_id
 WHERE
 Results.status=fail

最后,我还要为每个表添加一个primary_key列,以确保每个唯一组合的索引更快。

谢谢!

答案 2 :(得分:0)

如果您使用Oracle≥11g,另一种方法是使用UNPIVOT operation。这将在执行查询时将列转换为行:

select * from Results
unpivot ("result" for "bucket_id" in ("buc_1" as 1, "buc_2" as 2))
join Patterns
using("bucket_id")
where "result" = 'fail';

不幸的是,您仍然需要对各种列名进行硬编码。

请参阅http://sqlfiddle.com/#!4/a3eae/17