IF Column has a value - sql

I need to write sql query to check whether the column y in a table x has a value. In python I can check that like
object.y = 1
if object.y:
<statements>
Like this I need to check in Postgres
this is my query:
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang = NULL and y is TRUE order by sequence""",([event_root]))
Here I need to check y has a value.

try this
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang = NULL and coalesce(y, FALSE) is TRUE order by sequence""",([event_root]))

This is my solved answer
request.cr.execute(""" select * from x where parent_id = %s and nav_include = true and website_published = true and cms_lang is NULL and y is not null order by sequence""",([event_root]))
reference: https://www.techonthenet.com/postgresql/is_not_null.php

Related

How to select twice the same column on join query?

How Can I to count the gender when is M or F, somehting like
SELECT count(N.gender)
FROM `DATABASE_T` as T
LEFT JOIN `DATABASE_N` as N
ON
T.ENCUESTA = N.ENCUESTA AND
T.P_DEPTO = N.P_DEPTO AND
T.P_MUNIC = N.P_MUNIC AND
T.COD_VEREDA = N.COD_VEREDA AND
T.PAIS = N.PAIS and
T.UC_UO = N.UC_UO
WHERE N.ID_PROD=1 and N.gender="M"
SELECT countif(N.gender = 'M') as M, countif(N.gender = 'F') as F
FROM `DATABASE_T` as T
LEFT JOIN `DATABASE_N` as N
ON
T.ENCUESTA = N.ENCUESTA AND
T.P_DEPTO = N.P_DEPTO AND
T.P_MUNIC = N.P_MUNIC AND
T.COD_VEREDA = N.COD_VEREDA AND
T.PAIS = N.PAIS and
T.UC_UO = N.UC_UO
WHERE N.ID_PROD=1
Since you did not describe the structure of your table and use Spanish-looking identifiers, I will use a clearer example with my own schema:
SELECT
SUM( CASE WHEN Sex = 'M' THEN 1 ELSE 0 END ) AS M,
SUM( CASE WHEN Sex = 'F' THEN 1 ELSE 0 END ) AS F
FROM People
WHERE People.Dept = 5

Select cases from long table by key variable grouping

I have a table like below:
caseid | ncode | code | test
1 1 ABC TRUE
1 2 DEF TRUE
2 1 ABC TRUE
3 1 DEF TRUE
3 2 HIJ FALSE
Where caseid represents an individual case. This table creates the relationship that each individual case can have multiple codes associated with it (ncode and code). test is just a variable that tracks a boolean value of interest.
I have specific requirements for my query:
I need all cases where code = ABC and ncode = 1 and test = TRUE. This criteria has the highest priority.
Of those cases from #1, I need to create an additional column called hasdef that is a boolean that indicates if that specific caseid has any other rows where code = DEF and test = TRUE. It should be TRUE if so, otherwise FALSE.
So from the above table, what should return is:
caseid | ncode | code | test | hasdef
1 1 ABC TRUE TRUE
2 1 ABC TRUE FALSE
caseid = 1 returns because code = ABC, ncode = 1, and test = TRUE. hasdef = TRUE because in the second row, caseid = 1, code = DEF and test = TRUE.
caseid = 2 returns because code = ABC, ncode = 1, and test = TRUE. hasdef = FALSE because there is no other row with caseid = 2 where code = DEF.
caseid = 3 does not return. Even though there is a row where code = DEF and test = TRUE, the first criteria (code = ABC and ncode = 1) is not first satisfied.
This is what I have so far, but I am not confident it is working as desired:
select tab1.*, tab2.code is not null as hasdef from
(select * from mytable
where code = 'ABC' and ncode = 1) as tab1
left join (
select caseid, any_value(code) code, any_value(test) test
from mytable
group by caseid
having code = 'DEF' and test is true
) as tab2
using(caseid)
order by caseid
Below is for BigQuery Standard SQL
#standardSQL
select * from (
select *,
0 < countif(code = 'DEF' and test is true) over(partition by caseid) as hasdef
from `project.dataset.table`
)
where code = 'ABC' and ncode = 1 and test is true
if to apply to sample data from your question - output is
Note: you can replace test is true with just test as in below
select * from (
select *,
0 < countif(code = 'DEF' and test) over(partition by caseid) as hasdef
from `project.dataset.table`
)
where code = 'ABC' and ncode = 1 and test

How to Update with subquery in PostgreSQL

I have a function in MS SQL Server just like this:
UPDATE r
SET
monthly =
(
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = #type_rel_aux
AND h.hcar_day > #date_month_before
AND h.hcar_day <= #date_base
)
FROM #Month_Table r
WHERE type = 1;
and thats the result (after update):
Seq monthly
2 102471,34
1 -5129,46
3 -29841,23
4 0
But when I execute the same update in a fuction in PostgreSQL, all the rows get the same value:
UPDATE Month_Table
SET variacao_mes_rs = (
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = v_type_rel_aux
AND h.hcar_day > v_date_month_before
AND h.hcar_day <= v_date_base) FROM Month_Table r WHERE type = 1;
Result (after update), all the same value of Seq 3:]
Seq monthly
1 -29841,23
2 -29841,23
3 -29841,23
4 -29841,23
I don't see the cause of the problem...
Does PostgreSQL have different rules on UPDATE?
Can anyone help me?
Remove the FROM clause from Postgres:
UPDATE Month_Table r
SET variacao_mes_rs = (
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = v_type_rel_aux
AND h.hcar_day > v_date_month_before
AND h.hcar_day <= v_date_base)
WHERE type = 1;
The FROM clause in an UPDATE behaves differently in the two databases, as you have discovered.

CASE expression in WHERE clause for diferent and

Can I use case expression to build where like this?
select *
from table
where
case
when x=y then z= j and t=v
when x=k then q= p and s=l
end
;
I need change where clause depending on the value of x variable.
Use or:
select *
from table
where (x = y and z = j and t = v) or (x = k and q = p and s = l);
An alternative to using OR is to use nested CASE statements:
SELECT *
FROM table_name
WHERE CASE
WHEN x = y THEN CASE WHEN z = j AND t = v THEN 1 ELSE 0 END
WHEN x = k THEN CASE WHEN q = p AND s = l THEN 1 ELSE 0 END
ELSE 0
END = 1;
or you could simplify it to:
SELECT *
FROM table_name
WHERE CASE
WHEN x = y AND z = j AND t = v THEN 1
WHEN x = k AND q = p AND s = l THEN 1
ELSE 0
END = 1;
However, you should check whether Oracle can use column indexes or if a separate function-based index is required with these solutions.

Rewrite subquery with calculation in SQL to CASE statement

I have, as a part of a bigger query, some subqueries that I would like to convert to CASE statements instead.
The subquery looks like this (and works):
(SELECT (((SUM(DAm)-(SUM(StcCst)*-1))*100)/NULLIF(SUM(DAm),0)) AS 'DG' FROM [F0001].[dbo].[ProdTr] WHERE AcYrPr = '201601' AND ProdTr.TrTp = 1 AND [F0001].[dbo].[ProdTr].CustNo = '12773') AS dg_period_1
However, I don't seem to find any logical way to put this into a CASE-statement.
Any help would be appreciated!
(
SELECT CASE
WHEN SUM(t1.DAm) <> 0
THEN (SUM(t1.DAm) + SUM(t1.StcCst)) * 100 / SUM(t1.DAm)
ELSE 0 /* or whatever you want to have in this case */
END AS 'DG'
FROM [F0001].[dbo].[ProdTr] t1
WHERE t1.AcYrPr = '201601' AND
t1.TrTp = 1 AND
t1.CustNo = '12773'
) AS dg_period_1
I also removed some unneeded parentheses and simplified an operation (x - (y * -1) = x + y)
You could use the following statement with CASE provided you want to return a null when SUM(DAm) is null or 0.
(SELECT CASE
WHEN SUM(DAm) IS NOT NULL and SUM(DAm) <> 0 THEN (((SUM(DAm) - (SUM(StcCst) * -1)) * 100) /SUM(DAm))
ELSE NULL
END AS 'DG'
FROM [F0001].[dbo].[ProdTr]
WHERE AcYrPr = '201601'
AND ProdTr.TrTp = 1
AND [F0001].[dbo].[ProdTr].CustNo = '12773') AS dg_period_1