将两个不相关的视图合并到一个视图中
Posted
技术标签:
【中文标题】将两个不相关的视图合并到一个视图中【英文标题】:Merge two unrelated views into a single view 【发布时间】:2012-02-03 15:09:52 【问题描述】:假设我在第一眼看到(ClothingID, Shoes, Shirts)
在第二个视图中我有(ClothingID, Shoes, Shirts)
但是
数据是完全不相关的,即使是 ID 字段也不相关。
我希望它们组合成 1 个单一视图以用于报告目的。
所以第三个视图(我想要做的那个)应该是这样的:(ClothingID, ClothingID2, Shoes, Shoes2, Shirts, Shirts2)
所以根本没有关系,我只是将它们并排,不相关的数据放在同一个视图中。
任何帮助将不胜感激
【问题讨论】:
如果没有关系,为什么要加入他们?并且:如何?笛卡尔积? Merging 2 views together into 1 view的可能重复 【参考方案1】:您希望合并结果,但又能分开行。 复制所有列会有点矫枉过正。添加包含来源信息的列:
SELECT 'v1'::text AS source, clothingid, shoes, shirts
FROM view1
UNION ALL
SELECT 'v2'::text AS source, clothingid, shoes, shirts
FROM view2;
【讨论】:
我今天摸不着头脑,我想,嘿,我很傻,我应该再写一个说明来源的专栏,我回顾了我的答案,发现你展示了如何做这个,我想,就是这样!谢谢 @user519753:有时事情是隐藏在显而易见的地方。 :)【参考方案2】:select v1.ClothingID, v2.ClothingID as ClothingID2, v1.Shoes, v2.Shoes as Shoes2,
v1.Shirts, v2.Shirts as Shirts2
from (
select *, row_number() OVER (ORDER BY ClothingID) AS row
from view_1
) v1
full outer join (
select *, row_number() OVER (ORDER BY ClothingID) AS row
from view_2
) v2 on v1.row = v2.row
我认为使用新的不相关列 row
连接表的 full outer join
可以完成这项工作。
row_number()
存在于PostgreSQL 8.4 and above。
如果你有低版本你可以模仿row_number
,例子如下。只有ClothingID
在视图范围内是唯一的,它才会起作用。
select v1.ClothingID, v2.ClothingID as ClothingID2, v1.Shoes, v2.Shoes as Shoes2,
v1.Shirts, v2.Shirts as Shirts2
from (
select *, (select count(*) from view_1 t1
where t1.ClothingID <= t.ClothingID) as row
from view_1 t
) v1
full outer join (
select *, (select count(*) from view_2 t2
where t2.ClothingID <= t.ClothingID) as row
from view_2 t
) v2 on v1.row = v2.row
在评论后添加:
我注意到并纠正了前面查询中的错误。
我会试着解释一下。首先,我们必须在两个视图中添加一个行号,以确保 id 中没有间隙。这是很简单的方法:
select *, (select count(*) from view_1 t1
where t1.ClothingID <= t.ClothingID) as row
from view_1 t
这包括两件事,简单的查询选择行(*):
select *
from view_1 t
和correlated subquery (read more on wikipedia):
(
select count(*)
from view_1 t1
where t1.ClothingID <= t.ClothingID
) as row
这对外部查询的每一行(这里是 (*))包括 self.因此,您可能会说计算所有具有ClothingID
小于或等于视图中每一行的当前行的行。对于唯一的ClothingID
(我假设),它会为您提供行编号(按ClothingID
排序)。
data.stackexchange.com - row numbering 上的实时示例。
之后,我们可以使用两个带有行号的子查询来加入它们 (full outer join
on Wikipedia),data.stackexchange.com - merge two unrelated views 上的实时示例。
【讨论】:
我会试试这个,似乎是我唯一的希望:) @user519753 我为低于 8.4 的 PostgreSQL 添加了替代查询。t1.ClothingID <= t.ClothingID
还是不明白t.ClothingID
是干什么用的,不是表1 的t1 也不是表2 的t2,那么它代表什么?也感谢您深入解释。【参考方案3】:
您可以使用 Rownumber 作为连接参数和 2 个临时表吗?
比如:
Insert @table1
SELECT ROW_NUMBER() OVER (ORDER BY t1.Clothing_ID ASC) [Row_ID], Clothing_ID, Shoes, Shirts)
FROM Table1
Insert @table2
SELECT ROW_NUMBER() OVER (ORDER BY t1.Clothing_ID ASC)[RowID], Clothing_ID, Shoes, Shirts)
FROM Table2
Select t1.Clothing_ID, t2.Clothing_ID,t1.Shoes,t2.Shoes, t1.Shirts,t2.Shirts
from @table1 t1
JOIN atable2 t2 on t1.Row_ID = t2.Row_ID
我认为这应该是大致合理的。确保您使用的是正确的联接,以便显示两个查询的完整输出
e;fb
【讨论】:
【参考方案4】:如果视图不相关,SQL 将难以处理。你可以做到,但有更好更简单的方法......
我建议将它们一个接一个地合并,而不是像您建议的那样并排,即联合而不是加入:
select 'view1' as source, ClothingID, Shoes, Shirts
from view1
union all
select 'view2', ClothingID, Shoes, Shirts
from view2
这将是这种情况的常用方法,并且易于编码和理解。
请注意UNION ALL
的使用,它保留选定的行顺序并且不删除重复项,而不是UNION
,它对行进行排序并删除重复项。
已编辑
添加了一个列,指示该行来自哪个视图。
【讨论】:
UNION ALL
不一定保留行顺序。它只是不会删除任何重复项(通常 DBMS 会连接结果,但它们不是必需的)。请注意,对于这样的复合 SELECT 语句,您只能将 ORDER BY 子句放在末尾,而不能放在子部分中。
@Benoit 他们可能不是要求按所选顺序交付行,但在使用数据库的 20 年中,我还没有看到联合执行任何其他方式。
我昨天看到了(甲骨文)。 WITH x AS (SELECT ... UNION ALL SELECT ... /* ZERO order by here */) SELECT * FROM x
给了我打乱的结果。
它没有给我单独的列,所以如果数据被推送到相同的列并且数据不相关,我将无法在UNION ALL
中区分它们【参考方案5】:
您可以尝试以下操作:
SELECT *
FROM (SELECT row_number() over(), * FROM table1) t1
FULL JOIN (SELECT row_number() over(), * FROM table2) t2 using(row_number)
【讨论】:
以上是关于将两个不相关的视图合并到一个视图中的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 2008 中将两个表合并到一个索引视图中