Wie wähle ich mehrere mit Konstanten gefüllte Zeilen aus?

175

Das Auswählen von Konstanten ohne Bezugnahme auf eine Tabelle ist in einer SQL-Anweisung völlig legal:

SELECT 1, 2, 3

Die Ergebnismenge, die letztere zurückgibt, ist eine einzelne Zeile, die die Werte enthält. Ich habe mich gefragt, ob es eine Möglichkeit gibt, mehrere Zeilen gleichzeitig mit einem konstanten Ausdruck auszuwählen.

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

Ich möchte so etwas wie das Obige, das funktioniert und eine Ergebnismenge mit 3 Zeilen und 3 Spalten zurückgibt.

Blagovest Buyukliev
quelle
1
Ihre oben beschriebene Syntax ist hübscher (und konsistenter mit INSERT INTO) als die offizielle Syntax. Ich sag bloß.
Pete Alvin
2
@PeteAlvin Die imaginäre Syntax hat in Postgres bereits eine Bedeutung (eine einzelne Zeile mit einem Tupel ist ausgewählt).
Kirill Bulygin
2
Die folgende Antwort auf den SQL Server funktioniert gut für den SQL Server und entspricht fast dieser Syntax. stackoverflow.com/a/53269562/2129481
BenPen

Antworten:

202
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
Dewfy
quelle
2
Ich habe dies mit SQL Server verwendet und es hat funktioniert, aber ich musste verwenden AS, um Aliase auf dem erstenSELECT
Schlitten
danke @ArtB, dieser Kommentar kann anderen Entwicklern helfen, die richtige Syntax zu erhalten
Dewfy
3
Funktioniert auch perfekt in Oracle APEX 5.1, um Classic ReportTabellen mit statischem Inhalt zu erstellen , wenn diese FROM dualnach jedem SELECTWert und vor, UNION ALLfalls vorhanden, abgeschlossen sind.
VELFR
118

In PostgreSQLkönnen Sie tun:

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

In anderen Systemen einfach verwenden 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

In Oracle,SQL Server und PostgreSQLSie können auch Cord - Sets von beliebiger Anzahl von Zeilen (vorsehbar mit einer externen Variablen) erzeugen:

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

im 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

im SQL Server ,

SELECT  l
FROM    generate_series(1, $n) l

in PostgreSQL.

Quassnoi
quelle
1
1 die (etwas andere) Frage zu beantworten hatte ich: wie zu tun ist SELECT 1in Oracle ( SELECT 1 FROM Dualgearbeitet).
Aasmund Eldhuset
13

Der folgende bloße VALUESBefehl funktioniert für mich in PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)
Tregoreg
quelle
1
Funktioniert in T-SQL auch als mehrzeilige Einfügungsklausel. Das Einfügen in eine Tabellenvariable oder eine temporäre Tabelle könnte zuerst funktionieren, jedoch in mehreren Schritten.
Brian
12

Versuchen Sie die connect by-Klausel in oracle, so etwas

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

Weitere Informationen zur Connect by-Klausel finden Sie unter folgendem Link: URL entfernt, da die oraclebin-Site jetzt bösartig ist.

Sushant Butta
quelle
8

Für Microsoft SQL Server oder PostgreSQL möchten Sie möglicherweise diese Syntax ausprobieren

SELECT constants FROM (VALUES ('[email protected]'), ('[email protected]'), ('[email protected]')) AS MyTable(constants)

Sie können eine SQL-Geige auch hier anzeigen: http://www.sqlfiddle.com/#!17/9eecb/34703/0

Bigtunacan
quelle
1
Dies funktioniert auch in SQL Server 2010. Auch in mehreren Spalten: SELECT-Konstanten, E-Mail FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (Konstanten, E-Mail)
BenPen
7

Orakel. Dank dieses Beitrags PL / SQL - Verwenden Sie die Variable "List" in Where In Clause

Ich habe meine Beispielanweisung zusammengestellt, um Werte einfach manuell einzugeben (sie werden beim Testen einer Anwendung durch Tester wiederverwendet):

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods
Petr Szturc
quelle
1
Dies war ein Lebensretter. Eine Sache zu beachten: Wenn Sie auf einen Fehler mit zu vielen Werten gestoßen sind, können Sie einfach eine UNION ALL in der WITH-Klausel ausführen.
ScrappyDev
5
SELECT * 
FROM DUAL 
CONNECT BY ROWNUM <= 9;
Grokster
quelle
4

So fülle ich statische Daten in Oracle 10+ mit einem sauberen XML-Trick.

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 );

Beim Zusammenführen werden nur die Zeilen eingefügt, die in der Originaltabelle fehlen. Dies ist praktisch, wenn Sie Ihr Einfügeskript erneut ausführen möchten.

Nicholas Sushkin
quelle
3

Eine Option für 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
Vitaliy Ulantikov
quelle
0

In Oracle

SELECT
  CASE
    WHEN level = 1
    THEN 'HI'
    WHEN level = 2
    THEN 'BYE'
  END TEST
FROM dual
  CONNECT BY level <= 2;
Mike Robert
quelle
0

Hier erfahren Sie, wie Sie die XML-Funktionen von DB2 verwenden

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
;
Stavr00
quelle
0

Dieser Weg kann Ihnen helfen

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

Any_Table_In_Your_DataBase:Jede Tabelle, die mehr als 3 Datensätze enthält, oder jede Systemtabelle. Hier haben wir keine Bedenken hinsichtlich der Daten dieser Tabelle.

Sie können Variationen in der Ergebnismenge einbringen, indem Sie eine Spalte mit der ersten, zweiten und dritten Spalte aus der Any_Table_In_Your_DataBaseTabelle verketten .

Lali
quelle
Sie sollten angeben, welche Datenbank Sie verwenden. Das Schlüsselwort 'TOP' funktioniert nicht mit Oracle.
Hans Deragon
0

In MySQL können Sie Folgendes tun: values (1,2), (3, 4);

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

Mit MySQL 8 ist es auch möglich, die Spaltennamen anzugeben:

mysql> SELECT * FROM (SELECT 1, 2, 3, 4) AS dt (a, b, c, d);
+---+---+---+---+
| a | b | c | d |
+---+---+---+---+
| 1 | 2 | 3 | 4 |
+---+---+---+---+
Benedikt Köppel
quelle
1
Welche Version von MySQL verwenden Sie für "Werte (1,2), (3, 4);"?
Rene Wooller
Wählt dieses zweite Beispiel tatsächlich noch mehrere Zeilen aus? Außerdem scheint keine von beiden als Abfragen in PhpMyAdmin ausgeführt werden zu können. Ich wünschte, ich könnte Ihnen sagen, auf welcher MySQL-Version ich mich befinde, aber MySQL-Versionen sind so verwirrend, und ich bin mir sicher, dass ich es tun werde, wenn ich es herausfinde Sie haben keine Zeit mehr, diesen Kommentar zu bearbeiten ...
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;

sowas in der Art

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;
Dejoto
quelle