sql script group by help needed - mysql

I have sql script that needed further tweaking to produce a simpler report as shown below. I am looking for the results to be grouped on username.
userName, weeknum, and #of wins
select
p.userID,
s.gameID,
p.pickID,
u.userName,
s.weekNum,
s.homeID,
s.homeScore,
s.visitorID,
s.visitorScore
from nflp_picks p
inner join nflp_users u
on p.userID = u.userID
inner join nflp_schedule s
on p.gameID = s.gameID
where s.weekNum = 6
and u.userName <> 'admin'
order by p.userID, s.gameTimeEastern, s.gameID;

Make you current query as derived table, then do like this:
SELECT userName,
weeknum,
SUM(CASE WHEN pickID=homeID
AND homeScore > visitorScore THEN 1
WHEN pickID=visitorID
AND visitorScore > homeScore THEN 1
ELSE 0 END) AS "# of wins"
FROM
(SELECT
p.userID,
s.gameID,
p.pickID,
u.userName,
s.weekNum,
s.homeID,
s.homeScore,
s.visitorID,
s.visitorScore
FROM nflp_picks p
INNER JOIN nflp_users u
ON p.userID = u.userID
INNER JOIN nflp_schedule s
ON p.gameID = s.gameID
WHERE s.weekNum = 6
AND u.userName <> 'admin'
ORDER BY p.userID, s.gameTimeEastern, s.gameID) a
GROUP BY userName, weeknum;
SUM() over CASE expression checking if pickID value is the same as the winning team.
Here's a trimmed down fiddle example

Related

How do i create two conditions in one mysql field?

Sorry I did not know how to word the question, it's actually a little more complicated than it sounds. I've got the following in my database; please see screenshot in the link:
http://prntscr.com/utyopv
I am generating a report using BIRT and I want that when priority = 2, it displays a value of 'High'. Similarly when priority = 1, it shows 'Medium' and when it = 1, it shows 'Low'.
But I also want that when estimated_time = 4, it displays '16+hrs', when estimated_time = 3, it shows '< 16 hrs' etc etc.
Now I've managed to do the priority using the code below;
SELECT date_created, CONCAT(first_name, " ", last_name) as user, e_name, cc_name, 'High' as priority, job_description, due_date, estimated_time, impediment
FROM job_planning as jp
INNER JOIN user as u
ON jp.user_id = u.id
INNER JOIN employer as e
ON jp.employer_id = e.id
INNER JOIN client_company as cc
ON jp.client_id = cc.id
WHERE jp.priority = '2'
union
SELECT date_created, CONCAT(first_name, " ", last_name) as user, e_name, cc_name, 'Medium' as priority, job_description, due_date, estimated_time, impediment
FROM job_planning as jp
INNER JOIN user as u
ON jp.user_id = u.id
INNER JOIN employer as e
ON jp.employer_id = e.id
INNER JOIN client_company as cc
ON jp.client_id = cc.id
WHERE jp.priority = '1'
union
SELECT date_created, CONCAT(first_name, " ", last_name) as user, e_name, cc_name, 'Low' as priority, job_description, due_date, estimated_time, impediment
FROM job_planning as jp
INNER JOIN user as u
ON jp.user_id = u.id
INNER JOIN employer as e
ON jp.employer_id = e.id
INNER JOIN client_company as cc
ON jp.client_id = cc.id
WHERE jp.priority = '0';
But how can I also include estimated_time? Can i use OR in mysql? I cannot use AND because then it would separate the two.
Thanks and appreciate any help.
SELECT ... ,
CASE priority WHEN 2 THEN 'High'
WHEN 1 THEN 'Medium',
ELSE 'Low'
END AS verbal_priority,
CASE estimated_time WHEN 4 THEN '16+hrs'
...

How to make SQL query from this structure table?

Initial:
1_ = country
2_ = gender
3_ = purpose
How to make SQL query show data like this
Try this(this is a mysql approach), and next time please post your table schema with text not pictures if you want to ask a question in SO.
select
u.id,
u.name,
max(case when ud.code like '1_%' then fc.code_name else '' end) as country,
max(case when ud.code like '2_%' then fc.code_name else '' end) as gender,
max(case when ud.code like '3_%' then fc.code_name else '' end) as purpose,
group_concat(distinct vt.visit_to) as visit_to
from t_users u
left join t_user_details ud
on u.id = ud.id_user
left join t_field_code fc
on ud.code = fc.code
left join t_visit_to vt
on u.id = vt.id_user
group by u.id, u.name
This would do the job more or less:
SELECT user.id,
user.name,
country.code_name AS country,
gender.code_name AS gender,
purpose.code_name AS purpose,
visit.to_to
FROM t_users AS user
JOIN t_user_details AS details
ON user.id = details.user_id
LEFT OUTER JOIN t_field_code AS country
ON details.code = country.code
AND country.code LIKE '1_%'
LEFT OUTER JOIN t_field_code AS gender
ON details.code = gender.code
AND gender.code LIKE '2_%'
LEFT OUTER JOIN t_field_code AS purpose
ON details.code = purpose.code
AND purpose.code LIKE '3_%'
LEFT OUTER JOIN t_visit_to AS visit
ON user.id = visit.id_user
ORDER BY user.id;
The only problem is that it gives multiple rows in case the user has more places to visit.

MySQL counting elements without using count(*)

I'm practicing MySQL for an upcoming exam and need some help.
I have this db:
USER(Code, Name, Surname, Age)
THEATRE(Name, City, Capacity)
SUBSCRIPTION(ID, UserCode, TheatreName, Amount)
With these referential integrity constraints:
SUBSCRIPTION.UserCode->USER.Code
SUBSCRIPTION.TheatreName->THEATRE.Name
For exercise I need to write the query which determines code, name and surname of the users older than 50 and who has more than one subscription WITHOUT using the COUNT function.
I know that maybe a self-join could help but I really don't know how. Can anyone help me? Thank you very much.
You can use
EXISTS:
SELECT u.Code, u.Name, u.Surname
FROM USER u
WHERE u.Age > 50
AND EXISTS (
SELECT 1 FROM SUBSCRIPTION s WHERE u.Code = s.UserCode
)
Or JOIN
SELECT DISTINCT u.Code, u.Name, u.Surname
FROM USER u
JOIN SUBSCRIPTION s
ON u.Code = s.UserCode
WHERE u.Age > 50
Edited:
SELECT DISTINCT u.Code, u.Name, u.Surname
FROM USER u
JOIN SUBSCRIPTION s1
ON u.Code = s1.UserCode
JOIN SUBSCRIPTION s2
ON u.Code = s2.UserCode
WHERE s1.ID <> s2.ID
AND u.Age > 50
I believe the simplest way to accomplish this is to essentially redesign the count function into a sum function with a case statement thusly:
SELECT
u.NAME
, u.SURNAME
, u.CODE
, SUM(CASE WHEN t.SUBSCRIPTION IS NOT NULL THEN 1 ELSE 0 END) as TOTAL_SUBSCRIPTIONS -- IDENTICAL TO COUNT(s.*)
, COUNT(s.*) -- SHOULD MATCH THE TOTAL_SUBSCRIPTIONS
FROM
USER AS u
LEFT JOIN SUBSCRIPTION AS s
ON u.CODE = s.USERCODE
-- LEFT JOIN THEATRE AS t -- commented because I don't see a requirement for this table to be brought forward.
-- ON s.THEATRENAME = t.NAME
WHERE u.AGE > 50
HAVING SUM(CASE WHEN t.SUBSCRIPTION IS NOT NULL THEN 1 ELSE 0 END) > 1
Without using a CASE statment:
SELECT
u.NAME
, u.SURNAME
, u.CODE
, SUM( (select SUM(1) from SUBSCRIPTION WHERE s.USERCODE = u.CODE) ) as TOTAL_SUBSCRIPTIONS -- IDENTICAL TO COUNT(s.*)
FROM
USER AS u
WHERE u.AGE > 50

Count number of occurrences based on user id

I'm very new to SQL/MySQL and Stackoverflow for that matter, and I'm trying to create a query through iReport (though I don't have to use iReport) for SugarCRM CE. What I need is to create a report that displays the number of "Referrals", "Voicemails", "Emails", and "Call_ins" that are linked to a specific "user" (employee). The query I currently have set up works; however it is running through the data multiple times generating a report that is 200+ pages. This is the code that I am currently using:
SELECT
( SELECT COUNT(*) FROM `leads` INNER JOIN `leads_cstm` ON `leads`.`id` = `leads_cstm`.`id_c` WHERE (leadtype_c = 'Referral' AND users.`id` = leads.`assigned_user_id`) ),
( SELECT COUNT(*) FROM `leads` INNER JOIN `leads_cstm` ON `leads`.`id` = `leads_cstm`.`id_c` WHERE (leadtype_c = 'VM' AND users.`id` = leads.`assigned_user_id`) ),
( SELECT COUNT(*) FROM `leads` INNER JOIN `leads_cstm` ON `leads`.`id` = `leads_cstm`.`id_c` WHERE (leadtype_c = 'Email' AND users.`id` = leads.`assigned_user_id`) ),
users.`first_name`,users.`last_name`
FROM
`users` users,
`leads` leads
I would appreciate any guidance!
You want to use conditional summation. The following uses MySQL syntax:
SELECT sum(leadtype_c = 'Referral') as Referrals,
sum(leadtype_c = 'VM') as VMs,
sum(leadtype_c = 'Email') as Emails,
users.`first_name`, users.`last_name`
FROM users join
`leads`
on users.`id` = leads.`assigned_user_id` INNER JOIN
`leads_cstm`
ON `leads`.`id` = `leads_cstm`.`id_c`
group by users.id;
You can use COUNT with CASE for this:
SELECT u.first_name,
u.last_name,
count(case when leadtype_c = 'Referral' then 1 end),
count(case when leadtype_c = 'VM' then 1 end),
count(case when leadtype_c = 'Email' then 1 end)
FROM users u
JOIN leads l ON u.id = l.assigned_user_id
JOIN leads_cstm lc ON l.id = lc.id_c
GROUP BY u.id
To match your exact results, you should probably use an OUTER JOIN instead, but this gives you the idea.
A Visual Explanation of SQL Joins

How to create multiple counts in a mysql statement

I have some trouble to count more than 2 counts in mysql statement.
My count(b.entry_id) as totalbooking wont work. What have i done wrong? Is the statement setup also correctly made​​?
This is how i tried:
"SELECT
t.restaurant_id as restaurant_id, ct.title as title,
count(DISTINCT t.cardid) as totalmembers,
count(t.restaurant_id) as totaltransactions,
count(b.entry_id) as totalbooking
from transactions as t
inner join exp_menucard_booking as b on (t.restaurant_id = b.entry_id)
inner join exp_channel_titles as ct on (t.restaurant_id = ct.entry_id)
inner JOIN exp_channel_data as cd on (ct.entry_id = cd.entry_id)
where t.cardid != 88888888 and ct.status = 'open'
group by t.restaurant_id
order by ct.title asc";
Use this pattern to count subsets of the total rowset:
sum( case when ColumnToBeTested = trueCondition then 1 else 0 end) as SubCount