定数で満たされた複数の行を選択するにはどうすればよいですか?


176

テーブルを参照せずに定数を選択することは、SQLステートメントでは完全に正当です。

SELECT 1, 2, 3

後者が返す結果セットは、値を含む単一の行です。定数式を使用して一度に複数の行を選択する方法があるかどうか疑問に思っていました。

SELECT ((1, 2, 3), (4, 5, 6), (7, 8, 9))

上記のように動作し、3行3列の結果セットを返すものが欲しいです。


1
上記の想像上の構文は、公式の構文よりもきれいです(そしてINSERT INTOとの一貫性があります)。言ってるだけ。
ピートアルビン

2
@PeteAlvin想像上の構文は既にPostgresで意味を持っています(タプルを持つ単一の行が選択されています)。
Kirill Bulygin 2018年

2
以下のSQLサーバーの回答はSQLサーバーで適切に機能し、この構文とほぼ一致します。 stackoverflow.com/a/53269562/2129481
BenPen

回答:


203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9

2
私はこれをSQL Serverで使用ASしましたが、機能しましたが、最初にエイリアスを指定するために使用しなければなりませんでしたSELECT
Sled

@ArtBに感謝します。このコメントは、他の開発者が正しい構文を取得するのに役立つ場合があります
Dewfy

3
また、Oracle APEX 5.1でClassic Report完全に機能しFROM dual、それぞれのSELECT値の後、UNION ALL存在する場合はその前に静的コンテンツを含むテーブルを作成します。
VELFR 2018

118

ではPostgreSQL、次のことができます。

SELECT  *
FROM    (
        VALUES
        (1, 2),
        (3, 4)
        ) AS q (col1, col2)

他のシステムでは、次のように使用しますUNION ALL

SELECT  1 AS col1, 2 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle
UNION ALL
SELECT  3 AS col1, 3 AS col2
-- FROM    dual
-- uncomment the line above if in Oracle

OracleSQL ServerそしてPostgreSQL、あなたはまた、行(外部変数で提供可能)任意の数のレコードを生成することができます。

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

Oracle

WITH    q (l) AS
        (
        SELECT  1
        UNION ALL
        SELECT  l + 1
        FROM    q
        WHERE   l < @n
        )
SELECT  l
FROM    q
-- OPTION (MAXRECURSION 0)
-- uncomment line above if @n >= 100

SQL Server

SELECT  l
FROM    generate_series(1, $n) l

の中でPostgreSQL


1
私が持っていた(少し異なる)質問に答えるための+1:SELECT 1Oracleでの実行方法(動作しSELECT 1 FROM Dualました)。
Aasmund Eldhuset、2012年

13

以下の裸のVALUESコマンドはPostgreSQLで私のために機能します:

VALUES (1,2,3), (4,5,6), (7,8,9)

1
T-SQLでも複数行の挿入句として機能します。最初にテーブル変数または一時テーブルに挿入することもできますが、複数のステップが必要です。
ブライアリー2016

12

次のようなOracleのconnect by句を試してください

select level,level+1,level+2 from dual connect by level <=3;

句による接続の詳細については、次のリンクを参照してください。oraclebinサイトが悪質なため、URLを削除しました。


8

Microsoft SQL ServerまたはPostgreSQLの場合、この構文を試すことをお勧めします

SELECT constants FROM (VALUES ('foo@gmail.com'), ('bar@gmail.com'), ('baz@gmail.com')) AS MyTable(constants)

ここでSQL Fiddleを表示することもできます。http://www.sqlfiddle.com/#!17 / 9eecb / 34703/0


1
これはSQL Server 2010で完全に機能します。複数の列も:SELECT constants、email FROM(VALUES(1、 'foo @ gmail.com')、(2、 'bar @ gmail.com')、(3、 'baz @ gmail .com '))AS MyTable(constants、email)
BenPen

7

オラクル。この投稿のおかげでPL / SQL-Where In句で「List」変数を使用

簡単に手動で値を入力するためのサンプルステートメントをまとめました(テスターに​​よるアプリケーションのテストで再利用されています)。

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods

1
これは命の恩人でした。注意点:値エラーが多すぎる場合は、WITH句でUNION ALLを実行できます。
ScrappyDev 2018


4

ここでは、きちんとしたXMLトリックを使用してOracle 10+に静的データを入力する方法を示します。

create table prop
(ID NUMBER,
 NAME varchar2(10),
 VAL varchar2(10),
 CREATED timestamp,
 CONSTRAINT PK_PROP PRIMARY KEY(ID)
);

merge into Prop p
using (
select 
  extractValue(value(r), '/R/ID') ID,
  extractValue(value(r), '/R/NAME') NAME,
  extractValue(value(r), '/R/VAL') VAL
from
(select xmltype('
<ROWSET>
   <R><ID>1</ID><NAME>key1</NAME><VAL>value1</VAL></R>
   <R><ID>2</ID><NAME>key2</NAME><VAL>value2</VAL></R>
   <R><ID>3</ID><NAME>key3</NAME><VAL>value3</VAL></R>
</ROWSET>
') xml from dual) input,
 table(xmlsequence(input.xml.extract('/ROWSET/R'))) r
) p_new
on (p.ID = p_new.ID)
when not matched then
insert
(ID, NAME, VAL, CREATED)
values
( p_new.ID, p_new.NAME, p_new.VAL, SYSTIMESTAMP );

マージでは、元のテーブルにない行のみが挿入されます。これは、挿入スクリプトを再実行する場合に便利です。


3

DB2のオプション:

SELECT 101 AS C1, 102 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 201 AS C1, 202 AS C2 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 301 AS C1, 302 AS C2 FROM SYSIBM.SYSDUMMY1


0

DB2のXML機能を使用してそれを行う方法は次のとおりです

SELECT *
FROM
XMLTABLE ('$doc/ROWSET/ROW' PASSING XMLPARSE ( DOCUMENT '
<ROWSET>
  <ROW>
    <A val="1" /> <B val="2" /> <C val="3" />
  </ROW>
  <ROW>
    <A val="4" /> <B val="5" /> <C val="6" />
  </ROW>
  <ROW>
    <A val="7" /> <B val="8" /> <C val="9" />
  </ROW>
</ROWSET>
') AS "doc"
   COLUMNS 
      "A" INT PATH 'A/@val',
      "B" INT PATH 'B/@val',
      "C" INT PATH 'C/@val'
) 
AS X
;

0

この方法はあなたを助けることができます

SELECT   TOP 3
         1 AS First, 
         2 AS Second, 
         3 AS Third 
FROM     Any_Table_In_Your_DataBase

Any_Table_In_Your_DataBase:4つ以上のレコードを含む任意のテーブル、または任意のシステムテーブルを使用します。ここでは、そのテーブルのデータは関係ありません。

列をAny_Table_In_Your_DataBaseテーブルの最初、2番目、3番目の列と連結することにより、結果セットにバリエーションをもたらすことができます。


使用するデータベースを指定する必要があります。「TOP」キーワードはOracleでは機能しません。
Hans Deragon 2017年

0

MySQLでは、次のことができます。 values (1,2), (3, 4);

mysql> values (1,2), (3, 4);
+---+---+
| 1 | 2 |
+---+---+
| 1 | 2 |
| 3 | 4 |
+---+---+
2 rows in set (0.004 sec)

MySQL 8では、列名を指定することもできます。

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+

1
「値(1,2)、(3、4);」で使用しているmysqlのバージョンは何ですか?
Rene Wooller、

その2番目の例は、実際にはまだ複数の行を選択していますか?また、どちらもPhpMyAdminでクエリとして実行できないようです。MySQLのどのバージョンを使用しているかを教えてください。ただし、MySQLのバージョンは非常に混乱しているので、理解するまでに確信があります。このコメントを編集するには時間外にしてください...
still_dreaming_1

0
select (level - 1) * row_dif + 1 as a, (level - 1) * row_dif + 2 as b, (level - 1) * row_dif + 3 as c
    from dual 
    connect by level <= number_of_rows;

そんな感じ

select (level - 1) * 3 + 1 as a, (level - 1) * 3 + 2 as b, (level - 1) * 3 + 3 as c
    from dual 
    connect by level <= 3;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.