using define to store the result of a select statement - sql

Good evening, i want to ask about the feasibility of something so i have a select statement inside this select a lot of similare subqueries
i want to use a sub-query only once and store it's result I have tried something like that but I don't know what to do
any help would be appreciated
define A = Select somthing from TableA
Select case
when A <0
then 1
else 2
End as selectedcolumn from TableB
But i think that define is used only with static values

You can do this with a CTE, e.g.
WITH A AS
SELECT COUNT(*) c FROM TableA A
WHERE A.ColumnA = B.ColumnB
AND A.ColumnA2 = 0
Select A.c As test
from TableA ta
inner join TableB tb
on ta.columnA=tb.columnB
cross join A
This will make A.c available in your query. You can also then do (select c from A) anywhere in your query to get the value.
Alternately, if you're running a script in SQL*Plus, you can define a column variable using new_value:
COLUMN my_count NEW_VALUE my_constant
SELECT COUNT(*) my_count FROM TableA A
WHERE A.ColumnA = B.ColumnB
AND A.ColumnA2 = 0;
Then you can refer to it later on in your script using the substitution string &&my_constant:
Select case
when &&my_constant <0
then 1
else 2
End as selectedcolumn from TableB

Related

How can I use a comparison operator in a DELETE in PostgreSQL?

DELETE FROM tableA a
WHERE 0 = (SELECT b.quantity
FROM tableB b
WHERE a.id=b.id)
This is a example query, but i need to say if i can use the comparison operator = after the WHERE.
Try this:
DELETE FROM tableA
WHERE Id IN(SELECT id FROM tableB WHERE quantity=0)

Conditional join in SQL depending on a column value

I'm trying to do a join on a SAS table using PROC-SQL. Depending on the value of one variable in table A I need to join using a column, otherwise I need to use another column.
proc sql;
create table test
as select
A.*,
A.PPNG_RVNE * B.perc_ress as variable1,
A.P_RVNE * B.perc_ress as variable2
from tableA as A
left join tableB as B
on case when A.cod_cia = 1 then A.cod_cia=B.cod_cia and A.cod_agrup_produto=B.cod_agrup_produto
else A.cod_cia=B.cod_cia and A.projeto=B.projeto;
I need to join just to create variable1 and variable2. I don't want to select any variable from table B.
My cod doesn't run. SAS gives me an error message saying that it is expecting an `end.
Does anyone know how to conditional join depending on columns?
Don't use case. Just express the logic booleanly"
proc sql;
create table test as
select A.*, A.PPNG_RVNE * B.perc_ress as variable1, A.P_RVNE * B.perc_ress as variable2
from tableA A left join
tableB B
on A.cod_cia = B.cod_cia and
(A.cod_cia = 1 and A.cod_agrup_produto = B.cod_agrup_produto) or
(A.cod_cia <> 1 and A.projeto = B.projeto);
Note: This uses <> 1. If cod_cia could be NULL you need to take that into account. Also note that this factors out the first condition.
Not a PROC-SQL user so apologies if this is wrong, but based on this question a case statement needs the format:
CASE
WHEN ... THEN ...
WHEN ... THEN ...
ELSE ...
END
So have you tried:
proc sql;
create table test
as select
A.*,
A.PPNG_RVNE * B.perc_ress as variable1,
A.P_RVNE * B.perc_ress as variable2
from tableA as A
left join tableB as B
on case when A.cod_cia = 1 then A.cod_cia=B.cod_cia and A.cod_agrup_produto=B.cod_agrup_produto
else A.cod_cia=B.cod_cia and A.projeto=B.projeto
end;
I would use two joins and a coalesce statement:
proc sql;
create table test
as select
A.*,
A.PPNG_RVNE * coalesce(B1.perc_ress,B2.perc_ress) as variable1,
A.P_RVNE * coalesce(B1.perc_ress,B2.perc_ress) as variable2
from tableA as A
left join tableB as B1
on A.cod_cia = 1 and A.cod_cia=B1.cod_cia and A.cod_agrup_produto=B1.cod_agrup_produto
left join tableB as B2
on A.cod_cia=B2.cod_cia and A.projeto=B2.projeto;
you could add A.cod_cia ne 1 in the second join, but it's not necessary unless.

SQL Query efficiency (JOIN or Cartesian Product )

Hello I am Confused with three scenarios which commonly every one use in almost every project.
I wanted to Know which one of these will be Efficient accordinng to - Less Time Complexity - Efficiency - effectiveness
TableA (userid ,username, email , phone)
TableB (username,TestField)
.
Case 1
select email, TestField from TableA , TableB
where TableA.username = TableB.username and
TableB.username = 'ABC'
group by email, TestField
Case 2
select email, TestField from TableA
inner join TableB on TableB.username = 'ABC'
Case 3
declare #uname nvarchar(20);
set #uname = 'ABC';
declare #Email nvarchar(20);
select #Email= email from TableA where username = #uname;
select #Email as email , TestField from TableB
where username = #uname
Case 2 will give you a different output anyway, as you are not joining TableA and TableB in any way so you get a Cartesian product.
Since all of a sudden email came up, you will need a join in case 1:
In Case 1 you can simply rewrite the query to
SELECT DISTINCT A.Email , B.TestField
FROM TableA A join TableB B on A.username = B.Username
WHERE B.username = 'ABC'
Which is more readable and easier to maintain as you do not ave a superfluous GROUP BY clause.
In Case 3 you have userId in your where clause, which is not even in your tableB according to your post.
In general, for maintainability and readibility:
Use explicit joins
SELECT * FROM A JOIN B ON A.id = B.id
is preferable over
SELECT * FROM A, B WHERE A.id = B.id
And use DISTINCT when you want distinct values, instead of GROUP BY over all columns:
SELECT DISTINCT a, b, b FROM TABLE
is preferable over
SELECT a, b, c FROM TABLE GROUP BY a, b, c
Most database experts will tell you that cross products are evil and to be avoided. Your first example would work just fine. It is an implicit inner join.
Your second example is syntactically incorrect. I suspect you'd get an error from MSSQL Server Manager. What you probably meant was:
select a.email, b.TestField
from TableA a inner join TableB b
on (b.username = a.username)
where b.username = 'ABC'
Your first example will probably be the more efficient, since MSSQL Server is smart enough to do the projection on TableB.username before doing the join. I'm not so certain that this would be the case in the above version of case 2.
To be sure you could do it like this:
select a.email, b.TestField
from TableA a inner join
(select * from TableB where TableB.username = 'ABC') b
on (b.username = a.username)
where b.username = 'ABC'
Hope that helps.

Oracle select distinct syntax error

Why oracle doesn't recognize this sentence ? It says "From keyword" wasn't found where expected. What's wrong with it ?
Example:
select distinct a.id = b.id
from table1 a, table2 b
where a.column = X and b.column =Y;
MySQL allows me to do that. So what should I change ?
Your problem is that a.id = b.id is not valid sql when it's in the select clause.
Edit Below
Given your comment about expecting a boolean result, maybe you are looking for a case construct.
select case when a.id = b.id then 1 else 0 end BooleanResult
from tablea a join tableb b on something
where etc
First off, Oracle does not have a boolean data type in SQL (there is a boolean data type in PL/SQL) so a query cannot return a boolean.
You can do something like
select distinct (case when a.id = b.id
then 1
else 0
end)
from table1 a,
table2 b
where a.column = X
and b.column = Y;
It strikes me as terribly unlikely, however, that you really want to do a Cartesian product between table1 and table2 only to then apply a DISTINCT operator. Frequently, people incorrectly add a DISTINCT to a query when what they really want to do is add another join condition. I would expect that you really want
select distinct (case when a.id = b.id
then 1
else 0
end)
from table1 a,
table2 b
where a.some_key = b.some_key
and a.column = X
and b.column = Y;
Once you have the join defined correctly, you may no longer need the expense of the extra DISTINCT.
Here is it
select distinct a.id, b.id
from table1 a, table2 b
where a.column = X and b.column =Y;
You can also use decode in oracle
select distinct (decode (a.id,b.id,1,0)) from table1 a, table2 b
where a.some_key = b.some_key
and a.column = X ;

SQL Conditional filter with different values

I have found lots of posts on coniditonal filtering in the where clause, but they all seem to be based off of using the same value, such as:
WHERE (o.OrderID = #orderid OR #orderid IS NULL)
I need to do something slightly different, I need to remove a filter and its value completely base on another value, so something like:
select *
from tableA
where 1 = 1
case when a = 1 then
and b in (select b from tableB)
else
-- do nothing
end
I know that the above is not allowed, and I am just writing as an example of what I am trying to do. does Anyone have any idea of a good way to do this? I know i could use if statements and duplicate the query, but it is a large one, and i am trying to avoid that.
Thanks
SELECT *
FROM tableA
WHERE a <> 1
OR (a = 1 AND EXISTS(SELECT b from TableB WHERE tableA.b = TableB.b))
You could also write this as:
SELECT tableA.*
FROM tableA
LEFT JOIN tableB
ON tableA.b = tableB.b
WHERE tableA.a <> 1
OR (tableA.a = 1 AND tableB.b IS NOT NULL)
"Correcting" your WHERE clause:
select *
from tableA
where 'T' = case
when a = 1 then case
when b in (select b from tableB) then 'T'
end
else 'T'
end;