Use of asterisk in oracle sql - sql

Why is the use of asterisk perfectly valid in oracle sql when the asterisk is by itself in the SELECT clause, but it results in an error when there are other expressions in the SELECT?
For example:
select * from table1 -- is ok
But:
select field, * from table -- is not ok

Oracle only allows a "bare" asterisk when there are no other columns.
Otherwise, you need to qualify it:
select t.field, t.*
from table1 t;
I suspect the reason is that Oracle considers select * to be a full clause, rather than * being an abbreviation for all columns.

Related

Using calculation with an an aliased column in ORDER BY

As we all know, the ORDER BY clause is processed after the SELECT clause, so a column alias in the SELECT clause can be used.
However, I find that I can’t use the aliased column in a calculation in the ORDER BY clause.
WITH data AS(
SELECT *
FROM (VALUES
('apple'),
('banana'),
('cherry'),
('date')
) AS x(item)
)
SELECT item AS s
FROM data
-- ORDER BY s; -- OK
-- ORDER BY item + ''; -- OK
ORDER BY s + ''; -- Fails
I know there are alternative ways of doing this particular query, and I know that this is a trivial calculation, but I’m interested in why the column alias doesn’t work when in a calculation.
I have tested in PostgreSQL, MariaDB, SQLite and Oracle, and it works as expected. SQL Server appears to be the odd one out.
The documentation clearly states that:
The column names referenced in the ORDER BY clause must correspond to
either a column or column alias in the select list or to a column
defined in a table specified in the FROM clause without any
ambiguities. If the ORDER BY clause references a column alias from
the select list, the column alias must be used standalone, and not as
a part of some expression in ORDER BY clause:
Technically speaking, your query should work since order by clause is logically evaluated after select clause and it should have access to all expressions declared in select clause. But without looking at having access to the SQL specs I cannot comment whether it is a limitation of SQL Server or the other RDBMS implementing it as a bonus feature.
Anyway, you can use CROSS APPLY as a trick.... it is part of FROM clause so the expressions should be available in all subsequent clauses:
SELECT item
FROM t
CROSS APPLY (SELECT item + '') AS CA(item_for_sort)
ORDER BY item_for_sort
It is simply due to the way expressions are evaluated. A more illustrative example:
;WITH data AS
(
SELECT * FROM (VALUES('apple'),('banana')) AS sq(item)
)
SELECT item AS s
FROM data
ORDER BY CASE WHEN 1 = 1 THEN s END;
This returns the same Invalid column name error. The CASE expression (and the concatenation of s + '' in the simpler case) is evaluated before the alias in the select list is resolved.
One workaround for your simpler case is to append the empty string in the select list:
SELECT
item + '' AS s
...
ORDER BY s;
There are more complex ways, like using a derived table or CTE:
;WITH data AS
(
SELECT * FROM (VALUES('apple'),('banana') AS sq(item)
),
step2 AS
(
SELECT item AS s FROM data
)
SELECT s FROM step2 ORDER BY s+'';
This is just the way that SQL Server works, and I think you could say "well SQL Server is bad because of this" but SQL Server could also say "what the heck is this use case?" :-)

T-SQL SELECT statement

I have a simple question regarding SELECT statement in SQL Server. I would like to know the purpose of the following syntax:
SELECT column_name, . *
I don't understand the purpose of the (period) and a (star) after the SELECT. I understand SELECT column_name1, column_name2,.... etc. or SELECT *...
but what does a period do before the star.
That is invalid syntax and will not run.
.* can be used following a table name or alias to get all columns for that table. For example...
SELECT mytable.* FROM mytable
or
SELECT a.column_one, a.* FROM mytable a

DB2 SELECT EXCEPT with WHERE clause

I'm trying to compare two tables in a DB2 database in z/OS using SPUFI to submit SQL queries.
I'm doing this by using EXCEPT to see the difference between two SELECT queries.
I need to filter the SELECT statement from the first query with a WHERE clause.
SELECT KEY_FIELD_1,LOOKUP_FIELD_1
FROM TABLE_1
WHERE FILTER_FIELD = '1'
EXCEPT
SELECT KEY FIELD_2,LOOKUP_FIELD_2
FROM TABLE_2
I got results back, but it also returned an error -199 Is this because the WHERE clause is not present in the second SELECT statement?
ERROR: ILLEGAL USE OF KEYWORD EXCEPT.
TOKEN <ERR_STMT> <WNG_STMT> GET SQL
SAVEPOINT HOLD FREE ASSOCIATE WAS EXPECTED
Try introducing parentheses e.g.
( SELECT KEY_FIELD_1,LOOKUP_FIELD_1
FROM TABLE_1
WHERE FILTER_FIELD = '1' )
EXCEPT
( SELECT KEY FIELD_2,LOOKUP_FIELD_2
FROM TABLE_2 )

Ordering by expression from Select

I need to make a query like this:
SELECT (t.a-t.b) AS 'difference'
FROM t
ORDER BY abs(t.a-t.b)
Is there a way not to duplicate code (t.a-t.b) ? Thank you for your answers
You can wrap the SQL statement and then perform the ORDER BY if you're performing an absolute value on it.
SELECT * FROM
(
SELECT (t.a-t.b) AS "difference"
FROM t
) a
ORDER BY abs(a.difference)
UPDATE: I used SQL Server the 1st time, but depending on your environment (Oracle, MySQL), you may need to include double quotes around the column alias, so:
SELECT * FROM
(
SELECT (t.a-t.b) AS "difference"
FROM t
) a
ORDER BY abs("a.difference")

CROSS JOIN of query and single-row table

I have a big query and a table with a single row (I store some constants in it).
What is the best way to join the row of the table with every row of the query considering that Access doesn't support cross joins with queries?
SELECT * from (subquery), table -- Invalid in Access
Access will accept a cross join between a query named some_query and a table named some_table like this ...
SELECT *
FROM some_query, some_table;
With your names, try it this way ...
SELECT * from [some query], [table]
IOW, get rid of the parentheses, and enclose the data source names in square brackets because of the space in some query and because table is a reserved word.
OTOH, if you meant some query to be a placeholder for the text of a SQL statement instead of the name of a saved query, consider this example.
SELECT *
FROM
(SELECT * FROM agents) AS sub, Dual;
According to Microsoft and this previous question, cross joins are legal. You say is it invalid, but did you get an error message when you tried?