简体   繁体   中英

SQL Join select statements for multiple columns

I am using TOAD 9.7 to work in an oracle database.

I have three tables I am selecting data from. The three tables share a unique ID, called 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. 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

Here an example of data from the first table, we'll call it 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

+----------+-------+------------+--------+
|   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

+----------+-------+--------------------------+--------+
|   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    | 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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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