我正在使用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 | +----------+-------+---------+----------+------------+-----------+---------------+--------------------------+
任何人都可以帮我设计一个交叉表查询(或任何可以给我预期结果的数据)吗?
答案 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