Sql 在单行oracle中显示多行中的列
我从一个类似sql的数据库返回了数据Sql 在单行oracle中显示多行中的列,sql,oracle,Sql,Oracle,我从一个类似sql的数据库返回了数据 node_no code value1 order 100 AB 001 1 100 AB 007 2 101 AB 010 3 我必须使用sql进一步处理这些数据,以获得如下输出 node_no code value1 value2 100 AB 001 007 101 AB 010 null 要
node_no code value1 order
100 AB 001 1
100 AB 007 2
101 AB 010 3
我必须使用sql进一步处理这些数据,以获得如下输出
node_no code value1 value2
100 AB 001 007
101 AB 010 null
要求将两行或具有相同节点号的行中的列值显示为两个不同的列。
必须维持秩序
注意:这可能看起来像的副本
但在这里,我们将值显示为单个聚合列 试试这个:
with cte as
(select node_no, code, value1,
row_number() over (partition by node_no order by order) rn
from tbl)
select a.node_no, a.code, a.value1 x, b.value1 value2
from
cte a
left join cte b on a.node_no = b.node_no
and b.rn = 2
and a.rn = 1
where a.rn = 1
请注意,这假设value1字段是varchar2,因此,如果要执行标准词典以外的自定义排序,则需要在ORDERBY子句中自行实现
@MatBailie在下面的评论中建议的另一种解决方案消除了加入的需要,但仍然需要CTE:
SELECT node_no,
MAX(code) as code,
MAX(CASE WHEN rn=1 THEN value1 END) AS value1,
MAX(CASE WHEN rn=2 THEN value1 END) AS value2
FROM cte
GROUP BY node_no
Oracle的最新版本也支持PIVOT子句。但是,您仍然必须获得一个常量列标识符:
SELECT node_no, code, value1,
ROW_NUMBER() OVER(PARTITION BY node_no ORDER BY ordering) rn
FROM <table_name_here>)
此时,它将变成一个标准的PIVOT查询:
PIVOT需要一个聚合函数,但在这种情况下,我们没有任何东西可以聚合,所以
不过,我不确定这是否比现有答案更有效。您需要更清楚地定义所需的业务逻辑。例如,如何确定001列进入哪个列?是因为它比007小还是因为它的顺序值是最低的?如果一个节点有两个以上的值,应该怎么办?等等,等等,等等…它基于“顺序”字段,顺序。节点的值不会超过两个,后续问题最多只有1或2个Thx。您不需要使用连接。。。从cte GROUP BY node_no中选择node_no、MAXcode as code、MAXCASE WHEN rn=1、value1 END as value1、MAXCASE WHEN rn=2、value2 END as value2。这将减少读取次数和cpu周期数,无需处理两次数据。此外,通过在WHERE子句中使用b.rn=2,您已经破坏了左连接并将其转换为内部连接;因为如果它不存在于联接中,则该值将为NULL,它永远不等于2。@MatBailie您是对的,WHERE确实改变了其含义。我应该用你的建议编辑我的答案,还是像盗取你的信用?@MatBailie我的理解是,由于一个节点可以有两行,因此如果在输入中存在,那么rn=1的行必须始终存在于结果中。因此,连接指定了a.rn=1和b.rn=2,以及一个额外的where,其中仅获取每个节点的第一行。\u no。这有意义吗?如果按列进行分区,则ORDER BY子句不必包含该列。请随时从没有编写自己答案的人那里窃取信用:哇,因此,Oracle PIVOT语法与SQL Server几乎相同。我应该马上就试一下:D
node_no code value1 order rn
100 AB 001 1 1
100 AB 007 2 2
101 AB 010 3 1
SELECT node_no, code, value1, value2
FROM (SELECT node_no, code, value1,
ROW_NUMBER() OVER(PARTITION BY node_no ORDER BY ordering) rn
FROM Pivot_Example) Indexed
PIVOT (MAX(value1) FOR (rn) IN (1 AS value1, 2 AS value2))
ORDER BY node_no