我需要在垂直表中展平2行(然后连接到第三个表)我通常通过为我需要的每个字段创建派生表来实现这一点。只有两个领域,我认为这不是不合理的。
但我知道我想要在派生表中返回的行是我与第三个表连接的子集。 所以我试图找出最好的派生表,以便查询运行效率最高。
我认为我对派生表的where子句进行了更严格的限制,派生表越小,我得到的响应就越好。
我真正想要的是将派生表的where子句与第3个表的连接相关联,但是你不能在sql中这样做,这太糟糕了。但我不是sql master,也许有一些我不知道的技巧。
另一种选择只是使派生表没有where子句,它最终只加入整个表两次(每个字段一次),当我对他们进行连接时,连接过滤掉每一个东西进行。
所以我真正想要的是我猜是什么是制作派生表的最佳方法,我非常具体地知道我想要的行,但是sql不会让我得到它们。
一个例子:
table1
------
id tag value
-- ----- -----
1 first john
1 last smith
2 first sally
2 last smithers
table2
------
id occupation
-- ----------
1 carpenter
2 homemaker
select table2.occupation, firsttable.first, lasttable.last from
table2, (select value as first from table1 where tag = 'first') firsttable,
(select value as last from table1 where tag = 'last') lasttable
where table2.id = firsttable.id and table2.id = lasttable.id
我想做的是制作firsttable where子句,其中tag ='first'和id = table2.id
答案 0 :(得分:1)
DERIVED表不会按预期存储中间结果。这些只是使代码更简单的一种方法。使用派生表并不意味着派生表表达式将首先执行,并且输出将用于与剩余表连接。在大多数情况下,优化程序将自动生成派生表。
但是,在某些情况下,优化器可能希望存储子查询的结果,从而进行materilize而不是flattening。当你有某种聚合函数或类似函数时,通常会发生这种情况。但在你的情况下,查询也是如此简单,因此优化器将展平查询
此外,存储派生表表达式不会使您的查询变得更快,反过来可能会使它变得更糟。您的真正问题是规范化太多。查询该查询将只是两个表的连接。
为什么要进行这种规范化?为什么要将col值存储为行。尝试对table1进行非规范化,使其首先和最后有两列。这将是最佳解决方案。
另外,你对id和tag列有适当的索引吗?如果是,则合并连接非常适合您的查询。
请提供这些表格的索引详情以及您的查询生成的计划。
您的查询将像内部联接查询一样使用。
select table2.occupation, first.valkue as first, last.value as last
from
table2
inner join table1 first
on first.tag = 'first'
and first.id =table2.id
inner join table1 last
on last.tag = 'last'
and table2.id = last.id
答案 1 :(得分:0)
我认为你所要求的是COMMON TABLE EXPRESSION
。如果您的平台没有实现它们,那么临时表可能是最好的选择。
答案 2 :(得分:0)
我有点困惑。您的查询看起来没问题。 。 。虽然使用正确的连接语法看起来更好。
select table2.occupation, firsttable.first, lasttable.last
from table2 join
(select value as first from table1 where tag = 'first') firsttable
on table2.id = firsttable.id join
(select value as last from table1 where tag = 'last') lasttable
on table2.id = lasttable.id
此查询执行您要求它执行的操作。 SQL是一种声明性语言,而不是一种过程语言。这意味着您描述结果集并依赖数据库SQL编译器将其转换为正确的命令集。 (也就是说,有时候查询的结构如何使某些引擎更容易或更难以生成有效的查询计划。)