1つの表の行から複数の行を返す単一のSQL SELECT
質問
私たちは、形のあるテーブルを持っています:
ID,Value1,Value2,Value3
1,2,3,4
私たちは、にこれを変換する必要があります。
ID,Name,Value
1,'Value1',2
1,'Value2',3
1,'Value3',4
(すなわちのUNIONなし)1つのSELECT文でこれを行うの巧妙な方法はありますか?列名値1、値2とVALUE3を固定し、一定である。
データベースは、Oracle 9iのである。
解決
このは、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をサポートしているかなり確信しているので、それは再帰的な問い合わせを持っていない場合でも、あなただけ行うことができます代わりに「OFS(すべてはデュアルから3を選択したすべてのデュアル組合から2を選択するデュアル組合から1を選択)」。再帰クエリを乱用することは、もう少し一般 - Oracleのです。 (行を生成するために組合を使用したけれども、他のDBにポータブルである)
他のヒント
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のは、うまくいけば、異なっている必要がありますので)これは、データとの違いを作るべきではありませんが、それは少しそれをスピードアップすることがあります。
あなたはこのようにそれを行うことができますが、それはかなりありません。
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
合併する3つのselect文は、トリックを行う必要があります:
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
は、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
A UNION ALL、他の人が示唆しているとして、おそらくSQLのあなたの最善の策です。また、あなたの特定の要件が何であるかに応じて、フロントエンドでこれを取り扱いを検討する必要があります。
CTE構文は(私がTeradataの中でそれを実行した)Oracleの異なる場合がありますが、私はのみ1 2 3と4あなたが代わりに一時テーブルを使用することができ、テストデータを提供するために、CTEを使用しました。実際のselect文は、プレーンバニラSQLであり、それはすべてのリレーショナル・データベースになります。
SQL Serverの場合、UNIONの代替としてUNPIVOTを検討します:
SELECT id, value, colname
FROM #temp t
UNPIVOT (Value FOR ColName IN (value1,value2,value3)) as X
これは、同様に、列名を返します。私はXがために使用されているものをわからないんだけど、あなたはそれを残すことはできません。
これを試してください:
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にそれをキャストする必要があるかもしれません。