hive subquery must have a from clause?how to avoid it? - hive

I met a problem in hive sql:
this sql is ok:
select 20181102 as my_date
but this don't work:
select * from (select 20181107 as my_date) c
the error is:
Error in semantic analysis: ERROR-0-HIVE:00003:{semantic error => sub query must have a from clause!!}}
I really need a sql only with select some constants but no from table
how to avoid this error?

probably you should to find the equivalent of this date and try, for example in mysql is CURDATE
select * from (select CURDATE as my_date from dual) c
but if you want the actual date I think you'd better do something of similar of this
select * from (select DATE(20181107,'YYYYMMDD') as my_date from dual) c
you should to see the documentation of your database
for example you can use something of similar
TO_DATE('07-OCT-18','dd-MON-yy')
or
TO_DATE('07-OCT-18')

Related

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")

Setting a variable in ANSI SQL

I am new to SQL and have been searching for a way to set variables in ANSI SQL. I have this:
select * from table1
where first_date > '2014-01-01'
and where second_date = '2014-01-01'
and where third_date < '2014-01-01'
but I am hoping for something like:
set x = '2010-12-31'
select * from table1
where first_date > x
and where second_date = x
and where third_date < x
I read about stored procedures but it seems like overkill for something so seemingly simple. I'm running on Netezza but I'd like a general solution that can also work on other databases.
Standard (ANSI) SQL does not have variables. But what you can do in standard SQL is use a common table expression to only have the value once.
The following is ANSI SQL:
with data (the_date) as (
values (date '2014-01-01')
)
select *
from table1
where first_date > (select the_date from data)
and second_date = (select the_date from data)
and third_date < (select the_date from data);
The above would work on most DBMS. Not all of them support the values clause like that, but that can usually be worked around using a plain select statement instead.
As I have never used Netezza I have no idea if it supports the row constructor (the values clause) or common table expressions (the with clause)
Also some SQL clients offer the ability to define variables that are replaced before the SQL is actually sent to the database server.
a_horse_with_no_name's solution is the only pure SQL solution I know that doesn't go into procedural SQL extenion territory. There is another solution that is not strictly what you asked for as it is specific to the NZSQL CLI only, but you can use variables there like this.
TESTDB.ADMIN(ADMIN)=> \set x '\'2014-01-01\''
TESTDB.ADMIN(ADMIN)=>
SELECT *
FROM table1
WHERE first_date < :x
AND second_date = :x
AND third_date = :x;

Sybase - Subquery in FROM clause

I'm using Sybase ASE 12.5.0.3 and I'm unable to do subqueries like:
select * from (select '1' union select '2' ) X
I've been looking around and as far as I know it should be possible after Sybase ASE 12, am I doing something wrong, or is it not possible with this version???
Edit - Even after changing the query to:
select * from (select '1' as col1 union select '2' as col1 ) X
So even giving alias to the columns, it fails anyways...
Without seeing an error message, it appears that you need to give column aliases in your sub-query:
select *
from
(
select '1' as yournewCol
union
select '2' as yournewCol
) X
You need to give your columns name. Try this:
Sybase ASE does not support subqueries in the FROM clause:
Subqueries can be nested inside the where or having clause of an outer select, insert, update, or delete statement, inside another subquery, or in a select list. Alternatively, you can write many statements that contain subqueries as joins; Adaptive Server processes such statements as joins.

How to replace a nested select with "group by" with a "having" clause?

My SQL is getting somewhat rusty and the only way I have managed to retrieve from a table the ids of the newest records (based on a date field) of the same type is with a nested select, but I suspect that there must be a way to do the same with a having clause or something more efficient.
Supposing that the only columns are ID, TYPE and DATE, my current query is:
select ID from MY_TABLE,
(select TYPE as GROUP_TYPE,
max(DATE) as MAX_DATE
from MY_TABLE group by TYPE)
where TYPE = GROUP_TYPE
and DATE = MAX_DATE
(I'm writing it from my memory, maybe there are some syntax errors, but you get the idea)
I'd prefer to stick to pure standard SQL without proprietary extensions.
Then there is no "more efficient" way to write this query. Not in standard ANSI-SQL. The problem is that you are trying to compare an AGGREGATE column (Max-date) against a base column (date) to return another base column (ID). The HAVING clause cannot handle this type of comparison.
There are ways using ROW_NUMBER (windowing function) or MySQL (group by hack) to do it, but those are not portable across database systems.
SELECT a.id, a.type, a.dater
from my_table a inner join
(
select type, max(dater) as dater2
from my_table
group by type
) b
on a.type= b.type and a.dater= b.dater2
This should get you closer depending on your data
select ID from MY_TABLE
where (DATE = (select max(DATE) from MY_TABLE as X
where X.TYPE = MY_TABLE.TYPE)

Subselect in pgSQL

I'm trying to do a subselect in pgsql aka postgresql and the example I found doesn't work:
SELECT id FROM (SELECT * FROM table);
I just needed to add an AS for the subselect, like so:
SELECT id FROM (SELECT * FROM table) AS aliasname;
I think you need something like:
SELECT * FROM table WHERE id IN (SELECT id FROM table2);
I don't understand what your non-working subquery is attempting to do, it seems like you could just say SELECT id FROM table because presently its not valid SQL92 syntax.