How to get individual count using this MySql Query - mysql

I have table and this table contain result column with some entries. I just wanted to know how to get individual count these entries using MySql Query like this (see result required)...
also
(see the result column image and query) or helps are definitely appreciated
Result Column Image
Query
SELECT cpd.result FROM cron_players_data cpd
WHERE cpd.`status` = '1'
AND (cpd.`result` = '1' OR cpd.`result` = '2')
AND cpd.`player_id` = '81'
Result Required
result count
1 2
2 6

SELECT cpd.result, count(*) FROM cron_players_data cpd
WHERE cpd.`status` = '1'
AND (cpd.`result` = '1' OR cpd.`result` = '2')
AND cpd.`player_id` = '81' group by cpd.`result`

SELECT result, COUNT(result) `count` FROM
(
SELECT cpd.result result
FROM cron_players_data cpd
WHERE cpd.`status` = '1'
AND (cpd.`result` = '1' OR cpd.`result` = '2')
AND cpd.`player_id` = '81'
) a
GROUP BY result

Related

MYSQL SELECT is slow when crossing multiple tables

I have a mysql query which is to return the only 1 record that need to cross multiple table. However, the mysql query is slow when executing.
Query:
SELECT *,
(SELECT TreeName FROM sys_tree WHERE TreeId = Mktg_Unit_Booking.ProjectLevelId) AS PhaseName,
(CASE WHEN ProductType = 'U' THEN (SELECT UnitNo FROM prop_unit pu WHERE pu.UnitId = mktg_unit_booking.UnitId)
ELSE (SELECT BayNo FROM prop_car_park pcp WHERE pcp.CarParkId = UnitId) END) AS UnitNo,
(SELECT CustomerName FROM mktg_customer mc WHERE mc.CustomerId = mktg_unit_booking.CustomerId) AS CustomerName
FROM Mktg_Unit_Booking
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo
I have run EXPLAIN in the query and I got this:
Any other suggestion on how to improve the speed of the query?
Thank you!
you are doing the cross product, instead of that you should use join.
Don't use sub-queries in select statement instead use proper join on Mktg_Unit_Booking in after from statement.
you query should something look like :
select
sys_tree.TreeName AS PhaseName,
case
WHEN Mktg_Unit_Booking.ProductType = 'U' then prop_unit.UnitNo
else prop_car_park.BayNo
end as UnitNo,
mktg_customer.CustomerName AS CustomerName
FROM Mktg_Unit_Booking
left join sys_tree on sys_tree.TreeId = Mktg_Unit_Booking.ProjectLevelId
left join prop_unit on prop_unit.UnitId = Mktg_Unit_Booking.UnitId
left join prop_car_park on prop_car_park.CarParkId = Mktg_Unit_Booking.UnitId
left join mktg_customer on mktg_customer.CustomerId = Mktg_Unit_Booking.CustomerId
WHERE IsDeleted <> '1' AND IsApproved = '1'
AND UnitId = 1110 AND ProductType = 'U'
ORDER BY UnitNo;
I have assumed that each table consists of only 1 matching tuple. If there are more then your logic needs to be modified.

Adding a WHERE condition on an IF alias in a MySQL query

I'm having trouble adding a condition on aliases is_paid, is_overdue and is_outstanding in the following query:
SELECT r.doc_number,
r.doc_date,
r.due_date,
r.currency,
r.amount,
r.vat,
r.vatammount,
(r.amount + r.vatammount) final_amount,
r.currency,
b.boq_id,
b.boq_comp_id,
b.boq_client_id,
b.boq_agency,
b.boq_date,
b.boq_orders,
b.receivable_id,
c.comp_name,
crm.`cn-name-first`,
crm.`cn-name-last`,
bi.inv_path,
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id) total_amount_received,
IF (r.amount + r.vatammount =
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_paid,
IF (CURRENT_DATE >= r.due_date
AND r.amount + r.vatammount !=
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_overdue,
IF (r.due_date < CURRENT_DATE
AND r.amount + r.vatammount !=
(SELECT SUM(amount_recieved)
FROM receivables_payments
WHERE r_id = b.receivable_id),
'1',
'0') AS is_outstanding
FROM receivables r
LEFT JOIN boq b ON b.receivable_id = r.id
LEFT JOIN boq_invoices bi ON bi.inv_boq_id = b.boq_id
LEFT JOIN comp_companies c ON c.comp_id = b.boq_comp_id
LEFT JOIN crm_contacts crm ON crm.contact_id = b.boq_client_id
WHERE r.status = 'active'
AND r.doc_type = 'inv'
AND b.boq_status = 'active'
AND is_paid = '1'
ORDER BY r.doc_date DESC LIMIT 10
Is there any way to modify this query and to make it possible to add a condition on those three aliases?
use alias in where condition .. is not allowed . because .is not possibile
the query code is evaluted based on a specified order .. starting from FROM then
WHERE clause and last the SELECT and the column alias so .. when the where is performed the column alias is not available at the query
You could try with an having condition because having work on the result of the query and not on the raw rows value .. (this could have effect on performance ..because all the query is performed and only the result is filtered by having)

Multiple joins with ordered by count ignores where conditions

I am trying to only get rows from video_index that belongs to a specific category from category_video_rel and order the result by COUNT of view count. This is the query I'm using:
SELECT
COUNT(DISTINCT view_count.id) AS count,
view_count.remove,
view_count.video_id,
video_index.id AS video_id,
video_index.active,
video_index.remove,
video_index.title AS title,
video_index.date_published AS date_published,
category_video_rel.active,
category_video_rel.remove,
category_video_rel.video_id AS cv_video_id,
category_video_rel.category_id AS category_id
FROM
view_count JOIN video_index
ON view_count.video_id = video_index.id,
category_video_rel JOIN video_index AS v
ON category_video_rel.video_id = v.id
WHERE
view_count.remove = '0' AND
video_index.active = '1' AND
video_index.remove = '0' AND
video_index.date_published <= '$current_time' AND
category_video_rel.category_id = '$category_id' AND
category_video_rel.active = '1' AND
category_video_rel.remove = '0'
GROUP BY
video_index.id
ORDER BY
count DESC
The problem is it outputs all the rows from video_index with a view count higher than 0 regardless of the category. Basically, it's ignoring "category_video_rel.category_id = '$category_id'" in the WHERE condition.
I have no idea what I'm doing wrong, please help.
Your FROM clause is mixing old style joins and new style joins
Instead try:
FROM
view_count JOIN video_index
ON view_count.video_id = video_index.id
JOIN category_video_rel
ON category_video_rel.video_id = video_index.id

Select Count Row then update value

Just need some idea
Is there a way I can Select the count then update its value?
Here is my code to be edit.
I'm getting the number of new message in my table message
select count(id) as new from message where owner_id = '1' and status = '1' and isRecieve = '0'
When I get the number of message I want it to set all the message got from select query to isRecieve = 1
is there a way once I query I updte all isRecieve to 1?
like
select count(id) as new from message where owner_id = '1' and status = '1' and isRecieve = '0' then update isRecieve = 1
Thanks.
You should not select COUNT for your case. In fact, what your are trying to achieve is:
UPDATE corresponding records
Discover, how many rows was touched
This can be resolved with:
UPDATE
message
SET
isReceive = '1'
WHERE
owner_id = '1'
AND
status = '1'
AND
isRecieve = '0'
and then either do
SELECT ROW_COUNT()
to retrieve affected rows in SQL, or do something like mysqli_affected_rows() in application (function is in PHP, but the same thing is available in any mysql connection driver in any language).
UPDATE message set
isRecieve = 1 where
owner_id = '1' and
status = '1' and
isRecieve = '0' and
exists (
select 1 from message where
owner_id = '1' and
status = '1' and
isRecieve = '0'
group by id having count(*) = 1
)

Mysql multiply count

I have a query, which will loop through an orders table, and as a sub query, will also count the number of rows in another table using a foreign key.
SELECT eo.*, (
SELECT COUNT(*)
FROM ecom_order_items eoi
WHERE eo.eo_id = eoi.eoi_parentid
AND eoi.site_id = '1'
) AS num_prods
FROM ecom_orders eo
WHERE eo.site_id = '1' AND eo_username = 'testuser'
Now, on the ecom_order_items table, it has a eoi_quantity field. I want the query to display the number of products for each order, taking into account the quantity field.
SELECT eo.*, (
SELECT COUNT(*) * eoi.eoi_quantity
FROM ecom_order_items eoi
WHERE eo.eo_id = eoi.eoi_parentid
AND eoi.site_id = '1'
) AS num_prods
FROM ecom_orders eo
WHERE eo.site_id = '1' AND eo_username = 'testuser'
However when I try this, it just gives me the same number as before. For the order I am testing on, it has 2 items, one with quantity 1, the other with quantity as 10, and num_prod is returning as 2 on both queries.
Any ideas? :)
If the value of eoi.eoi_quantity consists of multiple values, 1 and 10, only one of them will be selected and multiplied by COUNT(*). So you are getting the result 1 * 2.
As COUNT(*) = 2 for two items, do you want the result 2 * 1 + 2 * 10? It doesn't seem right to me. I'm thinking you want to count the total quantity over all the relevant orders, so why not use SUM(eoi.eoi_quantity) to get 1 + 10 instead? Thus you would have:
SELECT eo.*, (
SELECT SUM(eoi.eoi_quantity)
FROM ecom_order_items eoi
WHERE eo.eo_id = eoi.eoi_parentid AND eoi.site_id = '1'
) AS num_prods
FROM ecom_orders eo
WHERE eo.site_id = '1' AND eo_username = 'testuser';
But this is still going to get you the same value for each column. In fact, a subquery like (SELECT eo.*,...) will result in an error if it returns more than one row.
That's why Johan suggested that you would want to join the tables. You need to join the tables to be sure that the rows are properly linked and then group them by the id's you want for each row. How about:
SELECT eo.*, SUM(eoi.eoi_quantity)
FROM ecom_orders eo JOIN ecom_order_items eoi ON eo.eo_id = eoi.eoi_parentid
WHERE eo.site_id = '1'
AND eo_username = 'testuser'
GROUP BY eo.eo_id;
Rewrite the query into:
SELECT eo.*, sum(eoi.eoi_quantity) as sales
FROM ecom_orders eo
INNER JOIN ecom_order_items eoi ON (eo.eo_id = eoi.eoi_parentid)
WHERE eo.site_id = '1' AND eoi.site_id = '1' AND eo_username = 'testuser'
GROUP BY eo.eo_id;
Because the count(*) for each individual item is 1, count(*) * quantity is the same as sum(quantity).