合并两个没有公共字段的表

Tar*_*rik 56 sql-server union

我想学习如何组合两个没有共同字段的数据库表.我已经检查了UNION,但是MSDN说:

以下是使用UNION组合两个查询的结果集的基本规则:

  1. 所有查询中列的数量和顺序必须相同.
  2. 数据类型必须兼容.

但我根本没有共同的领域.我想要的只是将它们组合在一个表中,就像一个视图.

所以我该怎么做 ?

提前致谢.

真诚.

pax*_*blo 114

有很多方法可以做到这一点,具体取决于你真正想要的.如果没有常用列,则需要确定是要引入公共列还是获取产品.

假设您有两个表:

parts:              custs:
+----+----------+   +-----+------+
| id | desc     |   |  id | name |
+----+----------+   +-----+------+
|  1 | Sprocket |   | 100 | Bob  |
|  2 | Flange   |   | 101 | Paul |
+----+----------+   +-----+------+
Run Code Online (Sandbox Code Playgroud)

忘记实际的列,因为在这种情况下你很可能客户/订单/部件关系; 我刚刚使用这些列来说明了实现它的方法.

笛卡尔积将匹配第一个表中的每一行与第二个中的每一行:

> select * from parts, custs;
      id desc     id  name
      -- ----     --- ----
      1  Sprocket 101 Bob
      1  Sprocket 102 Paul
      2  Flange   101 Bob
      2  Flange   102 Paul
Run Code Online (Sandbox Code Playgroud)

这可能不是你想要的,因为1000个零件和100个客户将产生100,000行,其中包含大量重复信息.

或者,您可以使用联合只输出数据,但不能并排(您需要确保两种选择之间的列类型兼容,方法是使表列兼容或在选择中强制它们):

> select id as pid, desc, null as cid, null as name from parts
  union
  select null as pid, null as desc, id as cid, name from custs;
    pid desc     cid name
    --- ----     --- ----
                 101 Bob 
                 102 Paul
    1   Sprocket
    2   Flange
Run Code Online (Sandbox Code Playgroud)

在某些数据库中,您可以使用rowid/rownum列或伪列来并排匹配记录,例如:

id desc     id  name
-- ----     --- ----
1  Sprocket 101 Bob
2  Flange   101 Bob
Run Code Online (Sandbox Code Playgroud)

代码如下:

select a.id, a.desc, b.id, b.name
from parts a, custs b
where a.rownum = b.rownum;
Run Code Online (Sandbox Code Playgroud)

它仍然笛卡尔积,但该where条款限制行如何组合以形成结果(所以根本不是笛卡尔积).

我没有为此测试过SQL,因为它是我选择的DBMS的局限之一,这是正确的,我认为在经过适当考虑的架构中不需要它.由于SQL不保证其生成数据的顺序,因此除非您具有特定的关系或order by子句,否则每次执行查询时匹配都会更改.

我认为理想的做法是在两个表中添加一个列来指定关系.如果没有真正的关系,那么你可能没有尝试将它们与SQL并排放置.

如果您只是希望它们在报表或网页上并排显示(两个示例),那么正确的工具就是生成报表或网页的任何内容,再加上两个独立的 SQL查询以使两者无关表.例如,BIRT(或Crystal或Jasper)中的两列网格,每个网格都有一个单独的数据表,或者HTML两列表(或CSS),每个都有一个单独的数据表.


Mat*_*ton 24

这是一个非常奇怪的请求,几乎可以肯定是你在现实世界的应用程序中永远不想做的事情,但从纯粹的学术角度来看,这是一个有趣的挑战.使用SQL Server 2005,您可以使用公用表表达式和row_number()函数并加入:

with OrderedFoos as (
    select row_number() over (order by FooName) RowNum, *
    from Foos (nolock)
),
OrderedBars as (
    select row_number() over (order by BarName) RowNum, *
    from Bars (nolock)
)
select * 
from OrderedFoos f
    full outer join OrderedBars u on u.RowNum = f.RowNum
Run Code Online (Sandbox Code Playgroud)

这是有效的,但它是非常愚蠢的,我只提供它作为"社区维基"的答案,因为我真的不会推荐它.


Jam*_*ack 11

SELECT *
FROM table1, table2
Run Code Online (Sandbox Code Playgroud)

这将连接table1中的每一行,table2(笛卡尔积)返回所有列.

  • 这将导致交叉连接,这似乎不是他正在寻找的. (4认同)

小智 5

select 
    status_id, 
    status, 
    null as path, 
    null as Description 
from 
    zmw_t_status

union
select 
    null, 
    null, 
    path as cid, 
    Description from zmw_t_path;
Run Code Online (Sandbox Code Playgroud)


Jay*_*aya 5

尝试:

select * from table 1 left join table2 as t on 1 = 1;
Run Code Online (Sandbox Code Playgroud)

这将带来两个表中的所有列。