I'm working with a frustrating set of data that contains null, 0, 1, and 2 values for the 'active' column in my users table.
Why does this work:
SELECT u.id AS LegacyContactKey,
u.first_name AS FirstName,
u.last_name AS LastName,
c.company_name AS CompanyName,
u.email AS EmailAddress,
(CASE WHEN u.active = 1 THEN 1 WHEN u.active = 2 THEN 1 ELSE 0 END) as IsMember
FROM tb_users AS u
INNER JOIN tb_company AS c ON u.company_id = c.company_id
But not this?
SELECT u.id AS LegacyContactKey,
u.first_name AS FirstName,
u.last_name AS LastName,
c.company_name AS CompanyName,
u.email AS EmailAddress,
CAST((CASE WHEN u.active = 1 THEN 1 WHEN u.active = 2 THEN 1 ELSE 0 END) AS BOOLEAN) as IsMember
FROM tb_users AS u
INNER JOIN tb_company AS c ON u.company_id = c.company_id
I want to cast one of my query results as a boolean so it returns true or false but when I add CAST() I get an error (near BOOLEAN)
Running MariaDB 10.3
I don't think cast() supports boolean. But the simplest method is really:
(u.active IN (1, 2)) as IsMember
You can just use a boolean expression and assign a column alias to it.
EDIT:
If NULL is an issue, just include it in the expression:
(u.active IN (1, 2) AND u.active IS NOT NULL) as IsMember
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 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'
...
I am using the following SQL Query:
SELECT package_stats.developer
,xf_user.username
,xf_user.email
,xf_user_profile.homepage
,xf_user_profile.location
,xf_user_profile.about
,CASE WHEN field_id ='Github' THEN field_value ELSE '' END AS Github
,CASE WHEN field_id ='Repository' THEN field_value ELSE '' END AS Repository
,CASE WHEN field_id ='twitter' THEN field_value ELSE '' END AS Twitter
FROM package_stats, xf_user, xf_user_field_value, xf_user_profile
WHERE xf_user.username = package_stats.developer AND xf_user_profile.user_id = xf_user.user_id AND xf_user_field_value.user_id = xf_user.user_id AND xf_user_field_value.field_value <> ''
Which outputs the following:
developer username email about Github Repository Twitter
John Doe jdoe j#doe.com It's me https://github....
John Doe jdoe j#doe.com It's me
John Doe jdoe j#doe.com It's me https://link....
John Doe jdoe j#doe.com It's me https://twitter.com/...
How can I mix all those rows into a single row?
I believe you can use conditional aggregation:
SELECT ps.developer, u.username, u.email,
up.homepage, up.location, up.about,
MAX(CASE WHEN ufv.field_id = 'Github' THEN ufv.field_value END) AS Github,
MAX(CASE WHEN ufv.field_id = 'Repository' THEN ufv.field_value END) AS Repository,
MAX(CASE WHEN ufv.field_id = 'twitter' THEN ufv.field_value END) AS Twitter
FROM package_stats ps JOIN
xf_user u
ON u.username = ps.developer JOIN
xf_user_profile up
ON up.user_id = u.user_id JOIN
xf_user_field_value ufv
ON ufv.user_id = u.user_id
WHERE ufv.field_value <> ''
GROUP BY ps.developer, u.username, u.email,
up.homepage, up.location, up.about;
Notes:
Table aliases make the query easier to write and to read.
All columns should be qualified with a table alias, to avoid ambiguity.
There is no reason to have an ELSE clause for this purpose. If there are no matches, then the column is NULL (a reasonable value).
If there could be more than one field for a given category, use GROUP_CONCAT().
You could use a (fake) aggregation function and group by
SELECT package_stats.developer
,xf_user.username
,xf_user.email
,xf_user_profile.homepage
,xf_user_profile.location
,xf_user_profile.about
,min(CASE WHEN field_id ='Github' THEN field_value END) AS Github
,min(CASE WHEN field_id ='Repository' THEN field_value END) AS Repository
,min(CASE WHEN field_id ='twitter' THEN field_value END ) AS Twitter
FROM package_stats
INNER JOIN xf_user ON xf_user.username = package_stats.developer
INNER JOIN xf_user_profile ON xf_user_profile.user_id = xf_user.user_id
INNER JOIN xf_user_field_value v1 ON xf_user_field_value.user_id = xf_user.user_id
WHERE xf_user_field_value.field_value <> ''
GROUP BY package_stats.developer
,xf_user.username
,xf_user.email
,xf_user_profile.homepage
,xf_user_profile.location
,xf_user_profile.about
and don't use implict joins are not clear ..
the implict join is an arcaic sintax
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
I have a query that looks like this:
SELECT
app.application_id,
j.job_number,
j.job_id,
j.job_title,
j.job_city,
j.job_state,
p.person_id AS candidate_id,
p.first_name,
p.last_name,
app.start_date,
ope1.percent_complete,
MAX(CASE
WHEN r.role_display_name = 'ENG - Recruiter' THEN
(SELECT CASE WHEN COUNT(last_name) = 0 THEN
'Unassigned'
ELSE
COUNT(last_name)
END AS uname
FROM users
JOIN job_roles ON job_roles.user_id = users.user_id
WHERE job_id = j.job_id
AND role_id = r.role_id
)
ELSE '' END) AS role_3
My problem is that COUNT(last_name) will not return 0, because there are no records returned, so there is no value of NULL. All makes sense, however I have tried wrapping it in IFNULL(), ISNULL() and none of them seem to fix this problem. How can I get it to return 0 when there are no records? Do I need another subquery inside the COUNT() aggregate? I would really like to not use another subquery....
If understand correctly what you want you can try to rewrite it this way
SELECT ...
,MAX(CASE WHEN r.role_display_name = 'ENG - Recruiter'
THEN COALESCE(NULLIF(
(
SELECT COUNT(last_name)
FROM users JOIN job_roles
ON job_roles.user_id = users.user_id
WHERE job_id = j.job_id
AND role_id = r.role_id
), 0), 'Unassigned')
ELSE ''
END) as role_3
...