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.