MYSQL Select without from (values table constructor)
[From https://modern-sql.com/use-case/select-without-from]
Select
without from
Let's get that straight from the beginning:
select
without from
is not standard conforming SQL. Full stop.
Nevertheless it works in many databases—also in standard conforming ones. That's no contradiction: the standard explicitly allows conforming databases to “provide user options to process non-conforming SQL statements”.0 The behavior of such statements is completely up to the vendor, of course.
So what alternative does the standard offer to
select
without from
? A surprisingly simple and yet powerful one: values
without insert
.
The following
select
statement can thus be implemented as a standard-conforming values without insert:
Instead of a non-conforming
select
without from
:SELECT CURRENT_DATE
the standard allows the use of
values
without insert
:VALUES (CURRENT_DATE)
Too bad the stand-alone use of
values
is still not part of Core SQL. Consequently, only three out of the six tested databases support it. select
without from
, on the other hand, works on four of them.
By now you might wonder why stand-alone
values
might be useful at all. As I implied above, it is more powerful than select
without from
because it is not limited to produce a single row.
The following
values
statement returns today’s and yesterday's dates (use-case) in two rows—not two columns:VALUES (CURRENT_DATE)
, (CURRENT_DATE - INTERVAL '1' DAY)
With
select
without from
, you'd need to use union
. That can quickly become bulky.Conforming Alternatives
SQL Server offers a confirming variant:
values
is allowed in the from
clause, if the from
clause assigns column names:SELECT *
FROM (VALUES (1,2)
, (3,4)
) t1 (c1, c2)
The only other standard-conforming alternative is to use a dummy table in the
from
clause. Databases that do not allow select
without from
usually ship with tables for this purpose (e.g., DUAL
in the Oracle database or SYSIBM.DUMMY1
in DB2). Besides portability there is nothing against using them.
The easiest way to build a standard-conforming and portable solution it is to ship your own dummy1 table with your software.
If you don't mind maintaining different
create
statements for each target database, you can also use a view2 based on the vendors proprietary dummy table. That may or may not save you from an argument about performance if the vendors dummy table is super-performance-optimized.Compatibility
On the bottom line, this topic is an embarrassing demonstration how poorly the standard is adopted. However, it is upon us to demand this SQL-92 feature from the database vendors.
[From https://dba.stackexchange.com/questions/177312/does-mariadb-or-mysql-implement-the-values-expression-table-value-constructor]
SELECT 1, t.7 FROM (VALUES (7),(42)) AS t; 1 | 7 -------- 1 | 7 1 | 42
You'll notice that there is no support for column_alias in the
FROM
clause, instead requiring you to use the table_alias and the name of the first row's value for that column. But column_alias are allowed in a CTE's WITH
clause,WITH t(a) AS ( VALUES (1),(2) )
SELECT t.a, t.a AS b
FROM t;
a | b
--------
1 | 1
2 | 2
Additionally you may able to skirt this by giving the first row a definitive alias.
SELECT 1 AS x ,2 AS y
UNION VALUES (3,4),(5,6);
x | y
-------
1 | 2
3 | 4
5 | 6
Comments
Post a Comment