【问题标题】:SQL multiple join on two tables两个表上的 SQL 多重连接
【发布时间】:2015-07-05 16:37:17
【问题描述】:

我是 SQL 新手。

我有两张桌子。 On 包含有关线性特征的概览信息,例如特征类型、名称等,table_1。每个线状要素存在于三个空间区域中。第二个表包含每个线性要素从区域到区域 table_2 时的 x,y 位置。 x,y 在两列中,交叉的区域在第三列。我必须将表格相互关联的唯一列是名称。我想做的是将 x,y 信息加入 table_1 三次。我必须为每个区域一次的唯一列。

  TABLE_1
    NAME    TYPE
    LINE_1  A
    LINE_2  B

  TABLE_2
    NAME    ZONE    X       Y
    LINE_1  ZONE_1  53.36   48.99
    LINE_2  ZONE_1  4.36    81.38
    LINE_1  ZONE_2  41.11   93.85
    LINE_2  ZONE_2  92.86   5.37
    LINE_1  ZONE_3  3.44    87.41
    LINE_2  ZONE_3  24.45   78.60


  TABLE_OUT
    NAME    TYPE    X_ZONE_1    Y_ZONE_1    X_ZONE_2    Y_ZONE_2    X_ZONE_3    Y_ZONE_3
    LINE_1  A       53.36       48.99       41.11       93.85       3.44        87.41
    LINE_2  B       4.36        81.38       92.86       5.37        24.45       78.60

我可以做一个区域好的...

SELECT A.NAME, B.X AS X_ZONE_1, B.Y AS Y_ZONE_2 FROM
TABLE_1 A, TABLE_2 B
WHERE A.NAME = B.NAME 
AND B.ZONE = '1'

【问题讨论】:

  • 请编辑您的问题并包括示例数据和所需的结果。

标签: sql oracle join


【解决方案1】:

作为新手,您应该学习使用 SQL。可能发生的最糟糕的情况是你得到一个编译错误;-)

通过一些实验,您可能会发现:

SELECT A.NAME, B1.X AS X_ZONE_1, B1.Y AS Y_ZONE_1 
             , B2.X AS X_ZONE_2, B2.Y AS Y_ZONE_2
             , B3.X AS X_ZONE_3, B3.Y AS Y_ZONE_3 
FROM  TABLE_1 A, TABLE_2 B1
      , TABLE_2 B2
      , TABLE_2 B3 
WHERE A.NAME = B1.NAME 
AND B1.ZONE = '1'
AND A.NAME = B2.NAME 
AND B2.ZONE = '2'
AND A.NAME = B3.NAME 
AND B3.ZONE = '3'

请注意,我们需要这些表和列别名来完成这项工作。


“这通常有效,但返回的记录太多。”

如果没有看到您的实际 SQL 和一些有代表性的输入数据,我无法评论您的实际 SQL。但总的来说,行数过多的原因是:

  • 缺少连接表达式
  • 缺少过滤器表达式

调试查询的方法是逐步构建它们。从 TABLE_1 开始;确保它返回一行。然后加入TABLE_2。还要排一排吗?加入TABLE_3。重复,直到你得到你不期望的结果。逐步构建 SQL 意味着您不太可能引入拼写错误,并且在您这样做时更容易发现它们。

请注意,此处发布的示例没有针对TABLE_1 的过滤器,因此它将为驱动表中的每一行返回至少一行。如果NAMETYPE 之间没有一一对应的关系,您将获得NAME 的每个值的多个结果。

ANSI 92 连接语法对复杂查询很有帮助。它将连接和过滤器分开,许多人认为这更易读:

SELECT A.NAME, B1.X AS X_ZONE_1, B1.Y AS Y_ZONE_1 
             , B2.X AS X_ZONE_2, B2.Y AS Y_ZONE_2
             , B3.X AS X_ZONE_3, B3.Y AS Y_ZONE_3 
FROM  TABLE_1 A
          join TABLE_2 B1 on B1.NAME = A.NAME
          join TABLE_2 B2 on B2.NAME = A.NAME
          join TABLE_2 B3 on B2.NAME = A.NAME
WHERE B1.ZONE = '1'
AND B2.ZONE = '2'
AND B3.ZONE = '3'

【讨论】:

  • 这主要是可行的,但它返回的记录太多。我确实有两个以上的表要加入,总共 5 个源表。我的 sql 正在制作 16 条记录,而我只想成为一条。
【解决方案2】:

只使用一个连接:

SQL Fiddle

Oracle 11g R2 架构设置

CREATE TABLE TABLE_1 ( NAME, TYPE ) AS
          SELECT 'LINE_1', 'A' FROM DUAL
UNION ALL SELECT 'LINE_2', 'B' FROM DUAL;

CREATE TABLE TABLE_2 (NAME, ZONE, X, Y ) AS
          SELECT 'LINE_1', 'ZONE_1', 53.36, 48.99 FROM DUAL
UNION ALL SELECT 'LINE_2', 'ZONE_1',  4.36, 81.38 FROM DUAL
UNION ALL SELECT 'LINE_1', 'ZONE_2', 41.11, 93.85 FROM DUAL
UNION ALL SELECT 'LINE_2', 'ZONE_2', 92.86,  5.37 FROM DUAL
UNION ALL SELECT 'LINE_1', 'ZONE_3',  3.44, 87.41 FROM DUAL
UNION ALL SELECT 'LINE_2', 'ZONE_3', 24.45, 78.60 FROM DUAL;

查询 1

SELECT t1.NAME,
       t1.TYPE,
       MIN( CASE ZONE WHEN 'ZONE_1' THEN X END ) AS X_ZONE_1,
       MIN( CASE ZONE WHEN 'ZONE_1' THEN Y END ) AS Y_ZONE_1,
       MIN( CASE ZONE WHEN 'ZONE_2' THEN X END ) AS X_ZONE_2,
       MIN( CASE ZONE WHEN 'ZONE_2' THEN Y END ) AS Y_ZONE_2,
       MIN( CASE ZONE WHEN 'ZONE_3' THEN X END ) AS X_ZONE_3,
       MIN( CASE ZONE WHEN 'ZONE_3' THEN Y END ) AS Y_ZONE_3
FROM   TABLE_1 t1
       INNER JOIN
       TABLE_2 t2
       ON ( t1.NAME = t2.NAME )
GROUP BY
       T1.NAME,
       T1.TYPE

Results

|   NAME | TYPE | X_ZONE_1 | Y_ZONE_1 | X_ZONE_2 | Y_ZONE_2 | X_ZONE_3 | Y_ZONE_3 |
|--------|------|----------|----------|----------|----------|----------|----------|
| LINE_1 |    A |    53.36 |    48.99 |    41.11 |    93.85 |     3.44 |    87.41 |
| LINE_2 |    B |     4.36 |    81.38 |    92.86 |     5.37 |    24.45 |     78.6 |

【讨论】:

    猜你喜欢
    • 2017-09-18
    • 2021-12-26
    • 2013-02-06
    • 1970-01-01
    • 2012-02-28
    • 2012-05-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    相关资源
    最近更新 更多