Как выбрать несколько строк, заполненных константами? - PullRequest
139 голосов
/ 04 февраля 2010

Выбор констант без обращения к таблице совершенно допустим в выражении SQL:

SELECT 1, 2, 3

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

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

Я бы хотел что-то подобное, что работает и возвращает набор результатов с 3 строками и 3 столбцами.

Ответы [ 14 ]

167 голосов
/ 04 февраля 2010
SELECT 1, 2, 3
UNION ALL SELECT 4, 5, 6
UNION ALL SELECT 7, 8, 9
102 голосов
/ 04 февраля 2010

В 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.

11 голосов
/ 28 декабря 2013

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

VALUES (1,2,3), (4,5,6), (7,8,9)
11 голосов
/ 05 января 2013

Попробуй пункт connect by в oracle, как-то так

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

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

4 голосов
/ 05 апреля 2018

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

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

WITH prods AS (
    SELECT column_value AS prods_code 
    FROM TABLE(
        sys.odcivarchar2list(
            'prod1', 
            'prod2'
        )
    )
)
SELECT * FROM prods
4 голосов
/ 24 мая 2013
SELECT * 
FROM DUAL 
CONNECT BY ROWNUM <= 9;
4 голосов
/ 23 июня 2011

Вот как я заполняю статические данные в 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 голосов
/ 12 ноября 2018

Для Microsoft SQL Server вы можете попробовать этот синтаксис

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

1 голос
/ 20 февраля 2017

Опция для 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 голосов
/ 01 июля 2019
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;
...