CHỌN từ không có gì?


90

Có thể có một tuyên bố như

SELECT "Hello world"
WHERE 1 = 1

trong SQL?

Điều chính tôi muốn biết, là tôi có thể CHỌN từ hư không, tức là không có mệnh đề TỪ.


3
Nhìn vào nhận xét của bạn trên @Rafael Belliard, bạn có thể nên hỏi bạn thực sự muốn làm gì. Bạn có muốn trả về một số chuỗi nếu các giá trị tồn tại cho một bảng nhất định chẳng hạn?
Jim L

Vâng, đó thực sự là những gì tôi muốn. Tôi biết rằng tôi có thể làm điều đó, tôi đã tự hỏi liệu tôi có cần một FROM NULLgiữa SELECTWHERE. Các cụm từ bị che khuất chủ yếu vì đó là bài tập về nhà và tôi không muốn ai đó đến và nói cho tôi câu trả lời nếu cảm giác ruột của tôi là sai.
Ritwik Bose

Câu trả lời:


140

Nó không nhất quán giữa các nhà cung cấp - Oracle, MySQL và DB2 hỗ trợ kép:

SELECT 'Hello world'
  FROM DUAL

... trong khi SQL Server, PostgreSQL và SQLite không yêu cầu FROM DUAL:

SELECT 'Hello world'

MySQL hỗ trợ cả hai cách.


2
Tôi luôn tự hỏi. Tại sao lại chọn thuật ngữ kép cho bảng ma?
Alex Blakemore, 17/09/10

5
@Alex: "Bảng KÉP ban đầu có hai hàng trong đó (do đó có tên như vậy), nhưng sau đó nó chỉ có một hàng."
nổi dậy

7
Trên DB2 kép được gọi là 'sysibm.sysdummy1'
Danubian Thủy thủ

1
Trên Postgresql, có thể tạo một bảng giả được gọi DUALvà thực hiện các truy vấn từ một bảng giống như ảo.
Stephan

1
@AlexBlakemore "Tôi đã tạo bảng KÉP làm đối tượng cơ bản trong Từ điển Dữ liệu Oracle. Nó không bao giờ có ý nghĩa để được nhìn thấy chính nó, mà thay vào đó được sử dụng bên trong một chế độ xem dự kiến ​​sẽ được truy vấn. Ý tưởng là bạn có thể thực hiện một JOIN để bảng DUAL và tạo hai hàng trong kết quả cho mỗi một hàng trong bảng của bạn. Sau đó, bằng cách sử dụng GROUP BY, phép nối kết quả có thể được tóm tắt để hiển thị dung lượng lưu trữ cho phạm vi DỮ LIỆU và cho (các) phạm vi INDEX. Tên, DUAL, dường như phù hợp với quá trình tạo một cặp hàng chỉ từ một hàng "( en.wikipedia.org/wiki/DUAL_table )
Nhấp vào Ok


14

Thử đi.

Độc thân:

SELECT *  FROM (VALUES ('Hello world')) t1 (col1) WHERE 1 = 1

Đa:

SELECT *  FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1

chi tiết hơn tại đây: http://modern-sql.com/use-case/select-without-from


1
Câu trả lời tuân thủ ANSI SQL duy nhất! (Đối với một câu hỏi không có dbms được chỉ định.)
jarlh

Mục đích là WHERE 1 = 1gì? Trên PostgreSQL hoạt động mà không có nó. Hay nó liên quan đến DMBS khác?
Frankie Drake

Chỉ là SELECT * FROM (VALUES ("Hello world")) t1 (col1)vẫn ổn. Wherechỉ cần trả lời cho câu hỏi này.
chuongtv

@chuongtv Bạn chọn nhiều hàng như thế nào?
Hector

@Hector Chỉ cần làm theo cách chèn cấu trúc của SQL. như thế nàySELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv

8

Đây là danh sách đầy đủ nhất về hỗ trợ cơ sở dữ liệu kép từ https://blog.jooq.org/tag/dual-table/ :

Trong nhiều RDBMS khác, không cần bảng giả, vì bạn có thể đưa ra các câu lệnh như sau:

SELECT 1;
SELECT 1 + 1;
SELECT SQRT(2);

Đây là các RDBMS, trong đó các điều trên thường có thể thực hiện được:

  • H2
  • MySQL
  • Ingres
  • Postgres
  • SQLite
  • Máy chủ SQL
  • Sybase ASE

Trong các RDBMS khác, cần có bảng giả, giống như trong Oracle. Do đó, bạn sẽ cần viết những thứ như sau:

SELECT 1       FROM DUAL;
SELECT 1 + 1   FROM DUAL;
SELECT SQRT(2) FROM DUAL;

Đây là RDBMS và các bảng giả tương ứng của chúng:

  • DB2: SYSIBM.DUAL
  • Derby: SYSIBM.SYSDUMMY1
  • H2: Tùy chọn hỗ trợ DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: Tùy chọn hỗ trợ DUAL
  • Oracle: KÉP
  • Sybase SQL mọi nơi: SYS.DUMMY

Ingres không có KÉP, nhưng thực sự sẽ cần nó vì trong Ingres bạn không thể có mệnh đề WHERE, GROUP BY hoặc HAVING mà không có mệnh đề FROM.


6

Trong kiểu SQL Server:

Select 'Your Text'

Không cần mệnh đề FROMhoặc WHERE.


5

Bạn có thể. Tôi đang sử dụng các dòng sau trong truy vấn StackExchange Data Explorer :

SELECT
(SELECT COUNT(*) FROM VotesOnPosts WHERE VoteTypeName = 'UpMod' AND UserId = @UserID AND PostTypeId = 2) AS TotalUpVotes,
(SELECT COUNT(*) FROM Answers WHERE UserId = @UserID) AS TotalAnswers

Data Exchange sử dụng Transact-SQL (phần mở rộng độc quyền của SQL Server cho SQL).

Bạn có thể tự mình thử bằng cách chạy một truy vấn như:

SELECT 'Hello world'

Data Exchange là Azure, dựa trên SQL Server.
OMG Ponies

2

Tôi nghĩ rằng điều đó là không thể. Về mặt lý thuyết: select thực hiện hai loại:

  • thu hẹp / mở rộng tập hợp (lý thuyết tập hợp);

  • ánh xạ kết quả.

Mệnh đề đầu tiên có thể được coi là giảm dần theo chiều ngang đối lập với mệnh đề where-có thể được coi là giảm dần theo chiều dọc. Mặt khác, một phép nối có thể tăng cường tập hợp theo chiều ngang trong đó một liên kết có thể tăng cường tập hợp theo chiều dọc.

               augmentation          diminishing
horizontal     join/select              select   
vertical          union            where/inner-join

Cái thứ hai là một ánh xạ. Một ánh xạ, là một công cụ chuyển đổi. Trong SQL, nó nhận một số trường và trả về không hoặc nhiều trường. Trong vùng chọn, bạn có thể sử dụng một số hàm tổng hợp như, sum, avg, v.v. Hoặc lấy tất cả các giá trị cột để chuyển đổi chúng thành chuỗi. Trong C # linq, chúng ta nói rằng một vùng chọn chấp nhận một đối tượng kiểu T và trả về một đối tượng kiểu U.

Tôi nghĩ rằng sự nhầm lẫn đến bởi thực tế là bạn có thể làm: select 'howdy' from <table_name>. Tính năng này là ánh xạ, phần chuyển đổi của lựa chọn. Bạn không in thứ gì đó, mà là chuyển đổi! Trong ví dụ của bạn:

SELECT "
WHERE 1 = 1

bạn đang chuyển đổi nothing / null thành "Hello world"và bạn thu hẹp tập hợp của bảng nothing / no thành một hàng, điều này không có ý nghĩa gì cả.

Bạn có thể nhận thấy rằng, nếu bạn không giới hạn số lượng cột, "Hello world"sẽ được in cho mỗi hàng có sẵn trong bảng. Tôi hy vọng, bạn hiểu tại sao bây giờ. Chọn của bạn mất gì từ các cột có sẵn và tạo ra một cột với nội dung: "Hello world".

Vì vậy, câu trả lời của tôi là KHÔNG. Bạn không thể bỏ qua mệnh đề from vì lựa chọn luôn cần các cột bảng để thực hiện.


2

Trong SQL tiêu chuẩn, không. Một WHEREmệnh đề ngụ ý một biểu thức bảng.

Từ thông số SQL-92:

7.6 "mệnh đề where"

Chức năng

Chỉ định một bảng có nguồn gốc từ việc áp dụng "điều kiện tìm kiếm" cho kết quả của mệnh đề "from" trước đó.

Lần lượt:

7.4 "từ mệnh đề"

Chức năng

Chỉ định một bảng dẫn xuất từ ​​một hoặc nhiều bảng được đặt tên.

Một cách tiêu chuẩn để làm điều đó (tức là sẽ hoạt động trên bất kỳ sản phẩm SQL nào):

SELECT DISTINCT 'Hello world' AS new_value
  FROM AnyTableWithOneOrMoreRows
 WHERE 1 = 1;

... giả sử bạn muốn thay đổi WHEREmệnh đề thành một điều gì đó có nghĩa hơn, nếu không nó có thể được bỏ qua.


LỖI: cột "hello world" không tồn tại trong my_table Truy vấn không thành công PostgreSQL đã nói: cột "hello world" không tồn tại trong my_table
Pål Brattberg

@ PålBrattberg: phải là dấu ngoặc kép, hiện đã được sửa.
onedaywhen

Không quan trọng bảng nào được sử dụng về thời gian xử lý? Hay thực tế là SELECT không tham chiếu đến bất kỳ cột nào làm cho bảng thực tế không liên quan?
Allen Gould

@AllenGould: nó sẽ là 'phụ thuộc vào nhà cung cấp' nhưng có những đoạn ngắn mạch rõ ràng có thể bị khai thác, ví dụ một trường hợp là trình tối ưu hóa nhận ra SELECTmệnh đề chỉ bao gồm các hằng số và đó AnyTableWithOneOrMoreRowslà một bảng được lưu trữ, do đó chỉ sử dụng thống kê để xác minh xem bảng có không hàng.
onedaywhen

2

Có một khả năng khác - độc lập VALUES():

VALUES ('Hello World');

Đầu ra:

column1
Hello World

Nó hữu ích khi bạn cần chỉ định nhiều giá trị theo cách nhỏ gọn:

VALUES (1, 'a'), (2, 'b'), (3, 'c');

Đầu ra:

column1     column2
      1     a
      2     b
      3     c

Bản trình diễn DBFiddle

Cú pháp này được hỗ trợ bởi SQLite / PostgreSQL / DB LUW / MariaDB 10.3.


2

Đối với ClickHouse, không có gì là system.one

SELECT 1 FROM system.one

1

Trong Firebird, bạn có thể làm điều này:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE là một bảng đặc biệt luôn có một hàng.


0

Tôi biết đây là một câu hỏi cũ nhưng cách giải quyết tốt nhất cho câu hỏi của bạn là sử dụng một truy vấn con giả:

SELECT 'Hello World'
FROM (SELECT name='Nothing') n
WHERE 1=1

Bằng cách này, bạn có thể có WHERE và bất kỳ mệnh đề nào (như Tham gia hoặc Áp dụng, v.v.) sau câu lệnh select vì truy vấn con giả buộc sử dụng mệnh đề FROM mà không thay đổi kết quả.


1
Bạn vẫn có một SELECTmà không có một FROMtrong subquery của bạn, vì vậy nó vẫn sẽ thất bại trong Oracle, vv
Pere

Trong Oracle thậm chí còn đơn giản hơn vì bạn có thể chỉ SELECT 'Hello' FROM dual WHERE 1=1và bỏ qua truy vấn con.
DomingoR

OP đã hỏi liệu có thể có một câu lệnh (cụ thể là a SELECT) mà không có FROMmệnh đề hay không. Bạn vẫn chưa đọc câu hỏi?
Pere

Tôi đã đọc câu hỏi nhưng trừ khi bạn hoàn toàn thiếu kinh nghiệm về SQL (hoặc chưa đọc các câu trả lời khác), bạn biết rằng bạn không thể WHEREthiếu FROM. Do đó, tôi đã trả lời câu đầu tiên của câu hỏi OP.
DomingoR

Chà, tôi đã có hơn 15 năm kinh nghiệm về SQL, có bằng Máy tính và không nhớ bây giờ có phải WHERElà SQL chuẩn hay không. Tôi cũng đọc các câu trả lời khác. Nhân tiện: điều thích hợp là bạn không thể có a SELECTmà không có aFROM , không phải "a WHEREwithout FROM" (?). Truy vấn của bạn hoạt động ở đâu, @DomingoR? Nó vẫn có a SELECTmà không có FROM(trong truy vấn con), do đó không thành công trên những DBMS không cho phép có các truy vấn mà không có a FROMvà chỉ hoạt động trên những truy vấn khác với SQL tiêu chuẩn và cho phép không có FROMtrong SELECT. Vì vậy, câu trả lời của bạn không phục vụ gì.
Pere

0

Tôi đang sử dụng firebird Trước hết, hãy tạo một bảng một cột có tên "NoTable" như thế này

CREATE TABLE NOTABLE 
(
  NOCOLUMN              INTEGER
);
INSERT INTO NOTABLE VALUES (0); -- You can put any value

bây giờ bạn có thể viết cái này

select 'hello world' as name

từ đáng chú ý

bạn có thể thêm bất kỳ cột nào bạn muốn được hiển thị


0

Đối với DB2:

`VALUES('Hello world')`

Bạn cũng có thể làm nhiều "hàng":

`VALUES('Hello world'),('Goodbye world');`

Bạn thậm chí có thể sử dụng chúng trong các phép nối miễn là các loại khớp với nhau:

VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.