ВИБРАТИ з нічого?


91

Чи можна мати таке твердження

SELECT "Hello world"
WHERE 1 = 1

в SQL?

Головне, що я хочу знати, це те, чи можу я ВІДБУТИ ні з чого, тобто не мати речення FROM.


3
Переглядаючи ваш коментар на @Rafael Belliard, можливо, вам краще запитати, що ви насправді хочете зробити. Ви хочете повернути деякий рядок, якщо для даної таблиці існують значення, наприклад?
Jim L

Так, насправді саме цього я і хотів. Я знаю, що можу це зробити, мені більше було цікаво, чи потрібна мені перерва FROM NULLміж SELECTі WHERE. Незрозуміле словосполучення здебільшого тому, що це домашнє завдання, і я не хотів, щоб хтось прийшов і сказав мені відповідь, якщо моє кишкове почуття було неправильним.
Ritwik Bose

Відповіді:


141

Це не узгоджено між постачальниками - Oracle, MySQL та DB2 підтримують подвійне:

SELECT 'Hello world'
  FROM DUAL

... хоча SQL Server, PostgreSQL і SQLite не вимагають FROM DUAL:

SELECT 'Hello world'

MySQL підтримує обидва способи.


2
Я завжди дивувався. Чому вибір терміна подвійний для фантомної таблиці?
Alex Blakemore

5
@Alex: "Оригінальна таблиця DUAL мала два рядки (звідси і її назва), але згодом вона мала лише один рядок."
повстання

7
На DB2 дуал називається 'sysibm.sysdummy1'
Дунайський моряк

1
На Postgresql можна створити фіктивну таблицю з назвою DUALта виконувати запити з фантомної таблиці.
Stephan

1
@AlexBlakemore "Я створив таблицю DUAL як основний об'єкт у Словнику даних Oracle. Її ніколи не передбачалося бачити самою, а натомість використовували всередині подання, яке, як очікувалося, буде запитано. таблиці DUAL і створіть два результати в результаті для кожного одного рядка у вашій таблиці. Потім, використовуючи GROUP BY, отримане об’єднання можна підсумувати, щоб показати обсяг пам’яті для екстента DATA та для індексу (-ів) INDEX. Ім'я, DUAL, здавалося підходящим для процесу створення пари рядків лише з одного "( en.wikipedia.org/wiki/DUAL_table )
натисніть кнопку Ok


15

Спробуйте це.

Одномісний:

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

Мульти:

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

докладніше тут: http://modern-sql.com/use-case/select-without-from


1
Єдина відповідь, сумісна з ANSI SQL! (До запитання без
dbms

Яка мета WHERE 1 = 1? На PostgreSQL працює без нього. Або це стосується іншого DMBS?
Френкі Дрейк

Тільки SELECT * FROM (VALUES ("Hello world")) t1 (col1)все ще добре. Whereпросто відповідь на це питання.
chuongtv

@chuongtv Як вибрати кілька рядків?
Гектор,

@Hector Просто дотримуйтесь вставки структури SQL. ось такSELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv

8

Ось найповніший список підтримки баз даних dual з https://blog.jooq.org/tag/dual-table/ :

У багатьох інших СУБД немає потреби в фіктивних таблицях, оскільки ви можете видавати такі оператори:

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

Це СУБД, де вищезазначене загалом можливо:

  • Н2
  • MySQL
  • Ingres
  • Postgres
  • SQLite
  • SQL Server
  • Sybase ASE

В інших СУБД потрібні фіктивні таблиці, як в Oracle. Отже, вам потрібно буде написати такі речі:

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

Це СУБД та відповідні фіктивні таблиці:

  • DB2: SYSIBM.DUAL
  • Дербі: SYSIBM.SYSDUMMY1
  • H2: За бажанням підтримує DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: За бажанням підтримує DUAL
  • Oracle: DUAL
  • Sybase SQL Anywhere: SYS.DUMMY

Ingres не має DUAL, але насправді він би потребував цього, оскільки в Ingres ви не можете мати речення WHERE, GROUP BY або HAVING без речення FROM.


6

У типі SQL Server:

Select 'Your Text'

Немає потреби в пункті FROMабо WHERE.


5

Ти можеш. Я використовую такі рядки у запиті 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

Обмін даними використовує Transact-SQL (власні розширення SQL Server до SQL).

Ви можете спробувати самі, запустивши такий запит:

SELECT 'Hello world'

Обмін даними - це Azure, заснований на SQL Server.
OMG Ponies,

2

Я думаю, що це неможливо. Теоретично: select виконує два типи речей:

  • звузити / розширити сукупність (теорія множин);

  • відображення результату.

Перший може розглядатися як горизонтальне зменшення на відміну від речення where, яке може розглядатися як вертикальне зменшення. З іншого боку, об’єднання може збільшити набір по горизонталі, де об’єднання може збільшити набір по вертикалі.

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

Другий - це відображення. Картографування - це більше конвертер. У SQL він бере деякі поля і повертає нуль або більше полів. У виборі ви можете використовувати деякі сукупні функції, такі як сума, середнє значення тощо. Або взяти всі значення стовпців і перетворити їх у рядок. У C # linq ми говоримо, що select приймає об'єкт типу T і повертає об'єкт типу U.

Я думаю , що плутанина приходить той факт , що ви можете зробити: select 'howdy' from <table_name>. Ця особливість - відображення, частина перетворювача селекту. Ви щось не друкуєте, а перетворюєте! У вашому прикладі:

SELECT "
WHERE 1 = 1

ви перетворюєте нічого / нульове в "Hello world"і звужуєте набір нічого / нічого не стоїть в один рядок, що, мабуть, взагалі не має сенсу.

Ви можете помітити, що, якщо ви не обмежуєте кількість стовпців, "Hello world"друкується для кожного доступного рядка в таблиці. Сподіваюся, ви вже зараз зрозуміли, чому. Ваш вибір не бере нічого зі списку доступних стовпців і створює один стовпець з текстом: "Hello world".

Отже, моя відповідь - НІ. Ви не можете просто не брати до уваги речення from, оскільки для вибору завжди потрібні таблиці-стовпці, на яких можна виконати.


2

У стандартному SQL немає. WHEREЗастереження має на увазі вислів таблиці.

З специфікації SQL-92:

7.6 "де речення"

Функція

Вкажіть таблицю, отриману шляхом застосування "умови пошуку" до результату попереднього "з пункту".

У свою чергу:

7.4 "з пункту"

Функція

Вкажіть таблицю, отриману з однієї або декількох іменованих таблиць.

Стандартний спосіб зробити це (тобто повинен працювати на будь-якому продукті SQL):

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

... припускаючи, що ви хочете змінити WHEREречення на щось більш значуще, інакше це можна пропустити.


ПОМИЛКА: стовпець "привіт світ" не існує в my_table Запит не вдався PostgreSQL сказав: стовпець "привіт світ" не існує в my_table
Pål Brattberg

@ PålBrattberg: це повинні бути одинарні лапки, тепер виправлені.
одного дня, коли

Чи має значення яка таблиця використовується з точки зору часу обробки? Або той факт, що SELECT не посилається на жоден із стовпців, робить фактичну таблицю неактуальною?
Аллен Гулд,

@AllenGould: це може залежати від постачальника, але існують очевидні короткі замикання, які можуть бути використані, наприклад, один із випадків, коли оптимізатор розпізнає, що SELECTпункт містить лише константи, а AnyTableWithOneOrMoreRowsце збережена таблиця, тому просто використовує статистику, щоб перевірити, чи є нульові ряди.
день, коли

2

Є ще одна можливість - автономна VALUES():

VALUES ('Hello World');

Вихід:

column1
Hello World

Це корисно, коли потрібно компактно вказати кілька значень:

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

Вихід:

column1     column2
      1     a
      2     b
      3     c

Демонстрація DBFiddle

Цей синтаксис підтримується SQLite / PostgreSQL / DB LUW / MariaDB 10.3.


2

Для ClickHouse нічого не існує system.one

SELECT 1 FROM system.one

1

У Firebird ви можете зробити це:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE - це спеціальна таблиця, яка завжди має один рядок.


0

Я знаю, що це старе запитання, але найкращим способом вирішення цього питання є використання фіктивного підзапиту:

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

Таким чином ви можете мати WHERE та будь-яке речення (наприклад, Joins або Apply тощо) після оператора select, оскільки фіктивний підзапит змушує використовувати речення FROM без зміни результату.


1
Ви по- , як і раніше є SELECTбез FROMвашої підзапиту, так що це буде по- , як і раніше не в Oracle і т.д.
Пере

В Oracle це ще простіше, оскільки ви можете просто SELECT 'Hello' FROM dual WHERE 1=1і пропустити підзапит.
DomingoR

ОП запитав, чи можна мати заяву (а саме, а SELECT) без FROMпункту. Ви не читали питання?
Пере

Я прочитав запитання, але якщо у вас немає абсолютно досвіду в SQL (або ви не читали інших відповідей), ви знаєте, що WHEREбез цього не можна FROM. Враховуючи це, я відповів на перше твердження запитання щодо ОП.
DomingoR

Ну, я маю більш ніж 15-річний досвід роботи в SQL, ступінь обчислювальної техніки, і не пам’ятав, чи є зараз WHEREстандартним SQL. Я також читав інші відповіді. До речі: правильним є те, що ви не можете мати SELECTбез, аFROM не " WHEREбез FROM" (?). Де працює ваш запит, @DomingoR? Він все ще має a SELECTбез FROM(у підзапиті), таким чином не вдаючись до тих СУБД, які не дозволяють мати запити без a FROMі працюють лише на тих, що відхиляються від стандартного SQL і дозволяють не мати FROMв SELECT. Тож ваша відповідь ні до чого.
Пере

0

Я використовую firebird Перш за все, створіть таблицю з одним стовпцем з назвою "NoTable", як це

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

тепер ви можете написати це

select 'hello world' as name

від помітного

Ви можете додати будь-який стовпець, який хочете, щоб відображався


0

Для DB2:

`VALUES('Hello world')`

Ви також можете зробити кілька "рядків":

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

Ви навіть можете використовувати їх у об’єднаннях, якщо типи збігаються:

VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.