SQL连接多列的select语句

时间:2014-12-16 20:47:07

标签: sql oracle select crosstab

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

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

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

这是第一个表格中的数据示例,我们称之为Table_G。

+----------+-------+--------+
|   GID    | METHN | TEAMID |
+----------+-------+--------+
| -1534063 |    60 |   3070 |
| -1534064 |    60 |   3070 |
| -1534065 |    60 |   3070 |
| -1534061 |    60 |   3069 |
| -1534062 |    60 |   3069 |
| -1534060 |    60 |   3069 |
+----------+-------+--------+

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

+----------+-------+------------+--------+
|   GID    | NTYPE |    NVAL    | TEAMID |
+----------+-------+------------+--------+
| -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

+----------+-------+--------------------------+--------+
|   GID    | ATYPE |           AVAL           | TEAMID |
+----------+-------+--------------------------+--------+
| -1534065 |   114 | IYSV Trial EC Selections |   3070 |
| -1534065 |   108 | White Inbreds            |   3070 |
| -1534065 |   107 | 400                      |   3070 |
| -1534064 |   114 | IYSV Trial EC Selections |   3070 |
| -1534064 |   108 | White Inbreds            |   3070 |
| -1534064 |   107 | 400                      |   3070 |
+----------+-------+--------------------------+--------+

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

+----------+-------+---------+----------+------------+-----------+---------------+--------------------------+
|   GID    | METHN | NTYPE_5 | NTYPE_18 |  NTYPE_61  | ATYPE_107 |   ATYPE_108   |        ATYPE_114         |
+----------+-------+---------+----------+------------+-----------+---------------+--------------------------+
| -1534064 |    60 |     659 |     1868 | 102-1095-1 |       400 | White Inbreds | IYSV Trial EC Selections |
+----------+-------+---------+----------+------------+-----------+---------------+--------------------------+

任何人都可以帮我设计一个交叉表查询(或任何可以给我预期结果的数据)吗?

2 个答案:

答案 0 :(得分:0)

你可以用手工连接语句来做到这一点,我总是觉得它比枢轴更容易使用 - 它在功能上是相同的。对于您的示例,它看起来像这样:

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

答案 1 :(得分:0)

使用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