【问题标题】: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) 所以根本没有关系,我只是将它们并排,不相关的数据放在同一个视图中。

任何帮助将不胜感激

【问题讨论】:

标签: sql postgresql views


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-04
      • 2014-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多