mysql 'as' repated - mysql

The 1st piece of code works fine and gives me the results I need.
what I want to do now is to have it return 3 number values on the 'as num'
for 3 different values on the 'as num' for 3 different where on the same column
SELECT COUNT(garage_list.account_id) as num,
garage_list.account_id,
garage_list.tank_id,
player_list.clan,
player_list.nickname,
tank_list.level
FROM garage_list
RIGHT JOIN player_list ON garage_list.account_id = player_list.account_id
RIGHT JOIN tank_list ON garage_list.tank_id = tank_list.tank_id
where tank_list.level='8'
and player_list.clan = 'bad-1'
GROUP BY account_id
above works
need to have a returned value for each of the " where tank_list.level='??' "
SELECT COUNT(garage_list.account_id) as num,
garage_list.account_id,
garage_list.tank_id,
player_list.clan,
player_list.nickname,
tank_list.level
FROM garage_list
RIGHT JOIN player_list ON garage_list.account_id = player_list.account_id
RIGHT JOIN tank_list ON garage_list.tank_id = tank_list.tank_id
where tank_list.level='6' //return a value for this
where tank_list.level='8' //return a value for this
where tank_list.level='10' //return a value for this
and player_list.clan = 'bad-1'
GROUP BY account_id

You need a conditional COUNT using a CASE:
SELECT COUNT(case when tank_list.level='6' then garage_list.account_id end) as num1,
COUNT(case when tank_list.level='8' then garage_list.account_id end) as num2,
COUNT(case when tank_list.level='10' then garage_list.account_id end) as num3,
garage_list.account_id,
garage_list.tank_id,
player_list.clan,
player_list.nickname,
tank_list.level
FROM garage_list
RIGHT JOIN player_list ON garage_list.account_id = player_list.account_id
RIGHT JOIN tank_list ON garage_list.tank_id = tank_list.tank_id
where tank_list.level in ('6','8','10')
and player_list.clan = 'bad-1'
GROUP BY account_id
And you need to check if your Outer Join logic is correct.

Related

MySQL - Joining same table twice, parent sum column value getting duplicated

I'm just 3 months of experience in MySQL. Here I'm trying to generate a report based on log and part table. When trying to join the "Part" table twice, the "Log" table Quantity gets doubled. Kindly let me know where I'm doing wrong.
Log Table
Part Table
Expected Report
Query Used
SELECT
report.*,
(SUM(report.quantity)) AS totalQuantity,
normalPart.price AS normalPrice,
premiumPart.price AS premiumPrice
FROM
log AS report
LEFT JOIN
(SELECT
*
FROM
part AS normalPart
WHERE
normalPart.type = 'normal'
GROUP BY normalPart.partNumber , normalPart.genId) AS normalPart ON report.partNumber = normalPart.partNumber
AND report.genId = normalPart.genId
AND normalPart.cat = report.fromCat
LEFT JOIN
(SELECT
*
FROM
part AS premiumPart
WHERE
premiumPart.type = 'premium'
GROUP BY premiumPart.partNumber , premiumPart.genId) AS premiumPart ON report.partNumber = premiumPart.partNumber
AND report.genId = premiumPart.genId
AND premiumPart.cat = report.toCat;
Query Result
This answers the original version of the question.
Aggregate before you join:
select l.*, p.normal_price, p.premium_price
from (select genid, partnumber, sum(quantity) as quantity
from log
group by genid, partnumber
) l left join
(select partnumber, genid,
max(case when type = 'normal' then price end) as normal_price,
max(case when type = 'premium' then price end) as premium_price
from part
group by partnumber, genid
) p
on p.partnumber = l.partnumber and p.genid = l.genid

Where clause using alias column with IF and IFNULL

I have an mysql query like below:
SELECT
sppt_ticket.*,
IF(sppt_read_support_ticket.ID_aks_user IS NULL,'N', 'Y') AS `read_status`,
IFNULL(readcomment.total_comment, 0) AS unread_comment
FROM
sppt_ticket
LEFT JOIN
sppt_read_support_ticket ON
sppt_ticket.ID_support_ticket = sppt_read_support_ticket.ID_support_ticket AND
ID_aks_user = 1
LEFT JOIN
(SELECT
sppt_comment.ID_support_ticket, SUM(IF(sppt_read_comment.ID_aks_user IS NULL, 1, 0))
AS
total_comment
FROM
sppt_comment
LEFT JOIN
sppt_read_comment
ON
sppt_comment.ID_comment = sppt_read_comment.ID_comment
AND
sppt_read_comment.ID_aks_user = 1
GROUP BY
sppt_comment.ID_support_ticket) AS readcomment ON readcomment.ID_support_ticket = sppt_ticket.ID_support_ticket
What I want to get in where clause is like this
WHERE read_status = 'Y'
I've tried using subquery, but still I didn't get it..
any help?
Have you tried this:
SELECT * FROM
(
-- your original query as a table
SELECT
sppt_ticket.*,
IF(sppt_read_support_ticket.ID_aks_user IS NULL,'N', 'Y') AS `read_status`,
IFNULL(readcomment.total_comment, 0) AS unread_comment
FROM
sppt_ticket
LEFT JOIN
sppt_read_support_ticket ON
sppt_ticket.ID_support_ticket = sppt_read_support_ticket.ID_support_ticket AND
ID_aks_user = 1
LEFT JOIN
(SELECT
sppt_comment.ID_support_ticket, SUM(IF(sppt_read_comment.ID_aks_user IS NULL, 1, 0))
AS
total_comment
FROM
sppt_comment
LEFT JOIN
sppt_read_comment
ON
sppt_comment.ID_comment = sppt_read_comment.ID_comment
AND
sppt_read_comment.ID_aks_user = 1
GROUP BY
sppt_comment.ID_support_ticket) AS readcomment ON readcomment.ID_support_ticket = sppt_ticket.ID_support_ticket
)
as temptable
where read_status = 'Y' -- this should work
Or you can use HAVING instead of WHERE if you do not want to treat your query as a table:
SELECT
sppt_ticket.*,
IF(sppt_read_support_ticket.ID_aks_user IS NULL,'N', 'Y') AS `read_status`,
IFNULL(readcomment.total_comment, 0) AS unread_comment
FROM
sppt_ticket
LEFT JOIN
sppt_read_support_ticket ON
sppt_ticket.ID_support_ticket = sppt_read_support_ticket.ID_support_ticket AND
ID_aks_user = 1
LEFT JOIN
(SELECT
sppt_comment.ID_support_ticket, SUM(IF(sppt_read_comment.ID_aks_user IS NULL, 1, 0))
AS
total_comment
FROM
sppt_comment
LEFT JOIN
sppt_read_comment
ON
sppt_comment.ID_comment = sppt_read_comment.ID_comment
AND
sppt_read_comment.ID_aks_user = 1
GROUP BY
sppt_comment.ID_support_ticket) AS readcomment ON readcomment.ID_support_ticket = sppt_ticket.ID_support_ticket
HAVING read_status = 'Y' -- use HAVING instead of WHERE
The reason why treating your original query as a table works is because of the way values are evaluated in the query. In your original query, the alias read_status cannot be used with the WHERE clause because the actual value might not yet be known when the WHERE clause is evaluated. As documented in Section B.1.5.4, “Problems with Column Aliases”. Treating it as a table ensures that the value for read_status has already been evaluated.
For the HAVING approach, MySQL created an extension to standard SQL that permits references in the HAVING clause to aliased expressions in the select list.

MySQL | Sum Column If Different ID

I'm trying to Sum column only if id is different.
I tried like this, but it is not working:
SUM(CASE WHEN
DISTINCT empLeaves.ApprovedLeaveID
THEN empLeaves.TotalLeavesTaken END) AS Total
What Would be the proper way to SUM it?
Here is the total query, I am working on:
SELECT
E.employee_id AS EmployeeID,
E.employee_code AS EmployeeCode,
E.full_name AS EmployeeName,
empLeaves.LeavesFromDate,
empLeaves.LeavesToDate,
-- COUNT(empLeaves.ApprovedLeaveID) AS TotalApprovedApplications,
ATT.`in_date` AS InDate,
ATT.`out_date` AS OutDate,
SUM(CASE WHEN DISTINCT empLeaves.ApprovedLeaveID THEN empLeaves.TotalLeavesTaken END) AS Total
FROM employee E
LEFT JOIN `attendence` ATT ON ATT.`employee_id` = E.`employee_id`
LEFT JOIN (
SELECT
LA.`leave_approval_id` AS ApprovedLeaveID,
E.`employee_id` AS EmployeeID,
LA.`approved_from` AS LeavesFromDate,
LA.`approved_to` AS LeavesToDate,
DATEDIFF(LA.approved_to,approved_from) AS TotalLeavesTaken
FROM leave_application APP
INNER JOIN leave_approval LA
ON LA.`leave_application_id` = APP.`application_id` AND LA.`trashed` = 0 AND LA.`status` = 2
INNER JOIN employee E
ON E.`employee_id` = APP.`employee_id` AND E.`trashed` = 0 AND E.`enrolled` = 1
INNER JOIN ml_leave_type MLLT
ON MLLT.`ml_leave_type_id` = APP.`ml_leave_type_id` AND MLLT.`trashed` = 0
) empLeaves ON E.`employee_id` = empLeaves.EmployeeID
WHERE
E.`enrolled` = 1 AND E.`trashed` = 0
GROUP BY
E.`employee_id`,empLeaves.EmployeeID
When which ID is different from what?
In general, when you have a value in a field and you want to add them together except for those in a particular set of rows, you simply set the unwanted values to 0:
sum( case otherfield when somevalue then row.field else 0 end ) as SumOfValues
So when otherfield shows that this is the row you want included in the total, you expose the field you want to add (row.field in this example). Otherwise, you expose a zero. Of course, if the value you're testing is to find the rows you don't want in the total, just put the zero after the then and the field after the else.

SOQL: Avoid count with NULL results return 0 (zero) instead

I have a problem, I have written a query and I need to return the count of opportunities in the given order: Name1, Name2, Name3, Name4. The problem is that if the count is NULL for example for Name2, then the query returns Name1_count, Name3_count, Name4_count.
I need to make sure that I always get the values in the right order and if the value is null i need to get back 0. But its not working :(
I tried:
Select Owner.Name
,IF(ISBLANK(count(id))
,0
,count(id))
from Opportunity
where CloseDate = Today
and Approved__c = true
and (Owner.Name = 'Name1'
or Owner.Name = 'Name2'
or Owner.Name = 'Name3'
or Owner.Name = 'Name4')
group by Owner.Name
Your query uses a table alias called owner which is not defined. Presumably, this is supposed to refer to Opportunity, although that is just a guess. Also, to get a 0 when you have a NULL, the typical function is coalesce(). And I replaced the complicated set of ors with in:
Select o.Name, coalesce(count(id), 0)
from Opportunity o
where CloseDate = Today and Approved__c = true and
o.Name in ('Name1', 'Name2', 'Name3', 'Name4')
group by o.Name ;
Finally, to get all four names in the output, you need to use left outer join:
Select names.Name, count(o.id) as cnt
from (select 'Name1' as name union all select 'Name2' union all
select 'Name3' union all select 'Name4'
) names left outer join
Opportunity o
on names.name = o.name
where CloseDate = Today and Approved__c = true
group by names.Name ;

count multiple in one statement

i have a table with data title and date of the data inserted.
and right now i want to do count to make the statistic out of it.
can i do multiple count in one sql statement?
like from, the column date, i want to count how many on this month, and how many in this year, until month selected. is it possible? if yes, how?
this is what i have come up, for now.
SELECT a.trigger_type_code
, c.trigger_name
, COUNT(*) AS number
FROM issue_trigger a
INNER JOIN cs_issue b
ON b.issue_id = a.issue_id
INNER JOIN ref_trigger_type c
ON c.trigger_type_code = a.trigger_type_code
WHERE MONTH(b.created_date) = '05'
AND YEAR(b.created_date) = '2011'
GROUP BY trigger_type_code,trigger_name
by this is only for one count.help.:(
You could use a case:
select sum(case when MONTH(b.created_date) = '05'
AND YEAR(b.created_date) = '2011' then 1 end) as Count_2011_05
, sum(case when YEAR(b.created_date) = '2011'
then 1 end) as Count_2011
from ... etc ...
I think you could go like this:
SELECT
a.trigger_type_code,
c.trigger_name,
COUNT(MONTH(b.created_date) < 5 OR NULL) AS before_the_month,
COUNT(MONTH(b.created_date) = 5 OR NULL) AS in_the_month
FROM issue_trigger a
INNER JOIN cs_issue b
ON b.issue_id = a.issue_id
INNER JOIN ref_trigger_type c
ON c.trigger_type_code = a.trigger_type_code
WHERE YEAR(b.created_date) = 2011
GROUP BY a.trigger_type_code, c.trigger_name