Select statement subquery, multiple conditions - sql

I am trying to create a query to select a certain condition then within that condition select two other conditions.
Breaking it down.
SELECT condition 1 FROM column 2, if this condition is not met return nothing.
SELECT condition 2 FROM column 3, SELECT condition 3 FROM column 4, if either of these two conditions are met return the respective column value from that rows value.
My feeble attempt which gives an obvious syntax error,
SELECT Column_1
FROM Data_TBL
WHERE Column_2 = 'Condition_1'
GROUP BY(WHERE Column_3 = 'Condition_2' OR Column_4 = 'Condition_3')
ORDER BY Column_1 ASC
Still very new to SQL statements and I am struggling with the syntax.

I think you just need a where clause. For the filtering:
select t.*
from data_tbl t
where (column2 = 'Condition_1') and
(column3 = 'Condition_2' or column4 = 'Condition_3);
I'm not sure what you want to return when both column3 and column4 meet the respective conditions, but I think this is what you want:
select (case when column3 = 'Condition_2' then column3 else column4 end)
from data_tbl t
where (column2 = 'Condition_1') and
(column3 = 'Condition_2' or column4 = 'Condition_3);

Related

How to use CASE statement in SQL to change an empty field in one column based on another column

I'm just starting with SQL with no training but the job suddenly requires it. So thank you in advance for any help.
Let's say I have a query that returns 3 columns. Some of the cells in column 3 are empty and I would like to fill them in with values based on column1.
example:
CASE column1 = 'Individual' then Column3 should show 'Individual' not empty, but if column1 = 'group' them column3 needs to show "group" else no change.
SELECT column1, column2, column3,
CASE
WHEN column1 = 'Individual' THEN Column3 = 'Individual'
WHEN column1 = "Group' THEN comlumn3 = 'Group'
END
FROM tablename
If you only want to select data and not change the table values you can use case as you tried:
SELECT column1, column2,
CASE
WHEN column3 IS NULL THEN Column1
ELSE column3
END as column3
FROM tablename

PostgreSQL count multiple columns of the same table

I want to count some columns from a table in PostgreSQL.
For each column count I have some conditions and I want to have all in one query. My problem is the fact that I don't get the expected results in counting because I tried to apply all the conditions for the entire data set.
The table:
column1
column2
column3
UUID10
UUID20
UUID30
NULL
UUID21
NULL
NULL
UUID22
UUID31
UUID11
UUID20
UUID30
This is what I tried so far:
SELECT
COUNT(DISTINCT column1) AS column1_count,
COUNT(DISTINCT column2) AS column2_count,
COUNT(DISTINCT column3) AS column3_count
FROM TABLE
WHERE
column2 IN ('UUID20', 'UUID21', 'UUID22')
AND column1 = 'UUID10' -> this condition should be removed from this where clause
OR column3 IN ('UUID30', 'UUID31')
Result:
column1_count
column2_count
coumn3_count
2
3
2
The result in not correct because I should have column1_count = 1. I mean, this is what the query does, but is not what I intended. So I thought to have some constrains for column2 and column3 in a subquery, and having a another condition just for column1.
A second try:
SELECT *
FROM
(
SELECT
column1
column2,
column3
FROM TABLE
WHERE
column2 IN ('UUID20', 'UUID21', 'UUID22')
OR column3 IN ('UUID30', 'UUID31')
) x
WHERE
column1 = 'UUID10'
Result:
column1_count
column2_count
coumn3_count
1
1
1
Because the last condition on column1 is restricting my result, I end up having 1 for all the counts.
How can I apply different conditions for counting each column?
I would try not to use UNION if is possible. Maybe there can be made some subqueries in another way than what I tried so far. I just have to find a way for the constraint for the column1, to not be on the same WHEN clause as for the column2 and column3.
I think you want conditional aggregation:
SELECT COUNT(DISTINCT CASE WHEN column1 = 'UUID10' THEN column1 END) AS column1_count,
COUNT(DISTINCT column2) AS column2_count,
COUNT(DISTINCT column3) AS coumn3_count
FROM TABLE
WHERE column2 IN ('UUID20', 'UUID21', 'UUID22') OR
column3 IN ('UUID30', 'UUID31');
I assume that you are aware that COUNT(DISTINCT CASE WHEN column1 = 'UUID10' THEN column1 END) is not particularly useful code. It returns 1 or 0 depending on whether the value is present. I assume your code is actually more interesting.

While executing case when both when and else part is working in oracle

I have used case when in select query and it executing both when and else part. please give a solution to come out of this.
SELECT column2
FROM template_Data_Details_bkp
WHERE template_id = (SELECT template_id
FROM templates
WHERE template_name = 'Testing')
AND column1 = 'EM1'
AND (CASE
WHEN (column2 = 'stock' AND column1 = 'EM1')
THEN
column2
ELSE
(SELECT column2
FROM template_data_details_bkp
WHERE template_id =
(SELECT template_id
FROM templates
WHERE template_name = 'Testing')
AND column1 = 'EM1'
AND column4 = 'YES')
END) = column2;
The Table looks like
column1
column2
column4
EM1
stock
NO
EM1
ragavi
YES
I excepting column2 value- stock,
but it returns both the values
Maybe you have two rows.
In the first row, the case statement enters into WHEN (column2 = 'stock' AND column1 = 'EM1')
In the second row, the statement enters into ELSE
You have one result per row.
If you want to see just one row, skip the else statement, or clean your WHERE statement and make it easier.
Regards.

ORACLE UPDATE SAME TABLE

I am getting error while updating one set of data by applying condition (LESS THAN SYMBOL) with other set of data on same table. could someone please help me.
Below is my oracle query -
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) <
(SELECT TRUNC(COLUMN4)
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y')
ERROR AS BELOW -
SQL Error:
ORA-01427: single-row subquery returns more than one row
01427. 00000 - "single-row subquery returns more than one row"
*Cause:
*Action:
First some homework; please do not call your table TABLE (Oracle will complain). Additionally your subquery doesn't make sense:
(SELECT TRUNC(COLUMN4)
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y')
If COLUMN4 = 'Y what does TRUNC(COLUMN4) mean?
But I guess what you mean is this (sample data added)
create table TAB as
select 1 COLUMN1, 'Y' COLUMN2, 'N' COLUMN3, sysdate-1 COLUMN4 from dual union all
select 2 COLUMN1, 'Y' COLUMN2, 'Y' COLUMN3, sysdate COLUMN4 from dual union all
select 2 COLUMN1, 'Y' COLUMN2, 'Y' COLUMN3, sysdate COLUMN4 from dual;
UPDATE TAB
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) <
(SELECT TRUNC(COLUMN4)
FROM TAB
WHERE COLUMN2 = 'Y' AND COLUMN3 = 'Y');
Which leads to
ORA-01427: single-row subquery returns more than one row
The problem is, with < you can compare only two numbers, if you want to compare a number with a set of numbers (= result of a subquery with more rows), you must use the Group Comparison Conditions. Two choices are available:
< ALL - the predicate is valid for ALL values returned by the subquery
< ANY / < SOME the predicate is valid for SOME (at least one) value returned by the subquery .
So what you can do this for example
UPDATE TAB
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y'
AND COLUMN3 = 'N'
AND TRUNC(COLUMN4) < ALL
(SELECT TRUNC(COLUMN4)
FROM TAB
WHERE COLUMN2 = 'Y' AND COLUMN3 = 'Y');
Update will be done in rows with TRUNC(COLUMN4) less than **ALL* values returned by the subquery.
I think the message is pretty clear. Perhaps you should use an aggregation function:
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y' AND
COLUMN3 = 'N' AND
TRUNC(COLUMN4) < (SELECT MIN(TRUNC(COLUMN4))
FROM TABLE
WHERE COLUMN3 = 'Y' AND COLUMN4 = 'Y'
);
EDIT:
Given the columns you've specified, this could be simplified to:
UPDATE TABLE
SET COLUMN1 = 1
WHERE COLUMN2 = 'Y' AND
COLUMN3 = 'N' AND
TRUNC(COLUMN4) < 'Y';
You might need an additional condition, if the purpose of the subquery was to see if any rows exist.

SELECT from CTEs which might be null/undefined

Inside a function/stored procedure in Postgres 9.6 I want to grab data from two different tables using one CTE for each table like so:
WITH "CTE_from_table1" AS (SELECT column1, column2 FROM table1 WHERE id = $1),
"CTE_from_table2" AS (SELECT column1, column2 FROM table2 WHERE id = $2)
SELECT
COALESCE(
"CTE_from_table1".column1,
"CTE_from_table2".column1,
CASE WHEN "CTE_from_table1".column2 = 42 OR "CTE_from_table2".column2 = 42
THEN 'Something is 42' ELSE 'something else!' END
)
FROM "CTE_from_table1","CTE_from_table2";
(Data type of column1 and column2 are resp. identical for both tables: column1 being a text, column2 an integer.)
That works as long as both CTEs are defined. The problem is: The parameters $1 and/or $2 could be null or could contain IDs which are simply not there. In this case, I expect the result something else!, because the first two COALESCE parameters evaluate to null and the third, being the CASE WHEN, should go to its ELSE which would return something else!.
That's my theory. However, in practice I get null as soon as one of the CTEs is undefined/null. What can I do about that?
Your problem is the dreaded comma in the FROM clause. Simple rule . . . Never use commas in the FROM clause. In this case, you want an "outer cross join". The comma does an "inner cross join", so no rows are returned if either CTE has no rows.
Unfortunately, OUTER CROSS JOIN doesn't exist, so you can make do with FULL OUTER JOIN:
WITH "CTE_from_table1" AS (SELECT column1, column2 FROM table1 WHERE id = $1),
"CTE_from_table2" AS (SELECT column1, column2 FROM table2 WHERE id = $2)
SELECT COALESCE(ct1.column1, ct2.column1,
CASE WHEN 42 IN (ct1.column2, ct2.column2)
THEN 'Something is 42'
ELSE 'something else!'
END
)
FROM "CTE_from_table1" ct1 FULL OUTER JOIN
"CTE_from_table2" ct2
ON 1=1;
I'm not a big fan of mixing CASE and COALESCE(), so I'd be inclined to write:
SELECT (CASE WHEN ct1.column1 IS NOT NULL THEN ct1.column1
WHEN ct2.column1 IS NOT NULL THEN ct2.column1
WHEN 42 IN (ct1.column2, ct2.column2) THEN 'Something is 42'
ELSE 'something else!'
END)