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.


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

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.


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)

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.


8

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

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

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


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

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


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.


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

0

W Oracle

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

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
;

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.


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

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;
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.