Як вибрати кілька рядків, заповнених константами?


176

Вибір констант без посилання на таблицю є абсолютно законним у операторі SQL:

SELECT 1, 2, 3

Набір результатів, який повертає останній, - це один рядок, що містить значення. Мені було цікаво, чи є спосіб вибрати декілька рядків одночасно, використовуючи постійний вираз, щось таке:

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

Я хотів би щось подібне, що працює вище, і повертає набір результатів із 3 рядків та 3 стовпців.


1
Ваш уявлений синтаксис вище гарніший (і більше відповідає INSERT INTO), ніж офіційний синтаксис. Просто говорю.
Піт Елвін

2
@PeteAlvin Уявлений синтаксис вже має значення у Postgres (вибрано один рядок з кортежем).
Кирило Булигін

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

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

В Oracle,SQL 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 1в Oracle ( SELECT 1 FROM Dualпрацював).
Асмунд Елдхусет

13

Наступна гола VALUESкоманда працює для мене в PostgreSQL:

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

1
Працює і в T-SQL як багаторядковий пункт вставки. Вставлення в змінну таблиці або тимчасову таблицю спочатку може спрацювати, але кілька кроків.
бріанарі

12

Спробуйте підключити словосполучення в oracle, щось подібне

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

Для отримання додаткової інформації про підключення за пунктом перейдіть за цим посиланням: видалена URL-адреса, оскільки сайт oraclebin зараз шкідливий.


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 сервері 2010. Також декілька стовпців: SELECT константи, електронна пошта від (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (константи, електронна пошта)
BenPen

7

Oracle. Завдяки цій публікації PL / SQL - використовуйте змінну "Список", де в пункті

Я зібрав свій приклад заяви, щоб легко вводити значення вручну (повторно використовуватися при тестуванні програми тестерами):

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

1
Це було рятівником життя. Варто зазначити одне: якщо ви зіткнулися з надто великою помилкою значень, ви можете просто зробити UNION ALL в пункті WITH.
ScrappyDev


4

Ось як я заповнюю статичні дані в Oracle 10+ за допомогою акуратного трюку 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 );

Злиття вставляє лише ті рядки, які відсутні у вихідній таблиці, що зручно, якщо ви хочете повторно запустити сценарій вставки.


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

Ось як це зробити за допомогою XML-функцій 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

Цей спосіб може вам допомогти

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

Any_Table_In_Your_DataBase:будь-яку таблицю, яка містить більше 3 записів, або використовувати будь-яку системну таблицю. Тут ми не хвилюємось даними цієї таблиці.

Ви можете змінити набір результатів шляхом об'єднання стовпця з першим, другим та третім стовпцями з Any_Table_In_Your_DataBaseтаблиці.


Ви повинні вказати, яку базу даних ви використовуєте. Ключове слово "TOP" не працює з Oracle.
Ганс Дерагон

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
на якій версії mysql ви знаєте "значення (1,2), (3, 4);"
Рене Вуллер

Цей другий приклад насправді вибирає кілька рядків? Також жоден з них не здається виконаним як запити в PhpMyAdmin .. Я б хотів сказати вам, на якій версії MySQL я перебуваю, але версії MySQL настільки заплутані, і я впевнений, що до моменту з'ясування не
встигнете

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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.