Why this subquery fails? - sql

select *
from
(select * from person) as t1; /*ok*/
select *
from
(select * from person) as t1
where t1.birthday >= '1987-04-09'; /*ok*/
select *
from
(select * from person) as t1
where
t1.birthday = (select max(birthday) from t1); /* fails with 't1 doesn't exist' */
I know that the correct SQL for the 3rd query is
select *
from person
where person.birthday = (select max(birthday) from person) /*ok*/
Would anyone help me understand why the 3rd SQL query failed?
Thanks a lot

The SQL Query Execution Order is:
From/Join
Where
Group By
Having
Select
Distinct
Order by
In your case, 'from t1' will be executed first and it will throw an error because t1 hasn't yet been recognised by the DB.
Better use the table name instead of t1.

Related

Hive Subquery in SELECT

I have a query like
SELECT name, salary/ (SELECT max(money) from table_sal) FROM table_a;
I get an error saying
Unsupported SubQuery Expression Invalid subquery. Subquery in SELECT could only be top-level expression
Is there a way to resolve this?
Does this work with a CROSS JOIN?
SELECT name, salary / s.max_money
FROM table_a CROSS JOIN
(SELECT max(money) as max_money from table_sal) s
You can also do this as below, please let me know if it works for you.
Select t1.name
, t1.salary/T2.max_money
from
(SELECT name
, salary, 1 as dummy
from table_a ) t1
Join
(SELECT max(money) as max_money
, 1 as dummy
from table_sal) t2
on t1.dummy = t2.dummy ;

Is there a way to SELECT * and do a CASE expression

So something like this:
SELECT *,
CASE
WHEN
....
I'm coding in Teradata
In Teradata if you are going to include more derived columns with your * then you must include the table or alias name with the *
So:
SELECT
myTable.*,
myOtherTable.*,
CASE WHEN... END
FROM myTable
INNER JOIN myOtherTable ON
mytable.id = myOtherTable.id;
If you have a thousand tables being joined together then just toss that mess into a subquery so you can SELECT * FROM and then add you case in the main query:
SELECT t1.*
CASE WHEN... END
FROM
(
SELECT *
FROM myTable
INNER JOIN myOtherTable ON
mytable.id = myOtherTable.id
) AS t1;

Apply inner join on two tables constructed with minus

I have two versions of the same table and want to find the differences between both: which rows have changed? I use a minus query twice to print the changed rows as they appear in the old and new table.
Now I want to add a new query: one that shows me the rows that have changed on a specific column.
(select * from NewTable minus select * from OldTable) NewRows
inner join
(select * from OldTable minus select * from NewTable) OldRows
on NewRows.column1 = OldRows.column1
and NewRows.column2 <> OldRows.column2
where column1 is the unique row id and column 2 is the changed property.
When I execute Oracle SQL Developer I get error ORA-00933 "SQL command not properly ended", and he indicates the definition of NewRows as error. I have also tried with ") as NewRows" but it did not work.
The following query does work, so the NewTable and OldTable are compatible.
(select * from NewTable minus select * from OldTable)
union
(select * from OldTable minus select * from NewTable)
Try with additional select * from on the beginning:
select * from
(select * from NewTable minus select * from OldTable) NewRows
inner join
(select * from OldTable minus select * from NewTable) OldRows
on (NewRows.column1 = OldRows.column1 and NewRows.column2 <> OldRows.column2)
Also be aware of nulls your condition for difference <> will not cover situation where one value is null and second is not null. You should probably use:
on (nvl(NewRows.column1, 'UNIQUEVAL1') = nvl(OldRows.column1, 'UNIQUEVAL1')
and nvl(NewRows.column2, 'UNIQUEVAL2') <> nvl(OldRows.column2, 'UNIQUEVAL2') )

SQL Statement not exists in

I want to select entries from first table that have no entries in second table
I tried this:
SELECT
first.clientid
FROM
table1 AS first,
table2 AS second
WHERE
first.clientid NOT IN second.clientid
but i have realize problem
any tips?
Wrong Syntax.
Either use IN:
SELECT clientid FROM table1
WHERE clientid NOT IN (SELECT clientid FROM table2);
Or use EXISTS:
SELECT clientid FROM table1
WHERE NOT EXISTS (SELECT * FROM table2 where table2.clientid = table1.clientid);
Or use MINUS (not avaliable in every DBMS):
SELECT clientid FROM table1
MINUS
SELECT clientid FROM table2;
You can use NOT EXISTS to do that:
SELECT first.clientid
FROM table1 AS first
WHERE NOT EXISTS
(SELECT * FROM table2 AS second WHERE first.clientid = second.clientid)

Is there a quick way to compare two equally formatted tables in SQL?

I would like to make an SQL query to compare two tables with identical columns, both names and types. Each table has a unique key. I want the query to return any rows that contain unequal values. I know could do something like this
select *
from table_1, table_2
where
table_1.key = table_2.key
and (
table_1.col1 != table_2.col1 OR
table_1.col2 != table_2.col2 OR
...
)
but this would be tedious since there are a large and potentially variable number of columns.
edit
If it helps, I'm using a tsql system.
Not sure what type of DB you are using but if you are using SQL Server 2005 or higher try this:
select 'table1' as tblName, * from
(select * from table1
except
select * from table2) x
union all
select 'table2' as tblName, * from
(select * from table2
except select *
from table1) x
How abt this..
select * from table1 where not exists (select * from table2)
union all
select * from table2 where not exists (select * from table1)
Verified with SQL Server:
(select * from table1 except select * from table2)
union
(select * from table2 except select * from table1);
Verified with Oracle:
(select * from table1 minus (select * from table2))
union
(select * from table2 minus (select * from table1))