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.


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

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.


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)

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.


8

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

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

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


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

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


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.


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

0

In Oracle

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

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
;

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 .


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 |
+---+---+---+---+

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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.