I am trying to compare 2 column values in hive using the below sample data
m_bldg_id bldg_id Indicator
1911 1968 19657 19658 Not resident
19657 1968 19657 19658 resident
19658 1968 19657 19658 resident
1968 1968 19657 19658 resident
19887 1968 19887 19658 16755 17543 34213 resident
11132 1968 19887 19658 16755 17543 34213 Not resident
I need to write a case statement to identify the indicator where if m_bldg_id like bldg_id then indicator is resident.So for the first row in the above data, m_bldg_id of 1911 is not in 1968 19657 19658 so the indicator value is not resident.In the second row m_bldg_id has a value of 19657 which is present in
bldg_id value of '1968 19657 19658' so it should be resident.
I tried
CASE WHEN m_bldg_id like %bldg_id% then 'resident' else 'not resident' which did not work, please help
Concat the '%' with field you are comparing
select
m_bldg_id,
bldg_id,
case
when m_bldg_id like '%' + bldg_id + '%' then 'resident'
else 'Non resident'
end as Indicator
from
tablename
Use split() + array_contains():
select
m_bldg_id,
bldg_id,
case
when array_contains(split(bldg_id,' '),m_bldg_id ) then 'resident'
else 'Non resident'
end as Indicator
from tablename;
Or use instr() function:
case when instr(bldg_id, m_bldg_id) > 0 then 'resident' else 'Non resident' end as Indicator
Related
I have the following table:
tbl
ID vaccine_code vaccine_day
A 1A 0
A 2A 30
B moderna,1A 0
B moderna,2A 35
C moderna 0
C moderna 25
there are various ways in which the vaccines are coded in my database. 1A denotes first dose and 2A denotes second dose. At times, as in ID='C', the dose number is not denoted. In that case, I need to use the value in the vaccine_day column to extrapolate dose information.
I am looking for the following:
ID vaccine_dose vaccine_day
A dose1 0
A dose2 30
B dose1 5
B dose2 35
C dose1 0
C dose2 25
So far, I have:
select ID,
case when vaccine_code like '%1A%' then 'dose1'
case when vaccine_code like '%2A%' then 'dose2'
case when vaccine_code = 'moderna' and min(vaccine_day) then 'dose1'
case when vaccine_code = 'moderna' and max(vaccine_day) then 'dose1'
from tbl
group by vaccine_day;
You have a few issues with your query.
You don't end your case.
You group by vaccine_day which will return you each vaccine_day.
Didn't test it as I don't have the full sample data, both your sample data are the same id and days, but you can start with something like this:
select id, case when vaccine_code like '%1A%' then 'dose1'
when vaccine_code like '%2A%' then 'dose2'
when vaccine_code = 'moderna' and vaccine_day = min(vaccine_day) then 'dose1'
when vaccine_code = 'moderna' and vaccine_day = max(vaccine_day) then 'dose1'
end as vaccine_dose
from tbl
group by id, vaccine_code;
Consider the following tables
ID_TYPE
ID
TYPE
1
3
2
3
3
1
4
2
5
2
ID_HISTORY
DEBIT_ID
DEBIT_LOCATION
AMOUNT
CREDIT_ID
CREDIT_LOCATION
MONTH
3
LOC1
100
1
LOC5
MAY
4
LOC2
200
3
LOC6
MAY
2
LOC3
300
5
LOC7
MAY
1
LOC4
400
3
LOC8
JUNE
3
LOC9
500
2
LOC10
JUNE
Now suppose I want to fetch all rows from ID_HISTORY in the MONTH of MAY, and result should contain only these columns:
Id, Location, Amount
Cases:
Result should contain rows only where either DEBIT_ID or CREDIT_ID is of TYPE=3 in ID_TYPE table
If the DEBIT_ID is of TYPE = 3 in the ID_TYPE table, then pick DEBIT_ID as "Id", else pick CREDIT_ID as "Id"
Similarly, If the DEBIT_ID is of TYPE 3 in the ID_TYPE table, then pick DEBIT_LOCATION as "Location", else pick CREDIT_LOCATION as "Location"
For example, above tables should result in the following:
Id
Location
Amount
1
LOC5
100
2
LOC3
300
I know that something like the following should work:
SELECT
(CASE
WHEN (Tab.DEBIT_ID IN (
SELECT ID
FROM ID_TYPE Typ
WHERE Typ.TYPE = 3)
) THEN Tab.DEBIT_ID
ELSE Tab.CREDIT_ID END
) "Id",
(CASE
WHEN (Tab.DEBIT_ID IN (
SELECT ID
FROM ID_TYPE Typ
WHERE Typ.TYPE = 3)
) THEN Tab.DEBIT_LOCATION
ELSE Tab.CREDIT_LOCATION END
) "Location",
Tab.AMOUNT "Amount"
FROM (
SELECT *
FROM ID_HISTORY Tab
WHERE Tab.MONTH = 'MAY'
--this block will be very complicated and contain complex multi-level queries to fetch data
)
But as you can see this will be inefficient as I have to basically duplicate the full case logic for each conditional columns. Also, this is no way "clean" in case there are a lot of similar columns.
Also, if the case logic is complex, it will be inefficient even further. It would be better if i could select multiple columns in THEN / ELSE cases. I tried doing that, but it just gives me "ORA-00913: too many values" error.
What would be the optimized version?
You could use a join to remove the sub-queries:
SELECT CASE
WHEN typ.id IS NOT NULL
THEN h.debit_id
ELSE h.credit_id
END AS id,
CASE
WHEN typ.id IS NOT NULL
THEN h.debit_location
ELSE h.credit_location
END AS location,
h.AMOUNT
FROM (
SELECT *
FROM ID_HISTORY
WHERE MONTH = 'MAY'
-- this block will be very complicated and contain complex multi-level queries to fetch data
) h
LEFT OUTER JOIN (
SELECT id
FROM id_type
WHERE type = 3
) typ
ON (h.debit_id = typ.id)
I have a little problem with my SQL to concat 2 query in a same row.
Here's my first request:
SELECT lien, id,
CASE WHEN inactif = 0 THEN 'Oui' ELSE 'Non' END AS 'Actif'
FROM redirection.elementsOutils
WHERE lien LIKE '%saaprod/soutien_tache/redirection.asp%'
ORDER BY inactif, dateMAJ
Here's the result:
lien id Actif
http://saaprod/soutien_tache/redirection.asp?id=4466 4467 Oui
Here's my second request (I need id from the precedent result):
SELECT id, clics AS 'Total clics', clicsAnneeActuelle,
nbEmployesAnneActuelle, dateMAJ,
CASE WHEN inactif = 0 THEN 'Oui'ELSE 'Non' END AS 'Actif'
FROM redirection.elementsParAnnee('2021-01-01 00:00:00.0')
WHERE id >0 AND (nom LIKE '%4466%'
OR id LIKE '%4466%' OR lien LIKE '%4466%')
Here's the result:
id Total clics clicsAnneeActuelle nbEmployesAnneActuelle dateMAJ Actif
4466 284 30 18 2021-09-02 Oui
4467 225 28 16 NULL Oui
Here's what I want:
lien id Actif Infos
http://saaprod/soutien_tache/redirection.asp?id=4466 4467 Oui {id:4466, clcis:284 clicsAnneeActuelle:30, nbEmpolyesAnneeActuelle:18, dateMAJ:2021-09-02, Actif:Oui}; {id:4467, clcis:225, clicsAnneeActuelle:28, nbEmpolyesAnneeActuelle:16, dateMAJ:NULL, Actif:Oui}
How I can do that?
You should aggregate the data in the second query and only then do the full join:
select * from (
SELECT lien, id,
CASE WHEN inactif = 0 THEN 'Oui' ELSE 'Non' END AS 'Actif'
FROM redirection.elementsOutils
WHERE lien LIKE '%saaprod/soutien_tache/redirection.asp%'
ORDER BY inactif, dateMAJ
)as a ,
(
SELECT '{'||STRING_AGG('id:'||id||', clics:'||clics||',clicsAnneeActuelle:'||clicsAnneeActuelle||', nbEmployesAnneActuelle:'||nbEmployesAnneActuelle||', dateMAJ:'||dateMAJ||'Actif:'||
CASE WHEN inactif = 0 THEN 'Oui'ELSE 'Non' END,'}; {')||'}' as Infos
FROM redirection.elementsParAnnee('2021-01-01 00:00:00.0')
WHERE id >0 AND (nom LIKE '%4466%' OR id LIKE '%4466%' OR lien LIKE '%4466%')
) as b
I have this first case statement below which I need to merge with the case statement below this for grouping values together like this:
days range | Activity_submit
-------------------------------------
0-9 | 11
10-19 | 14
20-29 | 3
SELECT
events_raw.properties ->> 'days_before_stay' AS "Days_before_stay",
COUNT(CASE WHEN ((events_raw.properties ->> 'event_type') LIKE
'fs_mystay_activity_submit') THEN 1 ELSE NULL END) AS "Request Count"
FROM events_raw
second case statement to merge with first
select events_raw.properties ->> 'days_before_stay' AS "Days_before_stay" [days range], count(*) as [number of occurences]
from (
select case
when days between 0 and 9 then ' 0- 9'
when days between 10 and 19 then '10-19'
else '20-99' end as range
from events_raw)
group by 1
I do not see your table structure, but here is example where you can see group by expression.
SELECT
(id/10)*10 toOrder, -- addition field to sort by
(id/10)*10 || ' - ' || ((id)/10+1)*10 AS range,
count(*) myCount
FROM report
GROUP BY
(id/10)*10,
(id/10)*10 || ' - ' || ((id)/10+1)*10, -- group by expression
ORDER BY toOrder;
Instead if id you can use any integer field.
The code below generates around 300 rows, but only a small fraction of them has any value in column "Unit=3". The rest have null values, and hence many duplicate values in column "ekod" exists.
Does anyone know how to remove all rows with a null value in the column "unit=3"?
Best regards!
Result:
ekod unit=3
0004 NULL
0114 15
0114 NULL
0114 NULL
0120 NULL
0120 NULL
0120 46
0120 NULL
Code:
select
A.ekod
,case when A.unit='3' then count(*) end AS [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] A
group by a.ekod, a.unit
order by ekod
You can use sum.
select
A.ekod
,sum(case when a.unit='3' then 1 else 0 end) AS [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] A
group by a.ekod
order by ekod
As a note, if you don't care about ekods with zero units:
select a.ekod, count(*) as [Unit=3]
from [Stat_unitdata].[dbo].[XXX_YYY] a
where a.unit = '3'
group by a.ekod
order by a.ekod;
This returns only ekod values that have at least one unit = '3'.