Using CASE to Mark No If No Results From SELECT Statement - sql

is it possible to print "no" if no result found
SELECT mobileno,
CASE
WHEN region = '1234'
THEN 'Yes'
ELSE 'NO'
END
FROM subscriber
WHERE region = '1234'
and status = 1
and mobileno in (77777,88888)
Currently it only print 1 row like
77777,yes
but i want like following
77777,yes
88888,no
Update: One mobileno like 7777 may belongs from two regions then 7777 will get print with NO and YES in two rows if we remove region condition.
Sample Data
sr.No, Name, mobileno, region, status
1, abc, 77777, 1234, 1
2, xyz, 88888, 1222, 1
3, tyu, 22342, 9898, 1
4, abc, 77777, 8787, 1
Sample OutPut
77777, Yes
88888, No

You can 'create' a table by selecting from dual, and left joining :
SELECT t.dummy_num,
CASE WHEN s.mobileno is null then 'No' else 'Yes' end
FROM (SELECT 77777 as dummy_num from dual
UNION select 88888 from dual) t
LEFT JOIN subscriber s
ON(t.dummy_num = s.mobileno and s.region = '1234' and s.status = 1 )
Edit: you can also do it dynamically like this:
SELECT t.mobileno,
CASE WHEN s.mobileno is null then 'No' else 'Yes' end
FROM (select distinct mobileno from subscriber) t
LEFT JOIN subscriber s
ON(t.mobileno= s.mobileno and s.region = '1234' and s.status = 1 )
WHERE t.mobileno IN(777,888,.....)

Related

how to avoid duplicates in hive query

I have two tables:
table1
the_date | my_id |
02/03/2021,123
02/03/2021, 1234
02/03/2021, 12345
table2
the_date | my_id |seq | txt
02/03/2021, 1234, 1 , 'OK'
02/03/2021, 12345, 1, 'OK'
02/03/2021, 12345, 2, 'HELLO HI THERE'
02/03/2021, 123456, 1, 'Ok'
Here is my code:
WITH AB AS (
SELECT A1.my_id
FROM DB1.table1 A1 , DB1.MSG_REC A2 WHERE
A1.my_id=A2.my_id
),
BC AS (
SELECT AB.the_date
COUNT ( DISTINCT (CASE WHEN (TXT like '%OK%') THEN AB.my_id ELSE NULL END )) AS
CASE1 ,
COUNT ( DISTINCT (CASE WHEN (TXT like '%HELLO HI THERE%') THEN AB.my_id ELSE NULL END )) AS
CASE2
FROM AB left JOIN DB1.my_id BC ON AB.my_id =BC.my_id
The issue that stems from above is I am looping over the value '12345' twice because it satisfies both of the case statements.
That causes data duplicates when capturing metrics of the counts. Is there a way to execute the first case and then perform the second case but exclude looping any of the "my_id' records from the first case.
So for example, when it is time to run the above script and the first case executes, it will pick up the below records and the count would be 3
02/03/2021, 1234, 1 , 'OK'
02/03/2021, 12345, 1, 'OK'
02/03/2021, 123456, 1, 'Ok
The second case should only be looping through the below records and the count would be only 1
02/03/2021, 12345, 2, 'HELLO HI THERE'
CASE1 would be 4 and CASE2 would by 2 if I don't create a condition to circumvent this issue. Any tips or suggestions?
Assign case to each your ID before DISTINCT aggregation . After that do distinct aggregation, in such way you will eliminate same IDs counted in different cases. See comments in the code:
select --do final distinct aggregation
count(distinct (case when assigned_case='CASE1' then my_id else null end ) ) as CASE1,
count(distinct (case when assigned_case='CASE2' then my_id else null end ) ) as CASE2
from
(
select my_id
--assign single CASE to all rows with the same id based on some logic:
case when case1_flag = 1 then 'CASE1'
when case1_flag = 1 then 'CASE2'
else NULL
end as assigned_case
from
(--calculate all CASE flags for each ID
select AB.my_id,
max(CASE WHEN (TXT like '%OK%') THEN 1 ELSE NULL END) over (partition by AB.my_id) as case1_flag
max(CASE WHEN (TXT like '%HELLO HI THERE%') THEN 1 ELSE NULL END) over (partition by AB.my_id) as case2_flag
from ...
) s
) s

unexpected results of a left join

I have a table named test_table_1 and a view named temp_test_view_1.
The goal is to find the NEW_CATEGORY_ID for every ID in the test_table_1. The relationship between NEW_CATEGORY_ID and ID is in the view temp_test_view_1
I use the left join for that purpose, with the base table being test_table_1.
In my opinion, the left join returns some unexpected results.
Here is all the data contained in table test_table_1:
select * from test_table_1:
id name
1 'a'
null 'd'
3 'd'
2 'c'
2 'b'
Here is the view script:
create view temp_test_view_1 as
select
id,
id_description,
case when id_category = 'phone_id' then 'phone' else 'other' end as new_id_category
from (
select
1 as id,
'first id' as id_description,
null as id_category
from dummy
union all
select
2 as id,
'second id' as id_description,
'phone_id' as id_category
from dummy
) x
;
Here is the query I use to left join the view to a table and then project the results to see the corresponding new_id_category for every ID in test_table_1:
select
t1.id,
t1.name,
t2.id,
t2.id_description,
t2.new_id_category
from test_table_1 t1
left join temp_test_view_1 t2 on t1.id = t2.id
output is:
id name,id id_description new_id_category
null 'd' null null, 'other'
1 'a' 1 'first id' 'other'
2 'b' 2 'second id' 'phone'
2 'c' 2 'second id' 'phone'
3 'd' null null 'other'
desired output:
id name,id id_description new_id_category
null 'd' null null, null
1 'a' 1 'first id' 'other'
2 'b' 2 'second id' 'phone'
2 'c' 2 'second id' 'phone'
3 'd' null null null
Can someone explain whether the result the query produces is correct and why if so? I expect this left join to return null on the columns retrieved from the view, as u can see from my desired outcome.
I did not test the query in DB systems offered by other vendors.
EDIT:
I tested it on sqlfiddle MS SQL, and it produces the desired output. Here is the link:
sqlfiddle.com/#!18/1c788/2
If someone needs the code itself to reproduce the results in MS SQL, (while he will fail to reproduce the resulst and instead get the desired result):
create view temp_test_view_1 as
select
id,
id_description,
case when id_category = 'phone_id' then 'phone' else 'other' end as new_id_category
from (
select
1 as id,
'first id' as id_description,
null as id_category
union all
select
2 as id,
'second id' as id_description,
'phone_id' as id_category
) x
;
select *
into test_table_1
from (
select
1 as id,
'a' as name
union all
select
2 as id,
'b' as name
union all
select
2 as id,
'c' as name
union all
select
3 as id,
'd' as name
union all
select
null as id,
'd' as name
) x;
select
t1.id,
t1.name,
t2.id,
t2.id_description,
t2.new_id_category
from test_table_1 t1
left join temp_test_view_1 t2 on t1.id = t2.id

Looking for best way to execute Yes/No Query check in select statement

I was wondering if anyone could recommend the best way to execute this. I will introduce you to what I'm working on.
I've written a select query with some sub-queries which gets order records, I have a number business logic that these orders need to meet so that they come up on the report.
Additionally I've added a nested case statement which helps me determine is the business logic is met and it simply returns a Yes or a No. So far all looks great!
E.G.
Above is just a sample result for one order (29817). What I need to do next is only show Order_No when NOYESCHECK returns all YES's.
Nested Case statement:
(case when sm.supply_code='Project Inventory' and
(select po.order_no
from purchase_order_line_all po
where po.contract = sm.contract
and po.part_no = sm.part_no
and po.activity_seq = sm.activity_seq
and po.project_id = sm.project_id
and po.state in ('Closed','Arrived','Recieved') order by po.date_entered desc fetch first 1 row only) is not null then 'YES'
when sm.supply_code='Invent Order' and
( select sum(QTY_ONHAND - QTY_RESERVED)
from inventory_part_in_stock ipis
where ipis.contract = sm.contract
and ipis.part_no = sm.part_no
and ipis.QTY_ONHAND - ipis.QTY_RESERVED > '0'
and ipis.project_id is null
and ipis.AVAILABILITY_CONTROL_ID not in ('QUARANTINE','RD','TRANSIT','PRE SCRAP')
) is not null then 'YES'
else 'NO' end)NoYesCheck
What would be the best way to achieve this? I have tried using ALL operator but it didn't work quite as expected. What I tried with ALL operator:
and 'YES' = ALL (case when sm.supply_code='Project Inventory' and
(select po.order_no
from purchase_order_line_all po
where po.contract = sm.contract
and po.part_no = sm.part_no
and po.activity_seq = sm.activity_seq
and po.project_id = sm.project_id
and po.state in ('Closed','Arrived','Recieved') order by po.date_entered desc fetch first 1 row only) is not null then 'YES'
when sm.supply_code='Invent Order' and
( select sum(QTY_ONHAND - QTY_RESERVED)
from inventory_part_in_stock ipis
where ipis.contract = sm.contract
and ipis.part_no = sm.part_no
and ipis.QTY_ONHAND - ipis.QTY_RESERVED > '0'
and ipis.AVAILABILITY_CONTROL_ID not in ('QUARANTINE','RD','TRANSIT','PRE SCRAP')
and ipis.project_id is null
) is not null then 'YES'
else 'NO' end)
It seemed to return only lines with 'YES' in my check but the purpose here is:
If check is done per order and returns at least one 'No' then do not show the order. So in above image this order was never meant to show up as a result in my query but it did. So I'm a little stuck.
Any help would be appreciated. Let me know if I need to provide more info.
Thanks,
Kasia
You can use your NOYESCHECK column in a subselect within the where clause combined with a NOT IN check.
Psuedo code:
select
--main query columns
from data_source
where key_column not in (
select distinct
key_column
from (
select
key_column,
noyescheck_column
from data_source
where noyescheck_column = 'NO'
)
)
Would this help? See comments within code.
SQL> with
2 -- this is what your query currently returns
3 test (order_no, component_part, noyescheck) as
4 (select 29817, 100, 'NO' from dual union all
5 select 29817, 101, 'YES' from dual union all
6 --
7 select 30000, 200, 'YES' from dual union all
8 select 30000, 201, 'YES' from dual union all
9 --
10 select 40000, 300, 'NO' from dual
11 ),
12 -- find ORDER_NOs whose NOYESCHECK = YES only
13 yess as
14 (select order_no
15 from test
16 group by order_no
17 having min(noyescheck) = max(noyescheck)
18 and min(noyescheck) = 'YES'
19 )
20 -- return only ORDER_NOs that satisfy condition
21 select t.*
22 from test t join yess y on y.order_no = t.order_no;
ORDER_NO COMPONENT_PART NOY
---------- -------------- ---
30000 200 YES
30000 201 YES
SQL>

Want to Return Empty Rows With a Case When Statement

Lets say I'm using 2 case when statements to group my data, like in the below example:
select case
when group1 = 'A' then 'Large'
when group1 = 'B' then 'Medium'
else 'Small'
end as 'Order Size'
,case
when method = 'Delivery' then 'Delivery'
else 'Pick-up'
end as 'Distribution Method'
,count(distinct(OrderIDs))
from OrderTable
GROUP BY
select case
when group1 = 'A' then 'Large'
when group1 = 'B' then 'Medium'
else 'Small'
end
,case
when method = 'Delivery' then 'Delivery'
else 'Pick-up'
end
Lets also say that there were no "Large" deliveries that were "Pick-Up'. Currently, this query will not return a row with Large,PickUp category.
Is there a way to have a row returned with 0’s if there is nothing that meets the multiple case when criteria?
Use a cross join to generate the rows and left join to bring in the data:
select os.OrderSize, coalesce(d.DistributionMethod, 'Pick-Up') as
count(*)
from (select 'Large' as OrderSize union all
select 'Medium' as OrderSize union all
select 'Small' as OrderSize
) os cross join
(select 'Delivery' as DistributionMethod union all
select 'Pick-Up' as DistributionMethod
) d left join
OrderTable ot
on ( (ot.group1 = 'A' and os.OrderSize = 'Large') or
(ot.group1 = 'B' and os.OrderSize = 'Medium') or
(ot.group1 not in ('A', 'B') and os.OrderSize = 'Small')
) and
ot.method = d.DistributionMethod
group by os.OrderSize, coalesce(d.DistributionMethod, 'Pick-Up');
Not all databases support the creation of a table of constants using this syntax, but there is generally some syntax that does this.
You could select a recordset that contains the required values and then left join your grouped recordset from there. Following is an example for SQL Server where you would join your results to [Groupings].[OrderSize] and [Groupings].[DistributionMethod]:
SELECT *
FROM (
SELECT *
FROM (
SELECT 'Large' AS [OrderSize]
UNION
SELECT 'Medium' AS [OrderSize]
UNION
SELECT 'Small' AS [OrderSize]
) AS [OrderSizes]
CROSS JOIN (
SELECT 'Delivery' AS [DistributionMethod]
UNION
SELECT 'Pick-up' AS [DistributionMethod]
) AS [DistributionMethods]
) AS [Groupings]
LEFT JOIN ...

CASE in sub query with SELECT

This is the query that I've written
SELECT id, name, (SELECT is_enable FROM customers WHERE id=table_one.id) AS some_tag FROM table_one;
The above query returns the date like this
ID NAME SOME_TAG
4 name 1 0
3 name 2 0
1 name 3 1
I'm trying to fit in a CASE in the above query so that I get the value of SOME_TAG as "Yes" when 1 and "No" when 0 but no luck so far. Any help/leads will be appreciated! Thanks!
So far I tried this
select id, name, (select is_enable case when is_enable is not null then "No" else "Yes" end from customers where id=table_one.id) as some_tag from table_one;
You can use a join instead of a sub-query... and then this is how'd the case would work.
SELECT
t.id,
t.name,
case when c.is_enabled = 1 then 'Yes' else 'No' end
from
table_one t
left join customers c on
c.id = t.id
Below code also works for your problem
SELECT
id,
name,
(CASE is_enable
WHEN 1 THEN 'YES'
WHEN 0 THEN 'NO'
END) AS TAG
FROM ( SELECT id, name, (SELECT is_enable FROM customers WHERE id=table_one.id) AS some_tag FROM table_one );