Remove second row caused by WITH ROLLUP - mysql

I need to remove the 2nd row of results which contain a duplicate of the total record from the 1st row. My result set is as follows
1 | 1025
1 | NULL --- I need to remove this row
My query is as follows:
SELECT SUM( mdl_quiz.fcpd ) AS cpdtotal, mdl_user.id AS userid
FROM mdl_grade_grades
INNER JOIN mdl_user ON mdl_grade_grades.userid = mdl_user.id
INNER JOIN mdl_grade_items ON mdl_grade_grades.itemid = mdl_grade_items.id
INNER JOIN mdl_quiz ON mdl_grade_items.itemname = mdl_quiz.name
INNER JOIN mdl_course ON mdl_grade_items.courseid = mdl_course.id
INNER JOIN mdl_user_info_data ON mdl_user.id = mdl_user_info_data.userid
WHERE mdl_user_info_data.fieldid =1
AND mdl_grade_items.itemname IS NOT NULL
AND mdl_user.annualCPDReportActive = 'Y'
AND (
mdl_course.category =27
)
AND mdl_user.id =1025
AND YEAR( FROM_UNIXTIME( mdl_grade_grades.timemodified ) ) =2013
GROUP BY mdl_user.id
WITH ROLLUP

You should remove WITH ROLLUP
more information here.

Related

mysql query taking long time to respond

SELECT t.id
, t.department
, t.owner
, t.client
, u.username as owner_name
, c.name as catagery
, d.dept_name as deptname
, t.periority
, t.status
, t.estimate
, cl.takeaway_name
from tbl_task t
JOIN tbl_user u
ON u.id = t.owner
JOIN tbl_task_catagery c
ON c.id = t.catagery
JOIN tbl_department d
ON d.id = t.department
JOIN tbl_clients cl
ON cl.id = t.client
and t.status = 0
and (t.id in (select task_id
from tbl_task_note tn
where tn.user_id = '69'
and tn.id in (select max(id)
from tbl_task_note tt
where tt.task_id = tn.task_id
)
)
)
order by t.id
Note : The above query is used for check users hold tasks. tbl_task_note table is used for check task notes for separate users task.
With this query you will get the task that have the last task_note registered, including the user, departament, client, and some other.
If it is what you need you can just do this.
select
t.id,
t.department,
t.owner,
t.client,
u.username as owner_name,
c.name as catagery,
d.dept_name as ptname,
t.periority,
t.status,
t.estimate,
cl.takeaway_name
from tbl_task t
INNER JOIN tbl_user u ON u.id=t.owner
INNER JOIN tbl_task_catagery c ON c.id=t.catagery
INNER JOIN tbl_department d ON d.id=t.department
INNER JOIN tbl_clients cl ON cl.id=t.client and t.status=0
INNER JOIN (select * from tbl_task_note where id =
(select max(id) from tbl_task_note)
)tb on tb.task_id = t.id
order by t.id
That way you can improve your query.
You shoud also ensure that your keys compared are foreign keys to get faster consults.

MySQL SELECT in a UNION statement is not able to refer to the parent table

I'm trying to execute the following MySQL SELECT statement, to get the date of the last activity done against a every parent opportunity id.
The list of activities will be retrieved from 4 tables: calls, meetings, tasks, emails.
I'm getting a syntax error when I add the the condition "XXXXX.parent_id = opportunities.id" (in the inner 4 sub-SELECTS).
If I delete "XXXXX.parent_id = opportunities.id", the statements gets executed (but, of course, results are irrelevant to what I want).
Here is the code I'm tried:
SELECT
opportunities.id,
opportunities.name,
(
SELECT MAX(`last_activity_date`) FROM
(
SELECT c.date_end AS `last_activity_date`
FROM calls AS c
WHERE c.parent_type = 'Opportunities'
AND c.parent_id = opportunities.id
AND c.status IN ('Held')
AND c.deleted = '0'
UNION
SELECT m.date_end
FROM meetings AS m
WHERE m.parent_type = 'Opportunities'
AND m.parent_id = opportunities.id
AND m.status IN ('Held')
AND m.deleted = '0'
UNION
SELECT t.date_due
FROM tasks AS t
WHERE t.parent_type = 'Opportunities'
AND t.parent_id = opportunities.id
AND t.status IN ('Completed')
AND t.deleted = '0'
UNION
SELECT e.date_sent
FROM emails AS e
WHERE e.parent_type = 'Opportunities'
AND e.parent_id = opportunities.id
AND e.status IN ('sent', 'archived')
AND e.deleted = '0'
) AS `activities`
) AS "opportunities_activities"
FROM opportunities
WHERE opportunities.deleted = '0'
ORDER BY opportunities.id ASC
You can not use outer query fields inside the inner nested query as each inner query must be independent of any outer query.
Try query below for desired result.
SELECT
opportunities.id,
opportunities.name,
(
SELECT MAX(`last_activity_date`) FROM
(
SELECT c.date_end AS `last_activity_date`
FROM calls AS c
join opportunities o on c.parent_id = o.id
WHERE c.parent_type = 'Opportunities'
AND c.status IN ('Held')
AND c.deleted = '0'
UNION
SELECT m.date_end
FROM meetings AS m
join opportunities o on m.parent_id = o.id
WHERE m.parent_type = 'Opportunities'
AND m.status IN ('Held')
AND m.deleted = '0'
UNION
SELECT t.date_due
FROM tasks AS t
join opportunities o on t.parent_id = o.id
WHERE t.parent_type = 'Opportunities'
AND t.status IN ('Completed')
AND t.deleted = '0'
UNION
SELECT e.date_sent
FROM emails AS e
join opportunities o on e.parent_id = o.id
WHERE e.parent_type = 'Opportunities'
AND e.status IN ('sent', 'archived')
AND e.deleted = '0'
) AS `activities`
) AS "opportunities_activities"
FROM opportunities
WHERE opportunities.deleted = '0'
ORDER BY opportunities.id ASC

Using MAX shuffles records around

I have the following influences table:
I need to get the latest influence for a stakeholder...
I have the following query but it's mixing up the row data because MAX isn't returning a full record:
SELECT stakeholder_id, MAX(created_at) AS maxca, influence
FROM influences
WHERE
project_id = 1 AND
deleted_at IS NULL
GROUP BY stakeholder_id
You can see that the influence against that maxca and stakeholder_id should be 3, not 5.
How do I overcome this issue?
My full existing statement was this:
SELECT `stakeholders`.*, `influences`.`influence`
FROM `project_stakeholder`
INNER JOIN `stakeholders` ON `project_stakeholder`.`stakeholder_id` = `stakeholders`.`id`
INNER JOIN `stakeholder_profiles` ON `stakeholder_profiles`.`stakeholder_id` = `stakeholders`.`id`
LEFT JOIN `stakeholder_profile_tag` ON `stakeholder_profile_tag`.`stakeholder_profile_id` = `stakeholder_profiles`.`id`
LEFT JOIN `stakeholder_profile_group` ON `stakeholder_profile_group`.`stakeholder_profile_id` = `stakeholder_profiles`.`id`
LEFT JOIN `influences` ON `influences`.`stakeholder_id` = `stakeholders`.`id`
INNER JOIN `projects` ON `project_stakeholder`.`project_id` = `projects`.`id`
LEFT JOIN (
/*! This is the bit that doesn't work */
SELECT stakeholder_id, MAX(created_at) AS maxca
FROM influences
WHERE
project_id = 1 AND
deleted_at IS NULL
GROUP BY stakeholder_id
)
iu ON `iu`.`stakeholder_id` = influences.stakeholder_id AND
iu.maxca = influences.created_at
WHERE `projects`.`id` = '1'
GROUP BY `stakeholders`.`id`
This seems to work:
SELECT `stakeholders`.*, iu.influence
FROM `project_stakeholder`
INNER JOIN `stakeholders` ON `project_stakeholder`.`stakeholder_id` = `stakeholders`.`id`
INNER JOIN `stakeholder_profiles` ON `stakeholder_profiles`.`stakeholder_id` = `stakeholders`.`id`
LEFT JOIN `stakeholder_profile_tag` ON `stakeholder_profile_tag`.`stakeholder_profile_id` = `stakeholder_profiles`.`id`
LEFT JOIN `stakeholder_profile_group` ON `stakeholder_profile_group`.`stakeholder_profile_id` = `stakeholder_profiles`.`id`
INNER JOIN `projects` ON `project_stakeholder`.`project_id` = `projects`.`id`
LEFT JOIN (
select i1.*
from influences i1
join
(
SELECT stakeholder_id, MAX(created_at) AS maxca
FROM influences
WHERE project_id = 1
AND deleted_at IS NULL
GROUP BY stakeholder_id
) i2 on i1.stakeholder_id = i2.stakeholder_id
and i1.created_at = i2.maxca
) iu ON `iu`.`stakeholder_id` = stakeholders.id
WHERE `projects`.`id` = '1'
GROUP BY `stakeholders`.`id`
select i1.*
from influences i1
join
(
SELECT stakeholder_id, MAX(created_at) AS maxca
FROM influences
WHERE project_id = 1
AND deleted_at IS NULL
GROUP BY stakeholder_id
) i2 on i1.stakeholder_id = i2.stakeholder_id
and i1.created_at = i2.maxca

How to combine this SQL query?

i have this query that it works ok but doesn't retrieve exact information (firstname,lastname), it only gives second name
SELECT b.email, c.value AS firstname, a.updated_at, d.added_at
FROM `wishlist` AS a
INNER JOIN customer_entity AS b
ON a.customer_id = b.entity_id
INNER JOIN customer_entity_varchar AS c
ON a.customer_id = c.entity_id
AND c.attribute_id = (
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'lastname'
AND entity_type_id = b.entity_type_id )
INNER JOIN wishlist_item AS d
ON a.wishlist_id = d.wishlist_id
INNER JOIN catalog_product_entity AS e
ON d.product_id = e.entity_id
LEFT JOIN sales_flat_order AS f ON
f.customer_email = b.email
LEFT JOIN sales_flat_order_item AS g
ON ( f.entity_id = g.order_id
AND g.sku LIKE CONCAT( e.sku, '%' )
AND g.product_type = 'simple' )
WHERE d.added_at
BETWEEN '2015-01-01'
AND '2015-02-01'
GROUP BY b.email
This query if i execute will result all customers fullname correctly
SELECT entity_id, group_concat(VALUE SEPARATOR ' ') AS fullname
FROM customer_address_entity_varchar AS val
INNER JOIN eav_attribute AS attr
ON attr.attribute_id = val.attribute_id
WHERE attr.attribute_code IN ( 'firstname', 'lastname' )
How can i edit the 1st query part of retrieving the customer name as the example on the 2nd query?
I am a little bit confused , i tried many combination in sql but non of them will work.
EDIT: i have updated the 1st long query, price should not be there. Also i understand that the group makes no sense but i need only 1 row per customer so i will have to hide the products. If possible all the products to be like wishproduct_1,wishproduct2,wishproduct3 .. in the same row be awesome.
Try this:
SELECT b.email,
h.price as firstname,
c.price AS lastname,
a.updated_at,
d.added_at
FROM `wishlist` AS a
INNER JOIN customer_entity AS b
ON a.customer_id = b.entity_id
INNER JOIN customer_entity_varchar AS c
ON a.customer_id = c.entity_id
AND c.attribute_id =
(
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'lastname'
AND entity_type_id = b.entity_type_id
)
INNER JOIN customer_entity_varchar AS h
ON a.customer_id = c.entity_id
AND c.attribute_id =
(
SELECT attribute_id
FROM eav_attribute
WHERE attribute_code = 'firstname'
AND entity_type_id = b.entity_type_id
)
INNER JOIN wishlist_item AS d
ON a.wishlist_id = d.wishlist_id
INNER JOIN catalog_product_entity AS e
ON d.product_id = e.entity_id
LEFT JOIN sales_flat_order AS f
ON f.customer_email = b.email
LEFT JOIN sales_flat_order_item AS g
ON ( f.entity_id = g.order_id
AND g.sku LIKE CONCAT( e.sku, '%' )
AND g.product_type = 'simple' )
WHERE d.added_at
BETWEEN '2015-01-01' AND '2015-02-01'
GROUP BY b.email, h.price, c.price, a.updated_at, d.added_at
LIMIT 0 , 30
I assumed that the field containing the actual first name would be the same as the one containing the last name (although price seems to be an odd choice). Also since I used correct grouping, you may notice that you will get more records. In that case one or more of teh fields in the group by need to be changed to an aggregate function such as Max() or Min() in order to have one record per email. Your business rules would need to dictate which aggregate function you would apply though.

How to access outer table in a LEFT OUTER JOIN

In the query below, I am trying to use the first table in a left outer join. However I am getting an error.
SELECT
products.id,
products_cstm.oem_c,
products.mfr_part_num,
products.description,
products.cost,
products.assigned_user_id,
customfields_oo.ans
FROM products
LEFT OUTER JOIN (SELECT COUNT( q.id ) AS ans
, pq.product_id
FROM products_quotes pq
LEFT JOIN quotes q
ON pq.quote_id = q.id
WHERE q.deleted = 0
AND pq.deleted = 0
AND q.stage <> 4
AND (pq.qty_shipped < pq.product_qty)
AND pq.product_id = products.id
GROUP BY pq.product_id
) AS customfields_oo
ON customfields_oo.product_id = products.id
LEFT JOIN products_cstm
ON products.id = products_cstm.id_c
WHERE products.deleted = 0
ORDER BY ans DESC
When I run the query it gives me the following error:
Error Code : 1054
Unknown column 'products.id' in 'where clause'
It is not allowing first "products" table in left outer join query.
The issue is that customfields_oo is a derived table not a correlated subquery. Thus, you cannot reference the outer table from within the definition of the derived table. In this case, you cannot refer to the outer products table from within the customfields_oo definition. Instead, you must do that filter in the On clause outside the dervied table definition.
Select products.id,
products_cstm.oem_c,
products.mfr_part_num,
products.description,
products.cost,
products.assigned_user_id,
customfields_oo.ans
FROM products
Left Join (
Select pq1.product_id
, Count( q1.id ) As ans
From products_quotes As pq1
Left Join quotes As q1
On pq1.quote_id = q1.id
Where q1.deleted = 0
And pq1.deleted = 0
And q1.stage <> 4
And pq1.qty_shipped < pq1.product_qty
Group By pq1.product_id
) As customfields_oo
On customfields_oo.product_id = products.id
Left Join products_cstm
On products.id = products_cstm.id_c
Where products.deleted = 0
Order By customfields_oo.ans Desc
Now, you have stated in comments that this is too slow because, say products where deleted <> 0 might be evaluated in the derived table. If that is the case, then simply expand the derived table to include the filters on the outer products table.
Select products.id,
products_cstm.oem_c,
products.mfr_part_num,
products.description,
products.cost,
products.assigned_user_id,
customfields_oo.ans
FROM products
Left Join (
Select pq1.product_id
, Count( q1.id ) As ans
From products_quotes As pq1
Join products As p1
On p1.products.id = pq1.product_id
Left Join quotes As q1
On pq1.quote_id = q1.id
Where q1.deleted = 0
And pq1.deleted = 0
And q1.stage <> 4
And pq1.qty_shipped < pq1.product_qty
And p1.deleted = 0
Group By pq1.product_id
) As customfields_oo
On customfields_oo.product_id = products.id
Left Join products_cstm
On products.id = products_cstm.id_c
Where products.deleted = 0
Order By customfields_oo.ans Desc
You do not need to have AND pq.product_id = products.id in the where statement. Because you are LEFT JOINing on that. So I think something like this will work:
AND (pq.qty_shipped < pq.product_qty)
GROUP BY pq.product_id) AS customfields_oo
ON customfields_oo.product_id = products.id
LEFT JOIN products_cstm
ON products.id = products_cstm.id_c
WHERE products.deleted = 0
ORDER BY openorder DESC
EDIT
You do not need to LEFT JOIN on the table you are COUNTing on. You can also do ot like this:
SELECT
.....
(
SELECT
COUNT( q.id )
FROM products_quotes pq
LEFT JOIN quotes q
ON pq.quote_id = q.id
WHERE q.deleted = 0
AND pq.deleted = 0
AND q.stage <> 4
AND (pq.qty_shipped < pq.product_qty)
AND pq.product_id = products.id
) AS ans
FROM products
.....