如何选择多行填充常量?


174

选择常量而不引用表在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 server效果很好,并且几乎与此语法匹配。 stackoverflow.com/a/53269562/2129481
BenPen

Answers:


201
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
Classic Report如果用FROM dualafter SELECT,after 值和before之前的值完成,还可以在Oracle APEX 5.1中完美地创建具有静态内容的表UNION ALL
VELFR

117

在中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

OracleSQL 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有效)。
2012年

12

VALUES在PostgreSQL中,执行以下裸命令即可:

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

1
在T-SQL中也可以作为多行插入子句使用。首先可以插入表变量或临时表,但可以执行多个步骤。
brianary

11

尝试在oracle中使用connect by子句,类似这样

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

有关connect by子句的更多信息,请单击以下链接:删除的URL,因为oraclebin网站现在是恶意的。


7

对于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常量,通过电子邮件从(VALUES(1,'foo @ gmail.com'),(2,'bar @ gmail.com'),(3,'baz @ gmail .com'))AS MyTable(constants,email)
BenPen

6

甲骨文 感谢这篇文章PL / SQL-在“子句中的位置”中使用“列表”变量

我将示例语句放在一起,以轻松地手动输入值(在测试人员对应用程序进行测试时可以重复使用):

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

1
这是救生员。需要注意的一件事:如果遇到太多的值错误,则可以在WITH子句中执行UNION ALL。
ScrappyDev


4

这是我使用整洁的XML技巧在Oracle 10+中填充静态数据的方法。

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

在甲骨文

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

0

这是使用DB2的XML功能来实现的

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
您针对“值(1,2),(3、4);”使用什么版本的mysql?
Rene Wooller,

第二个示例实际上是否仍在选择多行?另外,它们似乎都无法在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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.