Как выбрать несколько строк, заполненных константами?

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 Server ниже работает хорошо для сервера SQL, и почти соответствует этому синтаксису. stackoverflow.com/a/53269562/2129481
BenPen

Ответы:

203
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
Dewfy
источник
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.

Quassnoi
источник
1
+1 за ответ на (немного другой) вопрос, который у меня был: как это сделать SELECT 1в Oracle ( SELECT 1 FROM Dualсработало).
Aasmund Eldhuset
13

Следующая VALUESкоманда работает в PostgreSQL:

VALUES (1,2,3), (4,5,6), (7,8,9)
Tregoreg
источник
1
Работает в T-SQL как многострочный оператор вставки. Вставка в переменную таблицы или временную таблицу сначала может работать, но в несколько этапов.
brianary
12

Попробуй пункт connect by в оракуле, как то так

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

bigtunacan
источник
1
Это абсолютно работает в SQL Server 2010. Также несколько столбцов: SELECT константы, электронная почта FROM (VALUES (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (константы, электронная почта)
BenPen
7

Oracle. Благодаря этому посту PL / SQL - используйте переменную «List» в пункте Where In

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

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

В Oracle

SELECT
  CASE
    WHEN level = 1
    THEN 'HI'
    WHEN level = 2
    THEN 'BYE'
  END TEST
FROM dual
  CONNECT BY level <= 2;
Майк Роберт
источник
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
;
Stavr00
источник
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 вы используете "values ​​(1,2), (3, 4);"?
Рене
Этот второй пример на самом деле все еще выбирает несколько строк? Кроме того, ни один из них, кажется, не работает в качестве запросов в PhpMyAdmin .. Я хотел бы сказать вам, на какой версии MySQL я работаю, но версии MySQL настолько сбивают с толку, и я уверен, что к тому времени, когда я это выясню, я буду не успел отредактировать этот комментарий ...
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;

что-то такое

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
источник