【问题标题】:SQL Join select statements for multiple columnsSQL Join 多列的选择语句
【发布时间】:2015-02-15 07:07:03
【问题描述】:

我正在使用 TOAD 9.7 在 oracle 数据库中工作。

我有三个要从中选择数据的表。这三个表共享一个唯一 ID,称为 GID。

我想从满足特定条件的所有三个表中选择数据,然后加入 select 语句,以便有多个列,而不是具有相同唯一 ID 的多行。但是,我不想简单地加入多个选择语句。我相信我正在寻找的是一个交叉表查询,因为我只希望每个唯一 id 有一行,每个 ntype 和 atype 都有列标题

这里是第一个表的数据示例,我们将其称为 Table_G。

+---------+--------+--------+ |标识 |甲基 |团队 | +---------+--------+--------+ | -1534063 | 60 | 3070 | | -1534064 | 60 | 3070 | | -1534065 | 60 | 3070 | | -1534061 | 60 | 3069 | | -1534062 | 60 | 3069 | | -1534060 | 60 | 3069 | +---------+--------+--------+

这里是第二个表的例子,我们称之为 Table_N

+---------+--------+------------+--------+ |标识 |类型 | NVAL |团队 | +---------+--------+------------+--------+ | -1534064 | 61 | 102-1095-1 | 3070 | | -1534064 | 18 | 1868 | 3070 | | -1534064 | 5 |第659章3070 | | -1520001 | 61 | 103-1040-1 | 3070 | | -1520001 | 18 | 4285 | 3070 | | -1520002 | 61 | 103-1040-2 | 3070 | +---------+--------+------------+--------+

最后是第三张表,它与第二张表非常相似,但使用 atype 和 aval 而不是 ntype 和 nval——我们称之为 Table_A

+----------+--------+--------------+--- -----+ |标识 | ATYPE | AVAL |团队 | +----------+--------+--------------+--- -----+ | -1534065 | 114 | IYSV 试用 EC 选择 | 3070 | | -1534065 | 108 |白色近交系 | 3070 | | -1534065 | 107 | 400 | 3070 | | -1534064 | 114 | IYSV 试用 EC 选择 | 3070 | | -1534064 | 108 |白色近交系 | 3070 | | -1534064 | 107 | 400 | 3070 | +----------+--------+--------------+--- -----+

我希望每个 GID 只有一行,每个适用的 ntype 和 atype 有一列,其中 methn = 60(表中还有 methn 的其他值)和 teamid = 3070。结果将如下所示:

+----------+--------+---------+----------+--------- ---+-----------+---------------+------------------ --------+ |标识 |甲基 | NTYPE_5 | NTYPE_18 | NTYPE_61 | ATYPE_107 | ATYPE_108 | ATYPE_114 | +----------+--------+---------+----------+--------- ---+-----------+---------------+------------------ --------+ | -1534064 | 60 |第659章1868 | 102-1095-1 | 400 |白色近交系 | IYSV 试用 EC 选择 | +----------+--------+---------+----------+--------- ---+-----------+---------------+------------------ --------+

谁能帮我为这些数据设计一个交叉表查询(或任何能给我想要结果的东西)?

【问题讨论】:

  • 在 Oracle 中称为 Pivot,但列数必须是确定的,否则您必须使用动态 SQL。堆栈上有几个例子......这是一个:stackoverflow.com/questions/16978047/… 并问汤姆说:asktom.oracle.com/pls/asktom/… 如果它们是确定性的,那么一个简单的枢轴就可以了,但是您必须对每个 Ntype 和 AType 值进行硬编码。

标签: sql oracle select crosstab


【解决方案1】:

使用 pivot 可以实现这一点,但您需要牢记 xQbert 提出的这些要点。

WITH g_table(GID, METHN, TEAMID) AS 
 (SELECT  1534063, 60, 3070 FROM dual UNION ALL
  select 1534064 ,    60 ,   3070 FROM dual UNION ALL
  select 1534065 ,    60 ,   3070 FROM dual UNION ALL
  select 1534061 ,    60 ,   3069 FROM dual UNION ALL
  select 1534062 ,    60 ,   3069 FROM dual UNION ALL
  select 1534060 ,    60 ,   3069 FROM dual),
n_table(GID, NTYPE, NVAL, TEAMID) AS (
  select 1534064 ,    61 , 102-1095-1 ,   3070 from dual UNION ALL
  select 1534064 ,    18 , 1868       ,   3070 from dual UNION ALL
  select 1534064 ,     5 , 659        ,   3070 from dual UNION ALL
  select 1520001 ,    61 , 103-1040-1 ,   3070 from dual UNION ALL
  select 1520001 ,    18 , 4285       ,   3070 from dual UNION ALL
  select 1520002 ,    61 , 103-1040-2 ,   3070  from dual),
a_table(GID, ATYPE, AVAL, TEAMID) AS (
  select 1534065 ,   114 , 'IYSV Trial EC Selections' ,   3070 from dual UNION ALL
  select 1534065 ,   108 , 'White Inbreds'            ,   3070 from dual UNION ALL
  select 1534065 ,   107 , '400'                      ,   3070 from dual UNION ALL
  select 1534064 ,   114 , 'IYSV Trial EC Selections' ,   3070 from dual UNION ALL
  select 1534064 ,   108 , 'White Inbreds'            ,   3070 from dual UNION ALL
  select 1534064 ,   107 , '400'                     ,   3070 from dual),
--------------------------
-- End of Data preparation
--------------------------
gn_table AS (
  SELECT g.gid, g.methn, n.nval, n.ntype 
    FROM g_table g
    JOIN n_table n ON n.gid = g.gid),
gn_pivot AS (
  select * FROM gn_table
   PIVOT (MIN(nval) AS nval FOR ntype IN (61, 18, 5))),
agn_table AS (
  SELECT a.gid, a.aval, a.atype, gn.methn, gn."61_NVAL", gn."18_NVAL",gn."5_NVAL"
    FROM a_table a JOIN gn_pivot gn ON gn.gid = a.gid)
  select * 
    FROM agn_table
   PIVOT (MIN(aval) aval FOR atype IN (107, 108, 114));

输出:

GID METHN   61_NVAL 18_NVAL 5_NVAL  107_AVAL    108_AVAL        114_AVAL
-----------------------------------------------------------------------------
1534064 60  -994    1868    659     400         White Inbreds   IYSV Trial EC Selections

【讨论】:

    【解决方案2】:

    您可以手动使用连接语句来执行此操作,我总是发现它比枢轴更容易使用——它在功能上是相同的。对于您的示例,它看起来像这样:

    SELECT G.GID, G.METHIN, 
          NT_5.NVAL AS NTYPE_5,
          NT_18.NVAL AS NTYPE_18,
          NT_61.NVAL AS NTYPE_61,
          AT_107.NVAL AS ATYPE_107,
          AT_108.NVAL AS ATYPE_108,
          AT_114.NVAL AS ATYPE_114
    FROM Table_G as G
    LEFT JOIN Table_N AS NT_5 ON G.GID = NT_5.GID AND NT_5.NTYPE = 5
    LEFT JOIN Table_N AS NT_18 ON G.GID = NT_18.GID AND NT_18.NTYPE = 18
    LEFT JOIN Table_N AS NT_61 ON G.GID = NT_61.GID AND NT_61.NTYPE = 61
    LEFT JOIN Table_A AS AT_107 ON G.GID = AT_107.GID AND AT_107.NTYPE = 107
    LEFT JOIN Table_A AS AT_108 ON G.GID = AT_108.GID AND AT_108.NTYPE = 108
    LEFT JOIN Table_A AS AT_114 ON G.GID = AT_114.GID AND AT_114.NTYPE = 114
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-04-29
      • 1970-01-01
      • 2013-06-11
      • 2011-06-09
      • 1970-01-01
      • 2018-06-27
      相关资源
      最近更新 更多