SQL使用两个表中的值作为其他列名作为列名
我有点难以忍受我需要为工作编写的查询。我有以下两个表格:SQL使用两个表中的值作为其他列名作为列名
|===============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中的验证检查。查看模式表,我可以看到bucket 2属于模式b(bucket_id对应于结果表中的列名),所以实体124未通过手机验证。但是,我该如何编写一个查询来将这两个表连接到一列的值?如何调用此查询的限制很可能会阻止我使用任何游标。
如果您使用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';
不幸的是,你还是要硬编码的列名称。
Steam上面提到了pivot/unpivot,但我很高兴看到一个语法的例子!漂亮的功能!我能够使用它来到我需要的地方。谢谢! – Moose 2014-12-15 15:04:59
一些粗俗的解决方案:
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;
这将为每个id
斗1有失败病例报告所有故障描述或2.
请参阅http://sqlfiddle.com/#!4/a3eae/8为一个现场示例
话虽这么说,在右的解决办法是可能是您的模式更改为更易于管理。假设使用association table来存储每个失败的测试 - 因为您事实上在这里有一个many to many relationship。
我希望改变模式是一种选择!当我看到桌子时,我有点生气。这个联盟的想法很聪明!我可以使用它,但我必须看看执行时间如何。尽管我一次只能拉一个id,但结果表中会有数百万个值。 – Moose 2014-12-13 01:42:51
在我看来,你真正想知道的是在条件失败的情况下,Pattern条目的描述(在您的示例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列添加到每个表,以确保索引是每一个独特的组合更快。
谢谢!
你需要什么来得到结果?你不能以这种方式“加入”它们,但是你可以为每个'buc_X'列创建一个特定的连接子句。 – 2014-12-13 00:00:59
你可以重组你的桌子吗?这不是规范化数据库的良好实现。每当你添加一个新的模式,你需要添加一个新的列到你的结果表... – sgeddes 2014-12-13 00:09:46
哪个版本的Oracle DB你有?你应该看看PIVOT和UNPIVOT的概念 - http://oracle-base.com/articles/11g/pivot-and-unpivot-operators-11gr1.php – Steam 2014-12-13 00:26:33