In HiveQL, how to select result for all rows and some rows and display them in one table? - hiveql

In HiveQL, how to select result for all rows and some rows and display them in one table?
For example i have country codes column, i want data for all World plus some few countries in one table.
I tried case when but closest i achieved was countries plus the rest of the world:
select
case when lower(a.country) like 'cn' then 'China'
when lower(a.country) like 'us' then 'USA'
when lower(a.country) like 'uk' then 'UK'
when lower(a.country) like 'de' then 'Germany'
when lower(a.country) like 'jp' then 'Japan'
when lower(a.country) like 'br' then 'Brazil'
else "Rest"
end as Country,
c.D,
avg(case when a.time between 1 and 999999 then a.time else NULL end) as avg_time,
count(case when a.time between 1 and 999999 then a.time else NULL end) as time_count
from table1 a
join table2 c on a.vdate=c.cdate
and c.D like "2019_03"
group by c.D,
case when lower(a.country) like 'cn' then 'China'
when lower(a.country) like 'us' then 'USA'
when lower(a.country) like 'uk' then 'UK'
when lower(a.country) like 'de' then 'Germany'
when lower(a.country) like 'jp' then 'Japan'
when lower(a.country) like 'br' then 'Brazil'
else "Rest"
I also tried to put * in country list below in another query but that gives error, naturally:
select
c.D,
a.B,
avg(case when a.time between 1 and 999999 then a.time else NULL end) as
avg_time,
count(case when a.time between 1 and 999999 then a.time else NULL end) as time_count
from table1 a
join table2 c on a.vdate=c.date
where lower(a.country) in ("cn", "us", "uk", "de", "jp", "br")
and c.D like "2019_03"
group by c.D, a.B
How can I pull all world and the six countries in one query?

Related

Aggregating columns and getting count of values as row

I have a query output as below:
ID ID2 Working Leave Off Day
14595 76885302 10 0 0
178489 78756208 0 0 1
178489 78756208 0 1 0
I want to receive an output like below:
ID ID2 code value
14595 76885302 Working 10
178489 78756208 Off day 1
178489 78756208 Leave 1
My query is like below:
select tei.organisationunitid,pi.trackedentityinstanceid as tei,
count(case when tedv.value = 'Working' then tedv.value end) Working,
count(case when tedv.value = 'Off day' then tedv.value end) Offday,
count(case when tedv.value = 'Leave' then tedv.value end) Leave
from programstageinstance psi
inner join programinstance pi on pi.programinstanceid = psi.programinstanceid
inner join trackedentitydatavalue tedv on tedv.programstageinstanceid = psi.programstageinstanceid
inner join dataelement de on de.dataelementid = tedv.dataelementid
inner join trackedentityinstance tei on tei.trackedentityinstanceid = pi.trackedentityinstanceid
where psi.executiondate between '2017-01-01' and '2019-06-01'
and de.uid in ('x2222EGfY4K')
and psi.programstageid in (select programstageid
from programstage
where uid = 'CLoZpO22228')
and tei.organisationunitid in (select organisationunitid
from organisationunit
where path like '%Spd2222fvPr%')
group by pi.trackedentityinstanceid,de.uid,tei.organisationunitid,tedv.value
How can I achieve this?
I would try the JSON approach. I made a step-by-step fiddle:
demo:db<>fiddle
SELECT
id, id2,
elements ->> 'code' AS code,
SUM((elements ->> 'value')::int) AS value
FROM (
SELECT
id,
id2,
json_build_object('code', 'working', 'value', working) AS working,
json_build_object('code', 'leave', 'value', leave) AS leave,
json_build_object('code', 'off_day', 'value', off_day) AS off_day
FROM
mytable
) s,
unnest(ARRAY[working, leave, off_day]) as elements
GROUP BY 1,2,3
HAVING SUM((elements ->> 'value')::int) > 0

Using Where clause in between Inner Join Query

I am looking to fetch records and I have come through a scenario in which i have to include additional where clauses between the select query using inner join.
select stp.sales_person as "Sales_Person",
max(case when stp.jan_month is null then 0 else stp.jan_month end) as "January",
select sum(so.amount_total) from sale_order so inner join res_users ru on ru.id=so.user_id
where date(so.confirmation_date) > '2017-01-01' and date(so.confirmation_date) < '2017-01-30',
max(case when stp.feb_month is null then 0 else stp.feb_month end) as "February",
max(case when stp.march_month is null then 0 else stp.march_month end) as "March",
max(case when stp.dec_month is null then 0 else stp.dec_month end) as "December"
from sales_target_record stp
inner join res_partner rp on rp.name=stp.sales_person inner join res_users ru on ru.partner_id = rp.id inner join crm_team ct on ru.sale_team_id = ct.id
where ct.name = 'Direct Sales' group by stp.sales_person
I have to insert columns like i tried with sum but is not working as its a join query
You have a syntax issue in your query if this is truly SQL Server
select
stp.sales_person as Sales_Person,
max(case
when stp.jan_month is null
then 0
else stp.jan_month
end) as January,
--This needed parenthese since it's a subquery. Though, it's uncorrelated
( select sum(so.amount_total)
from sale_order so
inner join res_users ru on ru.id=so.user_id
where cast(so.confirmation_date as date) > '2017-01-01' and cast(so.confirmation_date as date) < '2017-01-30'
--here you need to add something like stp.someColumn = so.SomeColumn to correlate it to the outer query
) as SomeNewColumnUnCorrelated,
max(case
when stp.feb_month is null
then 0
else stp.feb_month
end) as February,
max(case
when stp.march_month is null
then 0
else stp.march_month
end) as March,
max(case
when stp.dec_month is null
then 0
else stp.dec_month
end) as December
from
sales_target_record stp
inner join
res_partner rp on
rp.name=stp.sales_person
inner join
res_users ru on
ru.partner_id = rp.id
where
ct.name = 'Direct Sales'
group by
stp.sales_person

convert rows into column in db2

I need the below select results to be converted into single row ,
Actual output:
ORDER POSTCODE Quantity Value
123456 AAAAA 22.78 5
123456 AAAAA 2.93 7
Expected Output:
ORDER POSTCODE AmbientQuantity Ambientvalue FVQuantity FvVAlue
123456 AAAAA 22.78 5 2.93 7
How to achieve the expected output in db2?
Following SQL will do the job:
with temp as (
select ORDER, POSTCODE, QUANTITY, VALUE,
rownumber() over (partition by ORDER, POSTCODE) as rownum
FROM mytable2
)
select ORDER, POSTCODE,
max(case when rownum = 1 Then QUANTITY end) as AMBIENTQUANTITY,
max(case when rownum = 1 Then VALUE end) as AMBIENTVALUE,
max(case when rownum = 2 Then QUANTITY end) as FVQuantity,
max(case when rownum = 2 Then VALUE end) as FVVALUE
from temp
group by ORDER, POSTCODE
Try something like this:
with tmp as (
select f0.*, rownumber() over(partition by f0.ORDER, f0.POSTCODE) rang
from your table f0
)
select
f1.ORDER, f1.POSTCODE, f1.Quantity AmbientQuantity, f1.Value Ambientvalue,
f2.Quantity FVQuantity2, f2.Value FvVAlue2,
f3.Quantity FVQuantity3, f2.Value FvVAlue3,
f4.Quantity FVQuantity4, f2.Value FvVAlue4
from tmp f1
left outer join tmp f2 on (f1.ORDER, f1.POSTCODE)=(f2.ORDER, f2.POSTCODE) and f2.rang=2
left outer join tmp f3 on (f1.ORDER, f1.POSTCODE)=(f3.ORDER, f3.POSTCODE) and f3.rang=3
left outer join tmp f4 on (f1.ORDER, f1.POSTCODE)=(f4.ORDER, f4.POSTCODE) and f4.rang=4
where f1.rang=1

How would you change or rather optimize this postgres sql query so that the output format remains the same?

Original expensive and slow query is this:
select 'INTEGRATED' as "STATUS", coalesce(sum(response_count),0) as "COUNT" from f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00','2015-08-05 01:00:00', null, 'LINK')
where wfc_result in ('TM_OK', 'TM_NO_CHANGE')
union
select 'WFC_FALLOUT' as "STATUS", coalesce(sum(response_count),0) as "COUNT" from f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00','2015-08-05 01:00:00', null, 'LINK')
where wfc_result LIKE 'WFC%'
union
select 'TM_FALLOUT' as "STATUS", coalesce(sum(response_count),0) as "COUNT" from f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00','2015-08-05 01:00:00', null, 'LINK')
where wfc_result = 'TM_FAIL'
union
select 'WFC_PENDING' as "STATUS", coalesce(sum(response_count),0) as "COUNT" from f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00','2015-08-05 01:00:00', null, 'LINK')
where wfc_result = 'PENDING';
Output:
Status Count
Integrated 40
TM_FALLOUT 50
WFC_PENDING 60
WFC_FALLOUT 70
The output format above is what I need. But this query takes a lot of time.
The query that I want to use is the following as it takes less time.
select
sum(CASE WHEN wfc_result IN ('TM_OK','TM_NO_CHANGE') THEN response_count ELSE 0 END) as "INTEGRATED",
sum(CASE WHEN wfc_result LIKE 'WFC%' THEN response_count ELSE 0 END) as "WFC_FALLOUT",
sum(CASE WHEN wfc_result = 'TM_FAIL' THEN response_count ELSE 0 END) as "TM_FALLOUT",
sum(CASE WHEN wfc_result = 'PENDING' THEN response_count ELSE 0 END) as "WFC_PENDING"
from f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00','2015-08-05 01:00:00',null, 'LINK')
However, the output of this query is as follows, I need the same output as I get from the first query.
Integrated WFC_FALLOUT TM_FALLOUT WFC_PENDING
40 50 60 70
I tried several ways but unable to find out how I can edit this?
Assuming that 'wfc_result' WFC% is always WFC_% yo can do the following:
SELECT status.lbl AS status, coalesce(sum(response_count), 0) AS count
FROM (VALUES
('TM_O', 'INTEGRATED'),
('TM_N', 'INTEGRATED'),
('WFC_', 'WFC_FALLOUT'),
('TM_F', 'TM_FALLOUT'),
('PEND', 'WFC_PENDING')) status(cls, lbl)
LEFT JOIN f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00', '2015-08-05 01:00:00', NULL, 'LINK') wfc
ON substr(wfc.wfc_result, 1, 4) = status.cls
GROUP BY 1;
If there are only a few 'wfc_result' strings LIKE 'WFC%' you could also spell them out (as well as the other classes) in the VALUES clause and then drop the substr() function in the JOIN clause.
To get the total output, the query is much simpler:
SELECT sum(response_count) AS total_count
FROM f_wfc_transaction_summary_isocc_ft_sum_no_tid('2015-07-22 00:00:00', '2015-08-05 01:00:00', NULL, 'LINK');
This does of course make another call to the expensive function, but there is no way to get around that on the database; in your client application you could simply sum up the "count" values returned from the previous query.

Make a column values header for rest of columns using TSQL

I have following table
ID | Group | Type | Product
1 Dairy Milk Fresh Milk
2 Dairy Butter Butter Cream
3 Beverage Coke Coca cola
4 Beverage Diet Dew
5 Beverage Juice Fresh Juice
I need following output/query result:
ID | Group | Type | Product
1 Dairy
1 Milk Fresh Milk
2 Butter Butter Cream
2 Beverage
1 Coke Coca cola
2 Diet Dew
3 Juice Fresh Juice
For above sample a hard coded script can do the job but I look for a dynamic script for any number of groups. I do not have any idea how it can be done so, I do not have a sample query yet. I need ideas, examples that at least give me an idea. PIVOT looks a close option but does not looks to be fully fit for this case.
Here's a possible way. It basically unions the "Group-Headers" and the "Group-Items". The difficulty was to order them correctly.
WITH CTE AS
(
SELECT ID,[Group],Type,Product,
ROW_NUMBER() OVER (PARTITION BY [Group] Order By ID)AS RN
FROM Drink
)
SELECT ID,[Group],Type,Product
FROM(
SELECT RN AS ID,[Group],[Id]AS OriginalId,'' As Type,'' As Product, 0 AS RN, 'Group' As RowType
FROM CTE WHERE RN = 1
UNION ALL
SELECT RN AS ID,'' AS [Group],[Id]AS OriginalId,Type,Product, RN, 'Item' As RowType
FROM CTE
)X
ORDER BY OriginalId ASC
, CASE WHEN RowType='Group' THEN 0 ELSE 1 END ASC
, RN ASC
Here's a demo-fiddle: http://sqlfiddle.com/#!6/ed6ca/2/0
A slightly simplified approach:
With Groups As
(
Select Distinct Min(Id) As Id, [Group], '' As [Type], '' As Product
From dbo.Source
Group By [Group]
)
Select Coalesce(Cast(Z.Id As varchar(10)),'') As Id
, Coalesce(Z.[Group],'') As [Group]
, Z.[Type], Z.Product
From (
Select Id As Sort, Id, [Group], [Type], Product
From Groups
Union All
Select G.Id, Null, Null, S.[Type], S.Product
From dbo.Source As S
Join Groups As G
On G.[Group] = S.[Group]
) As Z
Order By Sort
It should be noted that the use of Coalesce is purely for aesthetic reasons. You could simply return null in these cases.
SQL Fiddle
And an approach with ROW_NUMBER:
IF OBJECT_ID('dbo.grouprows') IS NOT NULL DROP TABLE dbo.grouprows;
CREATE TABLE dbo.grouprows(
ID INT,
Grp NVARCHAR(MAX),
Type NVARCHAR(MAX),
Product NVARCHAR(MAX)
);
INSERT INTO dbo.grouprows VALUES
(1,'Dairy','Milk','Fresh Milk'),
(2,'Dairy','Butter','Butter Cream'),
(3,'Beverage','Coke','Coca cola'),
(4,'Beverage','Diet','Dew'),
(5,'Beverage','Juice','Fresh Juice');
SELECT
CASE WHEN gg = 0 THEN dr1 END GrpId,
CASE WHEN gg = 1 THEN rn1 END TypeId,
ISNULL(Grp,'')Grp,
CASE WHEN gg = 1 THEN Type ELSE '' END Type,
CASE WHEN gg = 1 THEN Product ELSE '' END Product
FROM(
SELECT *,
DENSE_RANK()OVER(ORDER BY Grp DESC) dr1
FROM(
SELECT *,
ROW_NUMBER()OVER(PARTITION BY Grp ORDER BY type,gg) rn1,
ROW_NUMBER()OVER(ORDER BY type,gg) rn0
FROM(
SELECT Grp,Type,Product, GROUPING(Grp) gg, GROUPING(type) tg FROM dbo.grouprows
GROUP BY Product, Type, Grp
WITH ROLLUP
)X1
WHERE tg = 0
)X2
WHERE gg=1 OR rn1 = 1
)X3
ORDER BY rn0