简体   繁体   English

多列的SQL Join选择语句

[英]SQL Join select statements for multiple columns

I am using TOAD 9.7 to work in an oracle database. 我正在使用TOAD 9.7在oracle数据库中工作。

I have three tables I am selecting data from. 我有三个表,我正在从中选择数据。 The three tables share a unique ID, called GID. 这三个表共享唯一的ID,称为GID。

I want to select data from all three tables where certain criteria are met, then join the select statements so that there are multiple columns, instead of multiple rows with the same unique ID. 我想从满足特定条件的所有三个表中选择数据,然后加入select语句,以便有多个列,而不是具有相同唯一ID的多个行。 But, I don't want to simply JOIN multiple select statements. 但是,我不想简单地加入多个选择语句。 I believe what I am looking for is a cross-tab query, as I want only one row per unique id, with column headers for each ntype and atype 我相信我正在寻找的是交叉表查询,因为每个唯一的ID我只希望一行,每个ntype和atype都有列标题

Here an example of data from the first table, we'll call it Table_G. 这是第一个表中数据的示例,我们将其称为Table_G。

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

And here an example of the second table, we'll call it Table_N 这是第二个表的示例,我们将其称为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 |
+----------+-------+------------+--------+

And finally the third table, which is very similar to the second table, but with atype and aval instead of ntype and nval--we'll call it Table_A 最后是第三个表,它与第二个表非常相似,但是使用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 |
+----------+-------+--------------------------+--------+

I want to to have only one row for each GID, with a column for each applicable ntype and atype, where the methn = 60 (there are other values for methn in the table) and the teamid = 3070. The result would be something like below: 我希望每个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 |
+----------+-------+---------+----------+------------+-----------+---------------+--------------------------+

Can anyone help me to design a cross-tab query (or anything that would give me the desired result) for this data? 谁能帮助我为该数据设计一个交叉表查询(或任何可以给我所需结果的东西)?

You can do this with join statements by hand which I always find easier to work with than pivots -- it is functionally the same. 您可以使用手工连接语句来完成此任务,与枢轴相比,我总是发现使用它比使用枢轴更容易-它在功能上是相同的。 For your example it would look like this: 对于您的示例,它看起来像这样:

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

Using pivot, this can be achieved, but you need to keep those points raised by xQbert in mind. 使用数据透视,可以实现这一点,但是您需要牢记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));

Output: 输出:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM