Jak wybrać wiele wierszy wypełnionych stałymi?

176

Wybieranie stałych bez odwoływania się do tabeli jest całkowicie dozwolone w instrukcji SQL:

SELECT 1, 2, 3

Zestaw wyników, który zwraca ten ostatni, to pojedynczy wiersz zawierający wartości. Zastanawiałem się, czy istnieje sposób na wybranie wielu wierszy naraz przy użyciu stałego wyrażenia, coś w rodzaju:

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

Chciałbym, aby coś takiego jak powyżej działało i zwracało zestaw wyników z 3 wierszami i 3 kolumnami.

Blagovest Buyukliev
źródło
1
Twoja wyobrażona powyżej składnia jest ładniejsza (i bardziej spójna z INSERT INTO) niż oficjalna składnia. Tylko mówię.
Pete Alvin
2
@PeteAlvin Wyobrażona składnia ma już znaczenie w Postgres (wybrany jest pojedynczy wiersz z krotką).
Kirill Bulygin
2
Poniższa odpowiedź serwera sql działa dobrze dla serwera sql i prawie pasuje do tej składni. stackoverflow.com/a/53269562/2129481
BenPen

Odpowiedzi:

203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
Dewfy
źródło
2
Użyłem tego z SQL Server i zadziałało, ale musiałem użyć ASdo podania aliasów na pierwszymSELECT
Sled
dziękuję @ArtB, ten komentarz może pomóc innym programistom uzyskać poprawną składnię
Dewfy
3
Działa również doskonale w Oracle APEX 5.1 do tworzenia Classic Reporttabel z zawartością statyczną, jeśli uzupełnia się je FROM dualpo każdej SELECTwartości i przed, UNION ALLjeśli jest obecny.
VELFR,
118

W PostgreSQLmożesz:

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

W innych systemach wystarczy użyć 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

W Oracle, SQL Serveri PostgreSQL, można również generować zestawów rekordów z dowolnej liczby wierszy (providable ze zmienną zewnętrzną):

SELECT  level
FROM    dual
CONNECT BY
        level <= :n

w 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

w SQL Server,

SELECT  l
FROM    generate_series(1, $n) l

w PostgreSQL.

Quassnoi
źródło
1
+1 za odpowiedź na (nieco inne) pytanie, które miałem: jak to zrobić SELECT 1w Oracle ( SELECT 1 FROM Dualdziałało).
Aasmund Eldhuset
13

Poniższe VALUESpolecenie działa dla mnie w PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)
Tregoreg
źródło
1
Działa również w T-SQL jako wielowierszowa klauzula wstawiania. Wstawienie najpierw do zmiennej tabeli lub tabeli tymczasowej może zadziałać, ale może to być wiele kroków.
brianary
12

Wypróbuj klauzulę connect by w oracle, coś w tym rodzaju

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

Aby uzyskać więcej informacji na temat klauzuli connect by, kliknij ten link: usunięto adres URL, ponieważ witryna oraclebin jest teraz złośliwa.

Sushant Butta
źródło
8

W przypadku Microsoft SQL Server lub PostgreSQL możesz wypróbować tę składnię

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

Możesz również wyświetlić SQL Fiddle tutaj: http://www.sqlfiddle.com/#!17/9eecb/34703/0

bigtunacan
źródło
1
To absolutnie działa w SQL Server 2010. Wiele kolumn też: stałe SELECT, email FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (stałe, e-mail)
BenPen
7

Wyrocznia. Dzięki temu wpisowi PL / SQL - Użyj zmiennej "List" w klauzuli Where In

Złożyłem moją przykładową instrukcję, aby łatwo ręcznie wprowadzić wartości (ponownie wykorzystane do testowania aplikacji przez testerów):

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods
Petr Szturc
źródło
1
To uratowało życie. Jedna uwaga: jeśli napotkałeś błąd zbyt wielu wartości, możesz po prostu wykonać UNION ALL w klauzuli WITH.
ScrappyDev
5
SELECT * 
FROM DUAL 
CONNECT BY ROWNUM <= 9;
grokster
źródło
4

Oto jak wypełniam dane statyczne w Oracle 10+ przy użyciu zgrabnej sztuczki XML.

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

Scalanie powoduje wstawienie tylko tych wierszy, których brakuje w oryginalnej tabeli, co jest wygodne, jeśli chcesz ponownie uruchomić skrypt wstawiania.

Nicholas Sushkin
źródło
3

Opcja dla 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
źródło
0

W Oracle

SELECT
  CASE
    WHEN level = 1
    THEN 'HI'
    WHEN level = 2
    THEN 'BYE'
  END TEST
FROM dual
  CONNECT BY level <= 2;
Mike Robert
źródło
0

Oto, jak to zrobić, korzystając z funkcji XML programu DB2

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
źródło
0

Ten sposób może ci pomóc

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

Any_Table_In_Your_DataBase:dowolna tabela zawierająca więcej niż 3 rekordy lub dowolna tabela systemowa. Tutaj nie martwimy się o dane z tej tabeli.

Możesz wprowadzić zmiany w zestawie wyników, łącząc kolumnę z pierwszą, drugą i trzecią kolumną Any_Table_In_Your_DataBasetabeli.

Lali
źródło
Należy określić, której bazy danych używasz. Słowo kluczowe „TOP” nie działa z Oracle.
Hans Deragon
0

W MySQL możesz: values (1,2), (3, 4);

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

W MySQL 8 można również nadać nazwy kolumn:

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
źródło
1
w jakiej wersji mysql korzystasz z "wartości (1,2), (3, 4);"?
Rene Wooller
Czy ten drugi przykład faktycznie nadal wybiera wiele wierszy? Żaden z nich nie wydaje się również działać jako zapytania w PhpMyAdmin .. Chciałbym móc powiedzieć, na której wersji MySQL jestem, ale wersje MySQL są tak zagmatwane i jestem pewien, że zanim to zrozumiem, nie ma czasu na edycję tego komentarza ...
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;

coś w tym stylu

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
źródło