Displaying count based on several columns-- a report query - sql

I have a report to display count of transactions based on user, tariff plan type of operation and status of the transaction. What is the best possible way to do this. IS multiple groupby possible and feasible?
Sample data and output:
Date Plan Total USer Type of operation status product
2/8/2017 Entel Prepago Smart 5 01234567 Venta Success sim
2/8/2017 Super Plan 3 01234568 Venta Success pack
2/8/2017 Entel Prepago Smart 1 01234567 Venta Cancel sim
2/8/2017 Super Plan 1 01234568 Venta Cancel sim
2/8/2017 Entel Prepago 2 01234567 Reposicion Cancel sim
2/9/2017 Entel Prepago 10 01234570 Portabilidad Success pack
2/9/2017 Entel Prepago Smart 1 01234567 Venta Pending pack
2/9/2017 Super Plan 1 01234568 Portabilidad Success sim

Yes you can multiple group by.
You can try this query :
SELECT COUNT(transaction), user, tariff_plan, status FROM your_table GROUP BY user, tariff_plan, status

Try this:
select
user, plan, type_of_operation, status,
count(*) cnt
from your_table
group by
user, plan, type_of_operation, status;

Related

SQl query for overlap of users in different stream service?

I'm new to sql and keen to learn but i'm having trouble with this problem. I would appreciate any help. I have a login table with following column and i have explained the columns below.
id cur_date user_id stream user_signup tot_sec mov_sec ser_sec
1 19-MAY-20 5right TV 12-MAY-20 73430 73430 0
2 19-MAY-20 5right TV 12-JAN-16 3430 3430 0
3 19-MAY-20 5left MOBILE 03-JAN-20 3457 3430 45
4 19-MAY-20 7left MOBILE 04-JAN-20 4980 100 4880
5 19-MAY-20 7right Tv 04-FEB-20 15731 0 15731
6 19-MAY-20 7right WEB 04-APR-20 16731 1000 15731
7 19-MAY-20 7left TV 04-MAR-20 2731 1000 1731
8 19-MAY-20 5left TV 03-APR-20 12731 11000 1731
cur_date is when we take the user metrics
user_id (have same id on different stream service)
user_signup (user sign up date)
stream( streaming ways, contains 3 values mobile, web, TV)
tot_sec (total active time seconds)
mov_sec (watching movie time in seconds)
ser_sec(watching tv series time in seconds)
Quesion: write the SQL to which two stream have the greatest overlap of users? The users have the same id across stream service?
I wrote this:
select r1.user_id, r1.stream
from login as r1
inner join login as r2
on r1.user_id = r2.user_id
order by r1.stream;
However this is not quite what im asking for. Any ideas?
Thanks!
Hmmm . . . If you mean the counts of logged in users, then you need some sort of aggregation to count. So:
select s1.stream, s2.stream, count(*)
from login s1 join
login s2
on s1.user_id = s2.user_id and s1.stream <> s2.stream
group by s1.stream, s2.stream
order by count(*) desc
fetch first 1 row only;
If the users can be repeated for a given stream, then you want count(distinct s1.user_id) instead of count(*).

Trouble pivoting data in DB2

Before this one is marked as duplicate please know I have done my research on Pivoting in DB2 (even though DB2 doesnt have PIVOT) from these links
Pivoting in DB2 on SO and IBM Developers, but I just cant make sense of how to do it with my Data and need some help. I tried to manipulate my string using examples from both of those links and could not get it to work. Im not asking for anyone to write the full code for me, but just give me a point in the right direction on how to change my string to retrieve the desired result. Thank you in advance.
Current String:
SELECT
cfna1 AS "Customer Name", cfrisk AS "Risk Rating", cfrirc AS "Rated By", date(digits(decimal(cfrid7 + 0.090000, 7, 0))) AS "Risk Rated Date",cfuc3n3 AS "Credit Score", date(digits(decimal(cf3ud7 + 0.090000, 7, 0))) AS "CR Date"
FROM cncttp08.jhadat842.cfmast cfmast
WHERE cfcif# IN ('T000714', 'T000713', 'T000716', 'T000715')
ORDER BY
CASE cfcif#
WHEN 'T000714' THEN 1
WHEN 'T000713' THEN 2
WHEN 'T000716' THEN 3
WHEN 'T000715' THEN 4
END
Result as expected from String:
Customer Name | Risk Rating | Rated By | Risk Rated Date | Credit Score | CR Date
Elmer Fudd 8 MLA 2018-02-08 777 2018-02-08
Result I would like to achieve:
Elmer Fudd
Risk Rating 8
Rated By MLA
Risk Rated Date 2018-02-08
Credit Score 777
CR Date 2018-02-08
Use unpivot method suggested in developers link and use cast to convert all columns to varchar.
Example:
select st1.id1, unpivot1.col1, unpivot1.val1
from (
select id1, char1 , date1, number1
from sometable
) st1,
lateral (values
('char col', cast(st1.char1 as varchar(100))),
('date col', cast(st1.date1 as varchar(100))),
('number col', cast(st1.number1 as varchar(100)))
) as unpivot1 (col1, val1)
order by st1.id1
I don't think that output is possible in sql -- do you mean something like this?
id_group Data_Type Value
1 Name Elmer Fudd
1 Risk Rating 8
1 Rated By MLA
1 Risk Rated Date 2018-02-08
1 Credit Score 777
1 CR Date 2018-02-08
To do this we need another column that brings all the elements together -- I called it "id_group" this is the column that identifys the group

Multiple counts in a query

I'm writing a query that counts company complaints. The query should count the total number of complaints from a company and also break it down into who called from the company to make the complaint. So an example output would be:
Company Ref Company Name Company Complaints Caller Caller Complaints
11 Argos 10 Steve 8
11 Argos 10 JIM 2
So as you can see the query counts the total number of complaints, then also breaks it down to who complained. So far I have everything perfect apart from the total count. My code is:
SELECT COMPANYREF,
COMPANY,
(SELECT COUNT(COMPANYREF)
FROM XCALLSTABLE) AS CompanyCalls,
CALLER,
COUNT(*)
FROM XCALLSTABLE
JOIN XCUSTOMERTABLE ON (XCALLSTABLE.COMPANYREF = XCUSTOMERTABLE.CUSTREF)
JOIN XTELEPHONETABLE ON (XCUSTOMERTABLE.TELEPHONE = XTELEPHONETABLE.PHONENUMBER)
GROUP BY COMPANYREF,
COMPANY,
CALLER
HAVING COUNT(*) > 0 ;
Some sample output for the current code is:
Company Ref Company Name Company Complaints Caller Caller Complaints
145 Comfiture Traders 500 Alexis Patel 4
The issue here is the total count for the company just counts every row, whereas I'm trying to count the occurances of that company appearing in the column.
Any and all help would be greatly appreciated.
Using sstan's code gave a result of
111 Medusa Shipping 4 Lily Morgan 5
111 Medusa Shipping 4 Ruby Walker 6
Whereas the result should be
111 Medusa Shipping 11 Lily Morgan 5
111 Medusa Shipping 11 Ruby Walker 6
I'm sure there is a cleaner way of doing this, but the following query should work:
SELECT companyref,
company,
CompanyCalls,
caller,
COUNT(*)
FROM (SELECT c.companyref,
company,
COUNT(*) OVER (PARTITION BY c.companyref) AS CompanyCalls,
caller
FROM xcallstable c
JOIN xcustomertable ct
ON ct.custref = c.companyref
JOIN xtelephonetable t
ON t.phonenumber = ct.telephone)
GROUP BY companyref, company, CompanyCalls, caller
HAVING COUNT(*) > 0

SQL hourly log , show all matching rows that have a value below threshold for n hours

I have a simple SQL log table (named market_history in SQLite) for US markets it looks something like this:
Sample table (market_history)
id datetime market percent
1 9/5/2014 7:50 ARIZONA 50.0
2 9/5/2014 7:50 ATLANTA 97.4
3 9/5/2014 7:50 AUSTIN 78.8
4 9/5/2014 7:50 BOSTON 90.9
6 9/5/2014 7:50 CHARLOTTE 100.0
7 9/5/2014 7:50 CHICAGO 90.3
This table is an hourly snapshot of network capacity in various systems in each market. What I would like to do is set up an alert system that if any one particular market is below a threshold percent (say 50) for more than 2 consecutive hours (each row is recorded every hour), it triggers an alert email.. So the query should show me a a unique list of Market names where the percents is < 50.0 for more than the last 2 consecutive entries
Here's the SQL I'm trying, but it's not working:
Sample SQL (not working):
SELECT
mh.datetime, mh.market, mh.percent
FROM markets_history mh
WHERE
(SELECT mh1.precent FROM markets_history mh1 WHERE mh1.datetime BETWEEN "2015-03-23 00:00:00" AND "2015-03-23 00:59:59" AND mh.market=mh1.market ) < 50 AND (SELECT mh2.precent FROM markets_history mh2 WHERE mh2.datetime BETWEEN "2015-03-23 01:00:00" AND "2015-03-23 01:59:59" AND mh.market=mh2.market ) < 50
ORDER by mh.datetime
I know I'm missing something.. any sugggestions
If the time windows are fixed and reliable, just make sure the largest one isn't more than the threshold. It wouldn't really matter how far back you look either if you needed to extend this to more than two.
select market
from markets_history mh
where mh.datetime between <last_two_hours> and <now>
group by mh.market
having max(percent) < 50.0
-- and count(*) = 2 /* if you need to be sure of two ... */
Here is an approach that should work in SQLite. Find the last good id (if any) in each market. Then count the number of rows larger than than id.
select lastgood.market,
sum(case when lastgood.market is null then 1
when lastgood.id < mh.id then 1
else 0
end) as NumInRow
from market_history mh left join
(select market, max(id) as maxid
from market_history mh
where percent < 50.0
group by market
) as lastgood
on lastgood.market = mh.market and lastgood.id < mh.id;
This query is a little bit complicated because it needs to take into account the possibility of there not being any good id. If that is the case, then all rows for the market count.

sql select statement view

Today i made a post about a issue i was having with sql, with the help of some people over there i figured out how my query had to be.
Now i have a different question, the result of my previous query:
select
count(case when Job = 'Garbageman' then 1 end) as GarbageCount,
count(case when Job = 'Delivery' then 1 end) as DeliveryCount
from Job
are:
GarbageCount: DelivryCount:
4 5
What i am trying to achieve is the following:
Job: Count:
Garbage 4
Delivery 5
My table is the following:
User: Job:
Mark Garbageman
Dirk Garbageman
Henk Garbageman
Steven Garbageman
Mark Delivery
Dirk Delivery
Henk Delivery
Steven Delivery
Stevens Delivery
Anyone know how my sql query has to look like?
Group by is all you're looking for:
select job, count(*)
from yourtable
group by job