PostgreSQL Views: Referencing one calculated field in another calculated field - sql

I have the same question as #1895500, but with PostgreSQL not MySQL.
How can I define a view that has a calculated field, for example:
(mytable.col1 * 2) AS times_two
... and create another calculated field that's based on the first one:
(times_two * 2) AS times_four
...?

Depending on how heavy the formla is, you could use a subquery:
select inner.*, times_two * 2 from
(select mycol * 2 as times_two from table) sub
Or rewrite the computation:
select mycol * 2, mycol * 2 * 2 from table

Use this statement
CREATE VIEW view_name as SELECT column_name*2 as new_col1 , column_name*4 as new_col2 from table_name ;
select * from view_name ;
If you want use this view column values. use following things
create view new_viwe as select new_col1*2 as final_column from view_name ;
select * from new_view ;

Related

Referencing subqueries for SQL

I'd like to create a SQL subquery something like
(select *
from table t
where abc is true) as query_one;
select *
from query_one
group by abc
However, I keep running into syntax errors with trying to alias query_one... what's the right way to do this?
You can use a CTE:
with query_one as (
select *
from table t
where abc is true
)
select abc, count(*)
from query_one
group by abc;
Note that select * and group by do not belong together. This should be generating a syntax error.
Sounds like you're trying to create a view:
CREATE VIEW query_one AS
SELECT *
FROM t
WHERE abc = true
try this
select * from
(select *
from table t
where abc is true) query_one
group by abc

Convert from lateral view to case statements in hive

I need to place below code in case statement:
select
count (*)
from db.tab1
lateral view explode(secondary.tertiary) exp as lv
where id IN ('6','1') and array_contains (lv.ci, "1");
I have tried:
select
sum(
case
when id IN ('6','1')
and array_contains ((lateral view explode(secondary.tertiary)).ci, "1")
then 1
else 0
end)
from db.tab1;
But getting error.
select
count(*),
sum(if(..., 1, 0))
from db.tab1
lateral view explode(secondary.tertiary) exp as lv
;
For the provided SQL on table tab1, the actual logic is like:
Explode field secondary.tertiary, alias it as lv, which results in a temporary result set (table) tab2;
A join-like operation to concatenate tab2's fields back to rows in tab1, resulting in another intermediate table tab3;
Select from tab3, upon which where conditions are applied.

Reference a projected/selected column?

I project a column in my select statement. ("project" in the relational algebra sense.) With the goal of reducing code duplication, is there a way to reference that projected column in my where clause? Or is there a better way to do that?
Example:
select
(A.Column + A.Column2) * 8 'Column'
from A
where
(A.Column + A.Column2) * 8 < 1000
Basically, what I'm asking, if we think of columns as being "namespaced" by table (where A is a namespace and A.Column is the Column in the A namespace), is: is there a way to refer to the namespace for the ephemeral table we're currently selecting in the where clause of that table itself?
Another way is to use cte, common table expression.
with cte as(
select (A.Column + A.Column2) * 8 as [Column] from A
)
Select * from cte
Where [Column] < 1000
You can do it;
select * from
(
select (A.Column + A.Column2) * 8 as Col from A
) tmp
where Col<1000

select specific records using IN

I need to select records that has ID = 10,23,30 so I wrote this SQL
Select * from mytable where position(id in '10,23,30') > 0
But the problem I get additional records where ID = 1 and 2
Any ideas how to select only what I need ?
No need for position, just do IN:
Select * from mytable
where id in (10,23,30)
Use IN operator:
Select * from mytable where id in (10,23,30)

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END