FROM clause necessary in every SELECT statement - sql

is the FROM clause necessary in every SELECT statement?Thanks..

Not really - you can use SELECT to initialize a variable.
Examples from here:
mysql> SELECT 1 + 1;
-> 2

Not in MySQL, no. You could do this:
SELECT 1 + 1;
It will be in some DBMSs though - Oracle for example would require you to do:
SELECT 1 + 1 FROM DUAL;

No. you can very easily do
SELECT 1+1

(EDIT: Missed the the MYSQL tab.)
This depends on the database.
In Oracle, IIRC, the from is required. But Oracle has a table DUAL which always returns one row for cases where all the work is being done in the SELECT clause.
On the other hand, SQL Server does not require the FROM, to return the value of a variable just select it:
SELECT #myVar

As mentioned by ocedecio FROM is not required in every statement.
For example I tend to use the following syntax to initialise a table with data
insert into status(code, description)
select 'O', 'Open'
union all select 'C', 'Closed'
union all select 'P', 'Parked'
etc..
EDIT (following comments by gamecat)
The example above demonstrates when SELECT without FROM may have a practical use.
You can of course just call:
select 'O', 'Open'
union all select 'C', 'Closed'
union all select 'P', 'Parked'

Basically in SQL server 2005 FROM keyword is not required for Scalar value functions and system functions but it mandatory for table valued functions.
Scalar valued functions can executable like below syntax
Select functionname(arguments)
Table valued functions can executable like below syntax
Select * from functionname(arguments)
else
Select col1,col2 from functionname(argument1,argument2)

Actually, both "SELECT 1" and "SELECT 1 FROM DUAL" work in latest versions of MySQL.
Interesting enough, "SELECT 1 WHERE 1 = 1" requires a FROM clause: "SELECT 1 FROM DUAL WHERE 1 = 1" is fine. In other platforms, like PostgreSQL, "SELECT 1 WHERE 1 = 1" works fine.
Another oddity: "SELECT 1 FROM DUAL GROUP BY 1 HAVING 1=1" works in MySQL 5.7, but fails in MySQL 5.5.
Summary of the required/optional FROM clause in different platforms:
MySQL, MariaDB, Amazon Aurora: optional or use "FROM dual".
Oracle: use "FROM dual".
IBM DB2: use "FROM sysibm.sysdummy1".
Informix: use "FROM systables WHERE tabid=1"
Firebird, InterBase: use "FROM rdb$database".
Microsoft Access: required, but no dummy table. Try using "FROM (SELECT COUNT(*) FROM first_table_found WHERE 1=0) AS dual".
SQL Server, SQL Azure, SQL Server CE, Sybase ASE, SQL Anywhere, Ingres, PostgreSQL, Redshift, SQLite: optional.

Related

How to make Oracle and SQL Server ORDER BY the same?

I need to compare table counts for an Oracle schema to a SQL Server database. However, when I make my query, the results are always off because of the way each handles the underscore ('_') in terms of ordering. I've included an example of what I'm seeing below.
In Oracle:
SELECT FIELD1 FROM ORACLE_ORDER ORDER BY FIELD1 ASC;
Result:
'ABC'
'ABCD'
'ABC_D'
In SQL Server:
SELECT FIELD1 FROM SQL_ORDER ORDER BY FIELD1 ASC;
Result:
'ABC'
'ABC_D'
'ABCD'
As you can see from above, oracle and sql server both treat the underscore differently when it comes to ordering. How can I modify either of the queries (or environments) to make them order the same as the other?
In the SQL Server Side use the following
Select * from SQL_ORDER
ORDER BY FIELD1 Collate SQL_Latin1_General_CP850_BIN
The collation SQL_Latin1_General_CP850_BIN makes it to be used with ASCII values. In this case ASCII of underscore is 95, A being 65, and Z being 90. Remember lower case "a" will have a higher value than upper case "A" and so on.
Here is the fiddle
Simple way is to use Collate SQL_Latin1_General_CP850_BIN function in ORDER BY to achieve this
SELECT * FROM (
SELECT 'ABC' AS TAB UNION
SELECT'ABC_D'UNION
SELECT'ABCD'UNION
SELECT'ABC_'UNION
SELECT 'ABC' UNION
SELECT'A_C' UNION
SELECT'ABC_DE_FGH'UNION
SELECT'ABCXDEYFGH') AS X
ORDER BY X.Tab Collate SQL_Latin1_General_CP850_BIN

SQL Query - are functions injected in a query will be evaluated by Oracle

I would like to know if the SQL functions extractvalue() and xmltype() have chances to be executed in the following query or if they will be evaluated as a string value by the IN operator.
SELECT * FROM TABLE_1 WHERE (FIELD_1 IN ('foo','bar''||(select extractvalue(xmltype(''%gxgol;]>''),''/l'') from dual)||'''))
This query does not raise any error in Oracle and the output only contains the rows where FIELD_1 equal 'foo'.
No, the content of a string literal will not be executed. Thankfully.
You need a real subquery. Something like:
SELECT *
FROM TABLE_1
WHERE FIELD_1 IN (
SELECT 'foo' FROM DUAL
UNION ALL
SELECT 'bar' || extractvalue(bla,bla) FROM DUAL)
If you call them via
execute immediate
, yes they will taken as functions.
for more info https://docs.oracle.com/cd/B13789_01/appdev.101/b10807/13_elems017.htm

select where substring

SQL newbie here, but I can't find the solution to something that looks easy:
The following query does not seem to have a valid syntax (ORA-00904: invalid identifier), but its logic should be clear. How can I achieve this in a query that needs to be speedy?
SELECT * FROM table WHERE LEFT(column,4)="abcd"
For this purpose, you should use like rather than left(). First, Oracle doesn't support left() (you need substr() instead). Second, like can make use of indexes because the wildcard is not at the beginning of the string:
SELECT *
FROM table
WHERE column like 'abcd%';
Oracle and some other products have substr.
SELECT * FROM tablename WHERE substr(columnname, 1, 4) = 'abcd'
I.e. single quotes for string literals!
ANSI SQL has substring:
SELECT * FROM tablename WHERE substring(columnname from 1 for 4) = 'abcd'
And others have left:
SELECT * FROM tablename WHERE LEFT(columnname,4) = 'abcd'

SQLite IF Exists Clause

How to write IF EXISTS as shown in below query in SQLite? I read somewhere that IF clause doesn't exist in SQLite. What would be a better alternative for this?
if exists (select username from tbl_stats_assigned where username = 'abc' )
select 1 as uname
else
select 0 as uname
Just do it the standard SQL way:
select exists(
select 1
from tbl_stats_assigned
where username = 'abc'
);
Assuming of course that your 1 and 0 are actually boolean values (which SQLite represents with one and zero just like MySQL).
That should work in any SQL database and some even have special optimizations to support that idiom.

SELECT from nothing?

Is it possible to have a statement like
SELECT "Hello world"
WHERE 1 = 1
in SQL?
The main thing I want to know, is can I SELECT from nothing, ie not have a FROM clause.
It's not consistent across vendors - Oracle, MySQL, and DB2 support dual:
SELECT 'Hello world'
FROM DUAL
...while SQL Server, PostgreSQL, and SQLite don't require the FROM DUAL:
SELECT 'Hello world'
MySQL does support both ways.
Try this.
Single:
SELECT * FROM (VALUES ('Hello world')) t1 (col1) WHERE 1 = 1
Multi:
SELECT * FROM (VALUES ('Hello world'),('Hello world'),('Hello world')) t1 (col1) WHERE 1 = 1
more detail here : http://modern-sql.com/use-case/select-without-from
In Oracle:
SELECT 'Hello world' FROM dual
Dual equivalent in SQL Server:
SELECT 'Hello world'
Here is the most complete list of database support of dual from https://blog.jooq.org/tag/dual-table/:
In many other RDBMS, there is no need for dummy tables, as you can
issue statements like these:
SELECT 1;
SELECT 1 + 1;
SELECT SQRT(2);
These are the RDBMS, where the above is generally possible:
H2
MySQL
Ingres
Postgres
SQLite
SQL Server
Sybase ASE
In other RDBMS, dummy tables are required, like in Oracle. Hence,
you’ll need to write things like these:
SELECT 1 FROM DUAL;
SELECT 1 + 1 FROM DUAL;
SELECT SQRT(2) FROM DUAL;
These are the RDBMS and their respective dummy tables:
DB2: SYSIBM.DUAL
Derby: SYSIBM.SYSDUMMY1
H2: Optionally supports DUAL
HSQLDB: INFORMATION_SCHEMA.SYSTEM_USERS
MySQL: Optionally supports DUAL
Oracle: DUAL
Sybase SQL Anywhere: SYS.DUMMY
Ingres has no DUAL, but would actually need it as in Ingres you cannot
have a WHERE, GROUP BY or HAVING clause without a FROM clause.
In SQL Server type:
Select 'Your Text'
There is no need for the FROM or WHERE clause.
You can. I'm using the following lines in a StackExchange Data Explorer query:
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
The Data Exchange uses Transact-SQL (the SQL Server proprietary extensions to SQL).
You can try it yourself by running a query like:
SELECT 'Hello world'
There is another possibility - standalone VALUES():
VALUES ('Hello World');
Output:
column1
Hello World
It is useful when you need to specify multiple values in compact way:
VALUES (1, 'a'), (2, 'b'), (3, 'c');
Output:
column1 column2
1 a
2 b
3 c
DBFiddle Demo
This syntax is supported by SQLite/PostgreSQL/DB LUW/MariaDB 10.3.
In Firebird, you can do this:
select "Hello world" from RDB$DATABASE;
RDB$DATABASE is a special table that always has one row.
I think it is not possible. Theoretically: select performs two sorts of things:
narrow/broaden the set (set-theory);
mapping the result.
The first one can be seen as a horizontal diminishing opposed to the where-clause which can be seen as a vertical diminishing. On the other hand, a join can augment the set horizontally where a union can augment the set vertically.
augmentation diminishing
horizontal join/select select
vertical union where/inner-join
The second one is a mapping. A mapping, is more a converter. In SQL it takes some fields and returns zero or more fields. In the select, you can use some aggregate functions like, sum, avg etc. Or take all the columnvalues an convert them to string. In C# linq, we say that a select accepts an object of type T and returns an object of type U.
I think the confusion comes by the fact that you can do: select 'howdy' from <table_name>. This feature is the mapping, the converter part of the select. You are not printing something, but converting! In your example:
SELECT "
WHERE 1 = 1
you are converting nothing/null into "Hello world" and you narrow the set of nothing / no table into one row, which, imho make no sense at all.
You may notice that, if you don't constrain the number of columns, "Hello world" is printed for each available row in the table. I hope, you understand why by now. Your select takes nothing from the available columns and creates one column with the text: "Hello world".
So, my answer is NO. You can't just leave out the from-clause because the select always needs table-columns to perform on.
In Standard SQL, no. A WHERE clause implies a table expression.
From the SQL-92 spec:
7.6 "where clause"
Function
Specify a table derived by the
application of a "search condition" to
the result of the preceding "from
clause".
In turn:
7.4 "from clause"
Function
Specify a table derived from one or more named tables.
A Standard way of doing it (i.e. should work on any SQL product):
SELECT DISTINCT 'Hello world' AS new_value
FROM AnyTableWithOneOrMoreRows
WHERE 1 = 1;
...assuming you want to change the WHERE clause to something more meaningful, otherwise it can be omitted.
For ClickHouse, the nothing is system.one
SELECT 1 FROM system.one
I know this is an old question but the best workaround for your question is using a dummy subquery:
SELECT 'Hello World'
FROM (SELECT name='Nothing') n
WHERE 1=1
This way you can have WHERE and any clause (like Joins or Apply, etc.) after the select statement since the dummy subquery forces the use of the FROM clause without changing the result.
For DB2:
`VALUES('Hello world')`
You can do multiple "rows" as well:
`VALUES('Hello world'),('Goodbye world');`
You can even use them in joins as long as the types match:
VALUES(1,'Hello world')
UNION ALL
VALUES(2,'Goodbye world');
I'm using firebird
First of all, create a one column table named "NoTable" like this
CREATE TABLE NOTABLE
(
NOCOLUMN INTEGER
);
INSERT INTO NOTABLE VALUES (0); -- You can put any value
now you can write this
select 'hello world' as name
from notable
you can add any column you want to be shown