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.