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'
...
Related
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
Sorry for the wordy mess of a question. I have a query that draws data from the User table and I want to pull the completionstate from the course_modules_completion table for each activity in a course per user and course. I'm having trouble linking multiple values from various tables to a user per row.
I was able to obtain the info I wanted from the User table just fine. I then join multiple tables in order to be able to pull the completionstate field from the course_modules_completion table. What I need to do is pull the value of completionstate corresponding to each activity in a course for every user.
SELECT u.username AS 'ID'
,u.firstname AS 'Names'
,u.lastname AS 'Lastnames'
,(SELECT completionstate FROM prefix_course_modules_completion cmc
INNER JOIN prefix_user u ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (r.id = 6) AND (c.id = 5)
) AS 'Activity 1'
FROM prefix_user u LEFT JOIN prefix_grade_grades g ON u.id = g.userid
INNER JOIN prefix_course_modules_completion cmc ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (u.id > 7) AND (u.firstaccess > 0) AND (c.id = 5)
GROUP BY u.username
ORDER BY u.firstname ASC
What I expected was something like this:
ID - Name - Last name - Email - Activity 1 - Activity 2 - Test
382 - John - Johnson - email#e.com - Seen - Not seen - Failed
17 - Mark - Markson - email2#e.com - Seen - Seen - Passed
Instead what I'm getting are multiple rows of the same user with the values wanted or the same value wanted for all users as if it wasn't making any distinction about the user. As you can see in the code above, I tried with a subquery just for the completionstate value but it's returning multiple rows and thus, an error.
Furthermore, I want to show the values from the completionstate column as text. There are four values in that column: 0, 1, 2, 3 and what I'd like to do is transform each into "Not seen", "Seen", "Completed and passed" and "Completed and failed" respectively.
Because I'm a beginner in SQL I'm having trouble identifying if my issues are because of bad logic, bad coding or both.
Edit: Pruned the code a little to make it simpler for this question.
What you're trying to do is a kind of pivot, so you can do it without the correlated subqueries.
SELECT u.username AS 'ID'
,u.firstname AS 'Names'
,u.lastname AS 'Lastnames'
,u.email AS 'Email'
,c.fullname AS 'Course'
,(LEFT(g.finalgrade,2)) AS 'Final grade'
,ELT(MAX(IF(r.id = 6, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 1`
,ELT(MAX(IF(r.id = 7, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 2`
,ELT(MAX(IF(r.id = 8, completion_state, NULL))+1,
'Not seen', 'Seen', 'Completed and passed', 'Completed and failed') AS `Activity 3`
FROM prefix_user u LEFT JOIN prefix_grade_grades g ON u.id = g.userid
INNER JOIN prefix_course_modules_completion cmc ON cmc.userid = u.id
INNER JOIN prefix_course_modules cm ON cmc.coursemoduleid = cm.id
INNER JOIN prefix_course c ON cm.course = c.id
INNER JOIN prefix_resource r ON c.id = r.course
WHERE (u.id > 7) AND (u.firstaccess > 0) AND (c.id = 5)
GROUP BY u.id
ORDER BY u.firstname ASC
Yuo should also group by u.id rather than u.username. This will allow you to select other columns that are functionally dependent on this primary key without using aggregation functions.
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.
I know some degree of MySQL, but I'm not sure if there's a more correct way to do what I'm doing here.
#Select Ticket ID, Ticket Title, Assigned To
SELECT * FROM
(SELECT
ti.number, ti.ticket_id, foev.value AS "ticket_name",
CASE WHEN ti.staff_id = 0 AND ti.team_id = 0
then
"** Unassigned **"
ELSE
CASE when ti.staff_id = 0
THEN
(SELECT te.name FROM ost_team te WHERE te.team_id = ti.team_id)
ELSE
(SELECT CONCAT(st.firstname,LEFT(st.lastname,1)) FROM ost_staff st WHERE st.staff_id = ti.staff_id)
END
END AS "assigned_to"
FROM ost_ticket ti
LEFT JOIN ost_form_entry foe ON foe.object_id = ti.ticket_id AND foe.object_type = "T"
LEFT JOIN ost_form_entry_values foev ON foev.entry_id = foe.id
GROUP BY ti.ticket_id)
AS ticket_meta_list
ORDER BY ticket_id ASC;
Is there a more correct way to do those subqueries? I'm thinking there may be with joins that I'm less familiar with.
If your staff table has no staff_id with value 0, and your team table has no team_id with value 0, you can use left join in combination with coalesce:
SELECT ti.number,
ti.ticket_id,
foev.value AS ticket_name,
COALESCE(CONCAT(st.firstname,LEFT(st.lastname,1)),
te.name, '** Unassigned **') AS assigned_to
FROM ost_ticket ti
LEFT JOIN ost_form_entry foe
ON foe.object_id = ti.ticket_id
AND foe.object_type = 'T'
LEFT JOIN ost_form_entry_values foev
ON foev.entry_id = foe.id
LEFT JOIN ost_team te
ON te.team_id = ti.team_id
LEFT JOIN ost_staff st
ON st.staff_id = ti.staff_id
GROUP BY ti.ticket_id
ORDER BY ticket_id
I am joining multiple tables into a single query. I need to do a partial match on values in an IN statement. Here is an example.
SELECT DISTINCT
am.id AS id,
am.flagged AS flagged,
am.name AS name,
am.type AS type,
am.file AS file,
am.s3_tag AS s3_tag,
am.low_s3_tag AS low_s3_tag
FROM accounts_media am
LEFT JOIN accounts_location_media alm ON am.id = alm.media_id
LEFT JOIN accounts_location al ON al.id = alm.location_id
LEFT JOIN accounts_person_media apm ON am.id = apm.media_id
LEFT JOIN accounts_person ap ON ap.id = apm.person_id
LEFT JOIN accounts_event_media_record aemr ON am.id=aemr.media_id
LEFT JOIN accounts_medianote_media_record amma ON am.id=amma.media_id
LEFT JOIN accounts_medianote amn ON amma.medianote_id=amn.id
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
AND ('Da' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
AND ('Rob' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
In the
AND ('Da' IN (SELECT first_name FROM accounts_person WHERE account_id = '1234')
statement there are values that say 'Dan', 'Daniel', etc. in the table. There is also 'Rob' and 'Robert'. I need that statement to make sure and name that contains 'Da' AND any name that contains 'Rob' from that table. Is there a way to do this?
So a record can be linked to multiple people in the accounts_person table. So lets say I have three records.
Record One: A person named Dan is attached to the record.
Record Two: A person named Robert is attached to the record.
Record Three: A person named Dan and a person named Robert are attached to the record.
I want the query to only return Record Three because it has the match of 'Da' and 'Rob'.
Try this:
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
-- AND ( ap.first_name LIKE '%Da%' OR ap.first_name LIKE '%Rob%')
AND EXISTS
( SELECT 1
FROM accounts_person apx
WHERE apx.first_name LIKE '%Da%'
AND apx.account_id = am.account_id
)
AND EXISTS
( SELECT 1
FROM accounts_person apy
WHERE apy.first_name LIKE '%Rob%'
AND apy.account_id = am.account_id
)
I'm not sure, but I think you want a like statement, with a wild card after the Da.
SELECT DISTINCT
am.id AS id,
am.flagged AS flagged,
am.name AS name,
am.type AS type,
am.file AS file,
am.s3_tag AS s3_tag,
am.low_s3_tag AS low_s3_tag
FROM accounts_media am
LEFT JOIN accounts_location_media alm ON am.id = alm.media_id
LEFT JOIN accounts_location al ON al.id = alm.location_id
LEFT JOIN accounts_person_media apm ON am.id = apm.media_id
LEFT JOIN accounts_person ap ON ap.id = apm.person_id
LEFT JOIN accounts_event_media_record aemr ON am.id=aemr.media_id
LEFT JOIN accounts_medianote_media_record amma ON am.id=amma.media_id
LEFT JOIN accounts_medianote amn ON amma.medianote_id=amn.id
WHERE
am.account_id = '1234'
AND am.flagged = FALSE
AND (accounts_person.first_name like '%Da%'
OR accounts_person.first_name like '%Rob%')
AND accounts_person.account_id = '1234'