[英]Single SQL SELECT Returning multiple rows from one table row
我们有一个表格,其形式为:
ID,Value1,Value2,Value3
1,2,3,4
我们需要将其转化为。
ID,Name,Value
1,'Value1',2
1,'Value2',3
1,'Value3',4
在一个SELECT语句中是否有一种聪明的方法(即没有UNION)? 列名称Value1,Value2和Value3是固定的且恒定的。
该数据库是oracle 9i。
给union
一个机会。
select ID, 'Value1' as Name, Value1 as Value from table_name union all
select ID, 'Value2', Value2 as Value from table_name union all
select ID, 'Value3', Value3 as Value from table_name
order by ID, Name
使用union all
意味着服务器将不执行distinct
(这是隐含在union
的操作)。 它不会对数据造成任何影响(因为您的ID应该很不同),但是可能会加快速度。
这适用于Oracle 10g:
select id, 'Value' || n as name,
case n when 1 then value1 when 2 then value2 when 3 then value3 end as value
from (select rownum n
from (select 1 from dual connect by level <= 3)) ofs, t
我认为Oracle 9i有递归查询吗? 无论如何,我非常确定它具有CASE支持,因此即使它没有递归查询,也可以执行“(从双联合中选择1,从双联合中选择2,从双联合中选择3,全部从双中选择3)”代替。 对于Oracle,滥用递归查询会更普遍一些。 (不过,使用联合生成行可移植到其他数据库中)
您可以像这样进行操作,但效果并不理想:
SELECT id,'Value 1' AS name,value1 AS value FROM mytable
UNION
SELECT id,'Value 2' AS name,value2 AS value FROM mytable
UNION
SELECT id,'Value 3' AS name,value3 AS value FROM mytable
合并三个选择语句应该可以解决问题:
SELECT ID, 'Value1', Value1 AS Value
FROM TABLE
UNION
SELECT ID, 'Value2', Value2 AS Value
FROM TABLE
UNION
SELECT ID, 'Value3', Value3 AS Value
FROM TABLE
对于Oracle(我在Teradata中运行过),CTE语法可能有所不同,但是我仅使用CTE提供测试数据,即1 2 3和4。可以使用临时表代替。 实际的select语句是普通的香草SQL,它将在任何关系数据库上使用。
如果您使用的是SQL Server 2005+,则可以使用UNPIVOT
CREATE TABLE #tmp ( ID int, Value1 int, Value2 int, Value3 int)
INSERT INTO #tmp (ID, Value1, Value2, Value3) VALUES (1, 2, 3, 4)
SELECT
*
FROM
#tmp
SELECT
*
FROM
#tmp
UNPIVOT
(
[Value] FOR [Name] IN (Value1, Value2, Value3)
) uPIVOT
DROP TABLE #tmp
正如其他人所建议的,UNION ALL可能是您在SQL中最好的选择。 您可能还需要考虑根据自己的特定要求在前端进行处理。
尝试这个:
CTE创建具有4个值的临时表。 您可以在任何数据库中按原样运行它。
with TEST_CTE (ID) as
(select * from (select '1' as a) as aa union all
select * from (select '2' as b) as bb union all
select * from (select '3' as c) as cc union all
select * from (select '4' as d) as dd )
select a.ID, 'Value'|| a.ID, b.ID
from TEST_CTE a, TEST_CTE b
where b.ID = (select min(c.ID) from TEST_CTE c where c.ID > a.ID)
这是结果集:
1 Value1 2
2 Value2 3
3 Value3 4
请享用!
一些事后思考。
^^^ CTE语法在Oracle中可能有所不同。 我只能在Teradata中运行它。 您可以将其替换为临时表,也可以修复语法以使其与Oracle兼容。 select语句是普通香草SQL,可在任何数据库上使用。
^^^注意的另一件事。 如果ID字段是数字字段,则可能需要将其强制转换为CHAR,以便将其与“ Value”连接。
对于Sql Server,请考虑将UNPIVOT替代UNION:
SELECT id, value, colname
FROM #temp t
UNPIVOT (Value FOR ColName IN (value1,value2,value3)) as X
这也将返回列名称。 我不确定X的用途,但是您不能忽略它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.