Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在单行oracle中显示多行中的列_Sql_Oracle - Fatal编程技术网

Sql 在单行oracle中显示多行中的列

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 要

我从一个类似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
要求将两行或具有相同节点号的行中的列值显示为两个不同的列。 必须维持秩序

注意:这可能看起来像的副本

但在这里,我们将值显示为单个聚合列

试试这个:

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