methods to separate multiple count(*)s by external field - sql

I didn't know exactly what to call this question, so apologies if the title is confusing. I'm trying to generate a summary of user activity for a particular website. This query returns the total number of hits per type of page:
select
count(case when internal_handle = 'content' then 1 else null end) as CONTENT,
count(case when data = '/webapps/assessment/take/launch.jsp' then 1 else null end) as ASSESSMENTS,
count(case when internal_handle = 'discussion_board_entry' then 1 else null end) as DISCUSSIONS,
count(case when data = '/webapps/blackboard/execute/uploadAssignment' then 1 else null end) as BB_ASSIGNMENTS,
count(case when data = '/webapps/turn-plgnhndl-BBLEARN/links/submit.jsp' then 1 else null end) as TII_ASSIGNMENTS,
count(case when data = '/webapps/osv-kaltura-BBLEARN/jsp/courseGallery.jsp' then 1 else null end) as COURSE_GALLERY,
count(case when data = '/webapps/osc-BasicLTI-BBLEARN/frame.jsp' then 1 else null end) as ECHO_360,
count(case when internal_handle = 'check_grade' then 1 else null end) as MY_GRADES
from BBLEARN.ACTIVITY_ACCUMULATOR
where course_pk1 = (select pk1 from BBLEARN.course_main where course_id = '2014FA.BOS.PPB.445.A')
and user_pk1 in (select users_pk1 from BBLEARN.course_users where role = 'S' and crsmain_pk1 = course_pk1);
So the result is like:
CONTENT,ASSESSMENTS,DISCUSSIONS,BB_ASSIGNMENTS,TII_ASSIGNMENTS,COURSE_GALLERY,ECHO_360,MY_GRADES
5787,954,335,0,0,0,837,222
My goal, though, is to have it separated by hits per user. For instance, I'd want a result like:
USER_PK1,CONTENT,ASSESSMENTS,DISCUSSIONS,BB_ASSIGNMENTS,TII_ASSIGNMENTS,COURSE_GALLERY,ECHO_360,MY_GRADES
USER_A,250,79,41,0,0,0,66,7
USER_B,144,89,82,0,0,0,24,0
USER_C,174,45,23,0,0,0,58,1
--etcetera
I can imagine running the above query iteratively, but I'm not familiar enough with Oracle to do it effectively. How might I go about doing this? Or is there a better way to get the fields I'm looking for?
Thanks in advance!

Just add a group by:
select user_pk1,
count(case when internal_handle = 'content' then 1 else null end) as CONTENT,
count(case when data = '/webapps/assessment/take/launch.jsp' then 1 else null end) as ASSESSMENTS,
count(case when internal_handle = 'discussion_board_entry' then 1 else null end) as DISCUSSIONS,
count(case when data = '/webapps/blackboard/execute/uploadAssignment' then 1 else null end) as BB_ASSIGNMENTS,
count(case when data = '/webapps/turn-plgnhndl-BBLEARN/links/submit.jsp' then 1 else null end) as TII_ASSIGNMENTS,
count(case when data = '/webapps/osv-kaltura-BBLEARN/jsp/courseGallery.jsp' then 1 else null end) as COURSE_GALLERY,
count(case when data = '/webapps/osc-BasicLTI-BBLEARN/frame.jsp' then 1 else null end) as ECHO_360,
count(case when internal_handle = 'check_grade' then 1 else null end) as MY_GRADES
from BBLEARN.ACTIVITY_ACCUMULATOR
where course_pk1 = (select pk1 from BBLEARN.course_main where course_id = '2014FA.BOS.PPB.445.A') and
user_pk1 in (select users_pk1 from BBLEARN.course_users where role = 'S' and crsmain_pk1 = course_pk1)
group by user_pk1;
If user_pk1 isn't what you mean by "user", then you might have to join in another table.

Related

Column merge using sum in case Oracle APEX

I need help How can I merge the column into a single column, here is my code, is this method is correct. I want to get the count of the selected row in the table for the columns.
SELECT
CAT_MGR,
SUM ( case when CAT_MGR = 'A' THEN 1 else 0 end ) AS DESIGN,
sum (case when CAT_MGR = 'b' THEN 1 else 0 END) AS DESIGN,
sum (case when CAT_MGR = 'c' THEN 1 else 0 END) AS DESIGN
from Table_A
GROUP BY
CAT_MGR
Can you guys help me I'm a beginner at SQL.
Thank you in advance
If you want just one row in the resultset, then remove the group by clause. Then, if you want to count the three cat mgr together, you can use in:
select
sum(case when cat_mgr = 'a' then 1 else 0 end ) as design_a,
sum(case when cat_mgr = 'b' then 1 else 0 end ) as design_b,
sum(case when cat_mgr = 'c' then 1 else 0 end ) as design_c,
sum(case when cat_mgr in ('a', 'b', 'c') then 1 else 0 end ) as design
from Table_a
You just need to make addion like below in order to get one column "Design"
SELECT
CAT_MGR,
SUM (case when CAT_MGR = 'A' THEN 1 else 0 end )
+ sum (case when CAT_MGR = 'b' THEN 1 else 0 END)
+ sum (case when CAT_MGR = 'c' THEN 1 else 0 END)
AS DESIGN
from TJD_CORE_CATPB_TB
GROUP BY
CAT_MGR

Need to create a Totals report from oracle table data

I have a table in oracle similar to the the example table image that I need to have output the segregated totals as shown in the second example results image.
I need the sums of each item_type where A & B are just examples for a large number of possible items that can be added.
example table:
example results:
Any help would be appreciated. thanks
Use conditional aggregation:
SELECT
store,
SUM(CASE WHEN item_type = 'A' AND item_status = 'IN' THEN 1 ELSE 0 END) a_items_in,
SUM(CASE WHEN item_type = 'A' AND item_status = 'OUT' THEN 1 ELSE 0 END) a_items_out,
SUM(CASE WHEN item_type = 'B' AND item_status = 'IN' THEN 1 ELSE 0 END) b_items_in,
SUM(CASE WHEN item_type = 'B' AND item_status = 'OUT' THEN 1 ELSE 0 END) b_items_out
FROM mytable
GROUP BY store

How to aggregate unioned tables with count and dummy values?

I am counting in two tables some stuff and want one aggregated result (one row). I write this SQL for this purpose:
SELECT sum (Amount_New) Amount_New,
sum(Import_Dropout) Import_Dropout,
sum(Import)Import,
sum(Processing)Processing,
sum(Processing_Dropout)Processing_Dropout,
sum(Matching)Matching,
sum(Matching_Dropout)Matching_Dropout,
sum(Export)Export,
sum(Exported)Exported,
sum(Rejected)Rejected,
sum(AmountSubTotal)AmountSubTotal,
sum(AmountTotal)AmountTotal
FROM (
SELECT COUNT(CASE WHEN ProcessStatus='_New' THEN 1 ELSE null END) AS Amount_New,
COUNT(CASE WHEN ProcessStatus='Import_Dropout' THEN 1 ELSE null END) AS Import_Dropout,
COUNT(CASE WHEN ProcessStatus='Import' THEN 1 ELSE null END) AS Import,
COUNT(CASE WHEN ProcessStatus='Processing' THEN 1 ELSE null END) AS Processing,
COUNT(*) AS AmountTotal,
0 as Processing_Dropout,
0 as Matching,
0 as Matching_Dropout,
0 as Export,
0 as Export_Dropout,
0 as Exported,
0 as Rejected,
0 as AmountSubTotal,
0 as UnionOrder
FROM "fileimport$marketscanimportcsv"
WHERE ft_boekdat like '%2018%'
UNION
SELECT 0 AS Amount_New,
0 AS Import_Dropout,
0 AS Import,
COUNT(CASE WHEN ProcessStatus='Processing_Dropout' THEN 1 ELSE null END) AS Processing_Dropout,
COUNT(CASE WHEN ProcessStatus='Processing' THEN 1 ELSE null END) AS Processing,
COUNT(CASE WHEN ProcessStatus='Matching' THEN 1 ELSE null END) AS Matching,
COUNT(CASE WHEN ProcessStatus='Matching_Dropout' THEN 1 ELSE null END) AS Matching_Dropout,
COUNT(CASE WHEN ProcessStatus='Export' THEN 1 ELSE null END) AS Export,
COUNT(CASE WHEN ProcessStatus='Export_Dropout' THEN 1 ELSE null END) AS Export_Dropout,
COUNT(CASE WHEN ProcessStatus='Exported' THEN 1 ELSE null END) AS Exported,
COUNT(CASE WHEN ProcessStatus='Rejected' THEN 1 ELSE null END) AS Rejected,
COUNT(CASE WHEN ProcessStatus!= '_New' and ProcessStatus!= 'Import_Dropout' and ProcessStatus!= 'Import' THEN 1 ELSE null END) AS AmountSubTotal,
COUNT(*) AS AmountTotal,
1 as UnionOrder
FROM "matching$marketscanmovement"
WHERE date_part ('year', BookingDate_BA_MS)= 2018
) SK GROUP by unionorder order by unionorder asc
1) The result is 2 rows, which is not one value as total of that column.
Why is this query not summarizing the unioned same column values? How should it be written?
2) When I try sum "(Amount_New1+Amount_New2) Amount_New" (and changing the subquery column names to amount_new1 / amount_new2) it is not working neither. Why?
If you want to return a single row, conceptually representing an aggregate over the entire union table, then remove GROUP BY:
SELECT SUM(Amount_New) Amount_New,
SUM(Import_Dropout) Import_Dropout,
SUM(Import) Import,
SUM(Processing) Processing,
SUM(Processing_Dropout) Processing_Dropout,
SUM(Matching) Matching,
SUM(Matching_Dropout) Matching_Dropout,
SUM(Export) Export,
SUM(Exported) Exported,
SUM(Rejected) Rejected,
SUM(AmountSubTotal) AmountSubTotal,
SUM(AmountTotal) AmountTotal
FROM
(
-- ... your current query
) SK;
You also may want to remove the UnionOrder computed column, since there is no need to sort a single row result set.

Introducing a simple count subquery to an already existing subquery

I am creating a simple image browser which is connected to an SQLite database. Within the browser, similar images are grouped into an event and each image is labelled with a few tags.
Someone helped me construct this very helpful query below. It contains 5 random tags as an example:
SELECT *
FROM
(SELECT
t.EventId,
SUM(CASE WHEN name = 'necktie' THEN 1 ELSE 0 END) as 'necktie',
SUM(CASE WHEN name = 'shirt' THEN 1 ELSE 0 END) as 'shirt',
SUM(CASE WHEN name = 'suit' THEN 1 ELSE 0 END) as 'suit',
SUM(CASE WHEN name = 'man' THEN 1 ELSE 0 END) as 'man',
SUM(CASE WHEN name = 'male' THEN 1 ELSE 0 END) as 'male'
FROM
TagsMSCV t
WHERE
name IN ('necktie', 'shirt', 'suit', 'man', 'male')
GROUP BY
t.EventId)
ORDER BY
COUNT(*) DESC
This returns how many of each tag (column is called 'name') show up in each event. However now I also need the size of the event (number of unique image id's in the event) which can be accomplished with the below query:
SELECT EventId, COUNT(DISTINCT ImageId)
FROM TagsMSCV
GROUP BY EventId
But I have no idea how to introduce this syntax into the subquery above? If I put it beside t.EventId, it only counts the image id's in event that are tagged with the 5 random tags which is not correct. I need the total unique image id's in the event.
First, your subquery is not necessary. Second, you can use conditional COUNT(DISTINCT):
SELECT t.EventId,
SUM(CASE WHEN name = 'necktie' THEN 1 ELSE 0 END) as necktie,
SUM(CASE WHEN name = 'shirt' THEN 1 ELSE 0 END) as shirt,
SUM(CASE WHEN name = 'suit' THEN 1 ELSE 0 END) as suit,
SUM(CASE WHEN name = 'man' THEN 1 ELSE 0 END) as man,
SUM(CASE WHEN name = 'male' THEN 1 ELSE 0 END) as male
COUNT(DISTINCT CASE WHEN name = 'necktie' THEN imageid END) as necktie_images,
COUNT(DISTINCT CASE WHEN name = 'shirt' THEN imageid END) as shirt_images,
COUNT(DISTINCT CASE WHEN name = 'suit' THEN imageid END) as suit_images,
COUNT(DISTINCT CASE WHEN name = 'man' THEN imageid END) as man_images,
COUNT(DISTINCT CASE WHEN name = 'male' THEN imageid END) as male_images
FROM TagsMSCV t
WHERE name IN ('necktie', 'shirt', 'suit', 'man', 'male')
GROUP BY t.EventId
EDIT:
If you want the total distinct images for an event, then no conditional logic is needed. Just use:
COUNT(DISTINCT imageid) as total_images,
And remove the WHERE clause.

Trying to get count of votes in SQL based on ID

Table structures:
Solution_Votes:
ID int
SolutionID string
Vote int
Solution:
ID int
Solution
VotesUp
VotesDown
Code:
SELECT
*,
(SELECT SUM(CASE WHEN voteUp = 1 THEN 1 ELSE 0 END)
FROM Solutions_Votes) AS VoteCountUp,
(SELECT SUM(CASE WHEN voteDown = 0 THEN 1 ELSE 0 END)
FROM Solutions_Votes) AS VoteCountDown
FROM
Solution
When I run this query it gives me the count on each row for voteUpCount and voteDownCount. I need the count to be based on the solution ID so that each solution has its count of up votes and down votes. If anybody can help it would be appreciated. Thanks in advance!
Just use conditional aggregation. In your case this is simple:
select sv.solutionid,
sum(case when sv.voteUp = 1 then 1 else 0 end) as VoteCountUp,
sum(case when sv.voteDown = 0 then 1 else 0 end) as VoteCountDown
from solutions_votes sv
group by sv.solutionid;
You only need the solutions table if some solutions have no votes and you want to include them.
EDIT:
You would include solutions in various way. Here is one:
select s.*, ss.VoteCountUp, ss.VoteCountDown
from solutions s left join
(select sv.solutionid,
sum(case when sv.voteUp = 1 then 1 else 0 end) as VoteCountUp,
sum(case when sv.voteDown = 0 then 1 else 0 end) as VoteCountDown
from solutions_votes sv
group by sv.solutionid
) ss
on s.solutionid = ss.solutionid;