【问题标题】:Rows as Columns without Join没有连接的行作为列
【发布时间】:2014-03-26 05:57:54
【问题描述】:

请查看this。结果确实显示了两个集合的连接。我希望输出如下,即没有笛卡尔积。

ID_1    TYPE_1  NAME_1          ID_2    TYPE_2  NAME_2
===============================================================
TP001   1       Adam Smith      TV001   2       Leon Crowell
TP002   1       Ben Conrad      TV002   2       Chris Hobbs
TP003   1       Lively Jonathan 

我使用了一种解决方案,join,我知道选择行作为列,但我需要所需格式的结果,而join 不是强制性的。

【问题讨论】:

  • 毫无理由地投反对票!!!

标签: sql oracle oracle11g


【解决方案1】:

您需要一个人工列作为 id。对两种类型的教师都使用rownum。 因为您不知道是否有更多的类型 1 或类型 2 的教师,所以您必须执行完全外连接来组合这两个集合。

SELECT *
  FROM (SELECT ROWNUM AS cnt, teacherid
             , teachertype, teachername
          FROM teachers
         WHERE teachertype = 1) qry1
       FULL OUTER JOIN (SELECT ROWNUM AS cnt, teacherid
                             , teachertype, teachername
                          FROM teachers
                         WHERE teachertype = 2) qry2
          ON qry1.cnt = qry2.cnt

一般来说,数据库是按行而不是按列考虑的。在您的示例中,您很幸运-您只有两种类型的老师。对于每一种新类型的教师,您都必须更改语句并附加一个完整的外部连接,仅以一种特殊的方式呈现您的查询输出 - 每列一组。

但是通过简单的选择,您可以检索相同的信息,并且无论您有多少教师类型,它都会起作用。

SQL 在呈现数据方面有些限制,我会将其留给客户端检索数据或使用 PL/SQL 来获得更通用的方法。

【讨论】:

    【解决方案2】:

    连接一个或多个表的键应该有一些约束。如果没有约束,它将始终导致笛卡尔积,即第一个表的行数 x 第二个表的行数

    【讨论】:

      【解决方案3】:
      SELECT TONE.TEACHERID ID_1, TONE.TEACHERTYPE TYPE_1, TONE.TEACHERNAME NAME_1
            ,TTWO.TEACHERID ID_2, TTWO.TEACHERTYPE TYPE_2, TTWO.TEACHERNAME NAME_2
      FROM 
      (SELECT TEACHERID, TEACHERTYPE, TEACHERNAME FROM TEACHERS WHERE TEACHERTYPE = 1)
        TONE
      FULL OUTER JOIN
      (SELECT TEACHERID, TEACHERTYPE, TEACHERNAME FROM TEACHERS WHERE TEACHERTYPE = 2)
        TTWO
      ON TONE.TEACHERID = REPLACE(TTWO.TEACHERID,'TV','TP');
      
      ID_1    TYPE_1  NAME_1          ID_2    TYPE_2  NAME_2
      =====   ======  ======          ======  ======  ======
      TP001   1       Adam Smith      TV001   2       Leon Crowell
      TP002   1       Ben Conrad      TV002   2       Chris Hobbs
      TP003   1       Lively Jonathan (null)  (null)  (null)
      

      http://www.sqlfiddle.com/#!4/c58f3/28

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-03-05
        • 2019-10-10
        • 2018-05-15
        • 2012-04-08
        • 2014-03-02
        相关资源
        最近更新 更多