วิธีการเลือกหลายแถวที่เต็มไปด้วยค่าคงที่?


176

การเลือกค่าคงที่โดยไม่อ้างอิงตารางนั้นถูกต้องตามกฎหมายในคำสั่ง SQL:

SELECT 1, 2, 3

ชุดผลลัพธ์ที่ส่งคืนหลังคือแถวเดียวที่มีค่า ฉันสงสัยว่าถ้ามีวิธีการเลือกหลายแถวพร้อมกันโดยใช้นิพจน์คงที่สิ่งที่ชนิดของ:

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

ฉันต้องการอะไรข้างต้นที่ใช้งานได้และส่งคืนชุดผลลัพธ์ที่มี 3 แถวและ 3 คอลัมน์


1
ไวยากรณ์ที่คุณจินตนาการไว้ด้านบนนั้นดีกว่า (และสอดคล้องกับ INSERT INTO) มากกว่าไวยากรณ์ที่เป็นทางการ แค่พูดว่า
Pete Alvin

2
@PeteAlvin ไวยากรณ์ที่จินตนาการมีความหมายใน Postgres แล้ว (เลือกแถวเดียวที่มี tuple)
Kirill Bulygin

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
เลื่อน

ขอบคุณ @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คุณยังสามารถสร้างระเบียนของจำนวนข้อของแถว (providable กับตัวแปรภายนอก):

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คำสั่งbare ใช้งานได้สำหรับฉันใน 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 หลาย ๆ คอลัมน์เช่นกัน: ค่าคงที่เลือก, อีเมลจาก (ค่า (1, 'foo @ gmail.com'), (2, 'bar @ gmail.com'), (3, 'baz @ gmail .com ')) AS MyTable (ค่าคงที่อีเมล)
BenPen

7

คำพยากรณ์ ขอบคุณที่โพสต์นี้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
Hans Deragon

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);"?
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;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.