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


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

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сработало).
Aasmund Eldhuset

13

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

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

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


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

Объединение вставляет только те строки, которые отсутствуют в исходной таблице, что удобно, если вы хотите перезапустить сценарий вставки.




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 вы используете "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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.