将两个不相关的视图合并到一个视图中

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 &lt;= 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 中将两个表合并到一个索引视图中

我如何在这里将两个模板视图合并到单个视图中?

将两个视图合并为一个视图

如何将两个List合并,且其中不允许出现重复的项

如何合并两个模型集合并使其成为一个分页然后将其发送到 Laravel 中的视图

将两个imageViews合并为一个并保存iOS swift