WYBRAĆ z niczego?


91

Czy można mieć takie oświadczenie

SELECT "Hello world"
WHERE 1 = 1

w SQL?

Najważniejsze, co chcę wiedzieć, to czy mogę WYBIERAĆ z niczego, tj. Nie mam klauzuli FROM.


3
Patrząc na swój komentarz na temat @Rafael Belliard, być może lepiej będzie, jeśli zapytasz, co tak naprawdę chcesz robić. Czy chcesz zwrócić jakiś ciąg, jeśli na przykład istnieją wartości dla danej tabeli?
Jim L,

Tak, dokładnie tego chciałem. Wiem, że mogę to zrobić, bardziej zastanawiałem się, czy potrzebuję FROM NULLmiędzy SELECTa WHERE. Niejasne sformułowania, głównie dlatego, że to praca domowa i nie chciałem, aby ktoś przyszedł i powiedział mi odpowiedź, jeśli moje przeczucia były złe.
Ritwik Bose

Odpowiedzi:


141

To nie jest spójne u różnych dostawców - Oracle, MySQL i DB2 obsługują podwójnie:

SELECT 'Hello world'
  FROM DUAL

... podczas gdy SQL Server, PostgreSQL i SQLite nie wymagają FROM DUAL:

SELECT 'Hello world'

MySQL obsługuje oba sposoby.


2
Zawsze się zastanawiałem. Dlaczego wybór terminu dual dla tabeli fantomowej?
Alex Blakemore

5
@Alex: "Oryginalna tabela DUAL miała w sobie dwa wiersze (stąd jej nazwa), ale później miała tylko jeden wiersz."
buntownik

7
W systemie DB2 dual nazywa się „sysibm.sysdummy1”
Danubian Sailor

1
W Postgresql można utworzyć fałszywą tabelę o nazwie DUALi wykonywać zapytania z tabeli podobnej do fantomu.
Stephan

1
@AlexBlakemore "Stworzyłem tabelę DUAL jako obiekt bazowy w słowniku Oracle Data Dictionary. Nigdy nie miał być widoczny, ale zamiast tego został użyty w widoku, który miał być zapytany. Pomysł polegał na tym, że możesz wykonać JOIN, aby tabelę DUAL i utwórz dwa wiersze w wyniku dla każdego wiersza w tabeli. Następnie za pomocą funkcji GROUP BY można podsumować wynikowe łączenie, aby pokazać ilość miejsca dla zakresu DATA i dla zakresu INDEKSU. Nazwa DUAL wydawała się odpowiednia dla procesu tworzenia pary wierszy tylko z jednego ”( en.wikipedia.org/wiki/DUAL_table )
Kliknij OK


15

Spróbuj tego.

Pojedynczy:

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

Wielo:

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

więcej szczegółów tutaj: http://modern-sql.com/use-case/select-without-from


1
Jedyna odpowiedź zgodna z ANSI SQL! (Na pytanie bez określonych dbms.)
jarlh

Jaki jest cel WHERE 1 = 1? Na PostgreSQL działa bez niego. A może dotyczy innego DMBS?
Frankie Drake

Tylko SELECT * FROM (VALUES ("Hello world")) t1 (col1)nadal dobrze. Whereodpowiedz tylko na to pytanie.
chuongtv

@chuongtv Jak wybrać wiele wierszy?
Hector

@Hector Po prostu postępuj zgodnie ze strukturą wstawiania SQL. w ten sposóbSELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
chuongtv

8

Oto najpełniejsza lista obsługi bazy danych dual z https://blog.jooq.org/tag/dual-table/ :

W wielu innych RDBMS nie ma potrzeby stosowania fikcyjnych tabel, ponieważ można wydawać takie instrukcje:

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

Są to RDBMS, w których powyższe jest ogólnie możliwe:

  • H2
  • MySQL
  • Ingres
  • Postgres
  • SQLite
  • SQL Server
  • Sybase ASE

W innych RDBMS wymagane są fikcyjne tabele, tak jak w Oracle. Dlatego musisz napisać takie rzeczy:

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

Oto RDBMS i odpowiadające im fikcyjne tabele:

  • DB2: SYSIBM.DUAL
  • Derby: SYSIBM.SYSDUMMY1
  • H2: Opcjonalnie obsługuje DUAL
  • HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
  • MySQL: Opcjonalnie obsługuje DUAL
  • Wyrocznia: DUAL
  • Sybase SQL Anywhere: SYS.DUMMY

Ingres nie ma DUAL, ale w rzeczywistości by go potrzebował, ponieważ w Ingres nie możesz mieć klauzuli WHERE, GROUP BY lub HAVING bez klauzuli FROM.


6

W SQL Server wpisz:

Select 'Your Text'

Nie ma potrzeby stosowania klauzuli FROMlub WHERE.


5

Możesz. Używam następujących wierszy w kwerendzie 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

Wymiana danych używa języka Transact-SQL (zastrzeżone rozszerzenia SQL Server do SQL).

Możesz spróbować samemu, uruchamiając zapytanie takie jak:

SELECT 'Hello world'

Data Exchange to Azure, oparta na SQL Server.
OMG Kucyki

2

Myślę, że to niemożliwe. Teoretycznie: funkcja select wykonuje dwa rodzaje rzeczy:

  • zawęzić / poszerzyć zbiór (teoria mnogości);

  • mapowanie wyniku.

Pierwsza może być postrzegana jako poziome zmniejszanie, w przeciwieństwie do klauzuli gdzie, które można postrzegać jako pionowe zmniejszanie. Z drugiej strony złączenie może zwiększyć zestaw w poziomie, podczas gdy połączenie może zwiększyć zestaw w pionie.

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

Drugi to mapowanie. Mapowanie jest bardziej konwerterem. W SQL zajmuje kilka pól i zwraca zero lub więcej pól. W polu wyboru możesz użyć niektórych funkcji agregujących, takich jak suma, średnia itp. Lub wziąć wszystkie wartości kolumn i przekonwertować je na ciąg. W C # linq mówimy, że selekcja akceptuje obiekt typu T i zwraca obiekt typu U.

Myślę, że zamieszanie chodzi o fakt, że można zrobić: select 'howdy' from <table_name>. Ta funkcja to mapowanie, część konwertera zaznaczania. Nie drukujesz czegoś, tylko konwertujesz! W twoim przykładzie:

SELECT "
WHERE 1 = 1

konwertujesz nic / wartość null na "Hello world"i zawężasz zbiór nic / brak tabeli do jednego wiersza, co nie ma żadnego sensu.

Możesz zauważyć, że jeśli nie ograniczysz liczby kolumn, "Hello world"zostanie wydrukowany dla każdego dostępnego wiersza w tabeli. Mam nadzieję, że już teraz rozumiesz, dlaczego. Twój wybór nie pobiera nic z dostępnych kolumn i tworzy jedną kolumnę z tekstem:"Hello world" .

Więc moja odpowiedź brzmi NIE. Nie można po prostu pominąć klauzuli from, ponieważ funkcja select zawsze wymaga kolumn tabeli.


2

W standardowym SQL nie. WHEREKlauzula oznacza wyrażenie stołowego.

Ze specyfikacji SQL-92:

7.6 "klauzula gdzie"

Funkcjonować

Określ tabelę utworzoną przez zastosowanie „warunku wyszukiwania” do wyniku poprzedniej klauzuli „from”.

Z kolei:

7.4 „z klauzuli”

Funkcjonować

Określ tabelę pochodzącą z jednej lub więcej nazwanych tabel.

Standardowy sposób na zrobienie tego (tzn. Powinien działać na każdym produkcie SQL):

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

... zakładając, że chcesz zmienić WHEREklauzulę na coś bardziej znaczącego, w przeciwnym razie można ją pominąć.


BŁĄD: kolumna "hello world" nie istnieje w my_table Zapytanie nie powiodło się PostgreSQL powiedział: kolumna "hello world" nie istnieje w my_table
Pål Brattberg

@ PålBrattberg: powinny być pojedynczymi cudzysłowami, teraz naprawione.
onedaywhen

Czy ma znaczenie, który stół jest używany pod względem czasu przetwarzania? A może fakt, że SELECT nie odwołuje się do żadnej z kolumn, sprawia, że ​​rzeczywista tabela jest nieistotna?
Allen Gould

@AllenGould: byłby `` zależny od dostawcy '', ale istnieją oczywiste zwarcia, które można wykorzystać, np. W jednym przypadku optymalizator rozpoznaje SELECTklauzulę zawierającą tylko stałe i AnyTableWithOneOrMoreRowsjest to tabela przechowywana, dlatego wykorzystuje tylko statystyki do sprawdzenia, czy tabela ma zero wierszy.
kiedy

2

Jest jeszcze jedna możliwość - samodzielna VALUES():

VALUES ('Hello World');

Wynik:

column1
Hello World

Jest to przydatne, gdy musisz określić wiele wartości w zwięzły sposób:

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

Wynik:

column1     column2
      1     a
      2     b
      3     c

DBFiddle Demo

Ta składnia jest obsługiwana przez SQLite / PostgreSQL / DB LUW / MariaDB 10.3.


2

W przypadku ClickHouse nic nie jest system.one

SELECT 1 FROM system.one

1

W Firebird możesz to zrobić:

select "Hello world" from RDB$DATABASE;

RDB $ DATABASE to specjalna tabela, która zawsze ma jeden wiersz.


0

Wiem, że to stare pytanie, ale najlepszym sposobem obejścia tego pytania jest użycie fikcyjnego podzapytania:

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

W ten sposób możesz mieć WHERE i dowolną klauzulę (taką jak Joins lub Apply itp.) Po instrukcji select, ponieważ fikcyjne podzapytanie wymusza użycie klauzuli FROM bez zmiany wyniku.


1
Nadal masz w podzapytaniu SELECTbez a FROM, więc w Oracle nadal nie powiedzie się itd.
Pere

W Oracle jest jeszcze prostsze, ponieważ możesz po prostu SELECT 'Hello' FROM dual WHERE 1=1pominąć podzapytanie.
DomingoR

PO zapytał, czy możliwe jest posiadanie oświadczenia (a SELECT) bez FROMklauzuli. Nie przeczytałeś pytania?
Pere

Przeczytałem pytanie, ale jeśli nie jesteś całkowicie niedoświadczony w SQL (lub nie czytałeś innych odpowiedzi), wiesz, że nie możesz mieć WHEREbez FROM. Mając to na uwadze, odpowiedziałem na pierwsze stwierdzenie pytania PO.
DomingoR

Cóż, mam ponad 15-letnie doświadczenie w SQL, dyplom z informatyki i nie pamiętam, czy teraz mam WHEREstandardowy SQL. Czytałem też inne odpowiedzi. Swoją drogą: właściwe jest to, że nie możesz mieć a SELECTbez aFROM , a nie „ WHEREbez FROM” (?). Gdzie działa Twoje zapytanie, @DomingoR? Nadal ma a SELECTbez a FROM(w podzapytaniu), więc zawodzi na tych DBMS, które nie pozwalają na tworzenie zapytań bez a FROMi działają tylko na tych, które odbiegają od standardowego SQL i pozwalają nie mieć FROMw SELECT. Więc twoja odpowiedź nic nie da.
Pere

0

Używam firebird. Przede wszystkim utwórz tabelę z jedną kolumną o nazwie „NoTable” w ten sposób

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

teraz możesz to napisać

select 'hello world' as name

od godnych uwagi

możesz dodać dowolną kolumnę, która ma być wyświetlana


0

W przypadku DB2:

`VALUES('Hello world')`

Możesz też zrobić wiele „wierszy”:

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

Możesz ich nawet używać w połączeniach, o ile typy są zgodne:

VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.