MySQL slow on subquery - mysql

This following query take 1-2 seconds for querying.
SELECT updated, COUNT( * ) count
FROM v2_subscription
WHERE ss_id IN (SELECT MAX(ss_id) ss_id FROM v2_subscription GROUP BY uid, card_id)
while the subquery do take only few milliseconds.
SELECT MAX(ss_id) ss_id FROM v2_subscription GROUP BY uid, card_id
I do have index on uid, card_id and both uid, card_id
It's my sql and i have no idea how to optimize this.
Please advise,

Try this, May be it would help, let me know, if it does.
SELECT a.updated, COUNT( * ) count
FROM v2_subscription a
inner join v2_subscription b
on a.ss_id = max(b.ss_id)
GROUP BY b.uid, b.card_id
Or perhaps this
SELECT a.updated, COUNT( * ) count
FROM v2_subscription a
inner join v2_subscription b
on a.ss_id = (SELECT MAX(b.ss_id) b.ss_id FROM v2_subscription b GROUP BY b.uid, b.card_id)

Finally i have found the solution beside #arkumar above answer.
Adding "ORDER BY ss_id" inside the subquery also do the trick
Since without order by, the result of subquery do not have index.

Related

Count of total rows which have duplicates

I'm trying to get a total count of all the rows in a table which have duplicates.
Here is the query I am using right now:
SELECT count( `id_lead` )
FROM `lead_history`
GROUP BY `id_lead`
HAVING count( * ) > 1
The problem is that this isn't counting the total number of rows, it is counting the total amount of times each row contains a duplicate and returning that.
So right now, it is returning like this:
2
4
6
2
Given those results, I actually want my query to return 4, since there are 4 rows which have duplicates. The amount of duplicates each row has does not matter to me.
How would I write this query without using subqueries?
If you were using something like Oracle or SQL Server, you could take advantage of analytic functions. But MySQL does not have these, so using a subquery might the best way to get your answer.
SELECT COUNT(*)
FROM `lead_history`
WHERE `id_lead` IN (SELECT `id_lead` FROM `lead_history` GROUP BY `id_lead` HAVING COUNT(*) > 1)
Note that the subquery is not correlated, so the query optimizer should be able to make this run reasonably efficiently.
Try this way
SELECT COUNT(*)
FROM `lead_history` as b
join (SELECT `id_lead` FROM `lead_history` GROUP BY `id_lead` HAVING COUNT(*) > 1) a on b.id_lead=a.id_lead
Try This
SELECT count( * )
FROM `lead_history`
GROUP BY `id_lead`
HAVING count( * ) > 1
You're almost there, just put your query in a derived table and select the count from that. No additional in or join needed:
select count(*) from (
select `id_lead`
from `lead_history`
group by `id_lead`
having count(*) > 1
) t

SQL - Select multiply conditions

I would like to select multiply conditions using below query:
SELECT (SELECT count(*)
FROM users
)
as totalusers,
(SELECT sum(cashedout)
FROM users
) AS cashedout,
(SELECT COUNT(*)
FROM xeon_users_rented
) AS totalbots,
(SELECT sum(value)
FROM xeon_stats_clicks
WHERE typ='3' OR typ='1'
) AS totalclicks
The above query takes just under a second (0.912 to be exact) to execute. This slows things down a lot with thousands of requests.
What seems logical for me is this approach:
SELECT (SELECT count(*), sum(cashedout)
FROM users
)
as totalusers, cashedout,
(SELECT COUNT(*)
FROM xeon_users_rented
) AS totalbots,
(SELECT sum(value)
FROM xeon_stats_clicks
WHERE typ='3' OR typ='1'
) AS totalclicks
However that doesn't work, as I get the following error:
#1241 - Operand should contain 1 column(s)
Furthermore, how can I join the two other tables "xeon_users_rented" and "xeon_stats_clicks" in my first query?
It's slow because you have multiple subqueries. Try using joins instead.
Also, a list of your tables, columns would help us better assist you.
Your 2nd query is using wrong syntax, it should be
SELECT
count(*) as totalusers,
sum(cashedout) cashedout,
(SELECT COUNT(*) FROM xeon_users_rented) AS totalbots,
(SELECT sum(value) FROM xeon_stats_clicks
WHERE typ='3' OR typ='1') AS totalclicks
FROM users

Mysql WHERE IN subquery

I'd like to list all rows having a match on same table.
So far i have came up with this
SELECT *
FROM parim_firms
WHERE firm_name IN (
SELECT firm_name
FROM parim_firms
GROUP BY firm_name
HAVING COUNT(*) > 1
)
But this query keeps running, although the subquery itself runs in 0.1 sec.
How could i optimize this?
I think the subquery executes for each row, not only once. Am i right?
how about joining it?
SELECT a.*
FROM parim_firms a
INNER JOIN
(
SELECT firm_name
FROM parim_firms
GROUP BY firm_name
HAVING COUNT(*) > 1
) b ON a.firm_name = b.firm_name
PS: be sure to add index on column firm_name for faster execution.

Summing union of counts in a correlated subquery

I have a member table that has a foreign key to various other tables. I am checking each of these tables to see if a member has one or more records in it and if they do I return a value, if not I return 0, this is all selected as a total. This is mostly working except in one place. I need to check two tables and if there is a record in either of them the query will return 5,0 otherwise. I am trying to use a SUM of counts with a UNION for this but I am not getting the results I expect, it seems like only the first record in each of the two tables is being selected and that is it.
I am using(after some help ) a series of correlated queries with COUNT() and IF() to get the total. Here is what part of the query looks like :
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT member_id, COUNT(tbl2.id) as tbl_count
FROM tbl2
UNION ALL
SELECT member_id, COUNT(tbl3.id) as tbl_count
FROM tbl3
) sub WHERE sub.member_id = m.member_id
)
as total
FROM members m
The actual query joins another 10 or so tables, again the only part that is not working is the SUM of COUNT with the UNION. Could anyone suggest how I should do this? Any help would be very much appreciated. Thank you very much.
I think you are looking for this:
First try (FAIL)
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT COUNT(*) as tbl_count
FROM tbl2
WHERE tbl2.member_id = m.member_id
UNION ALL
SELECT COUNT(*) as tbl_count
FROM tbl3
WHERE tbl3.member_id = m.member_id
) sub
)
as total
FROM members m
Second try:
SELECT
member_id,
(SELECT IF(COUNT(member_id)>0,10,0) FROM tbl1 WHERE member_id = m.member_id)
+
(SELECT IF(SUM(tbl_count) > 0,5,0) FROM
(
SELECT member_id, COUNT(*) as tbl_count
FROM tbl2
GROUP BY member_id
UNION ALL
SELECT member_id, COUNT(*) as tbl_count
FROM tbl3
GROUP BY member_id
) sub
WHERE sub.member_id = m.member_id
)
as total
FROM members m
If the query has 10 joins maybe you have to think about refactoring... :-)

Help with a MySql Query - The Rows Holding the Group-wise Maximum of a Certain Column

I need help returning a relevant result for this query. I have one table that I am hitting with three columns. trans_date, trans_amount and user_id
what I am trying to determine is this. For a given user_id when was the last trans_date and what was the trans_amount.
I'm having trouble returning the correct transaction_amount. Here is my code so far. It's returning the correct date but the amount is not right
select user_id, trans_date, trans_credit
from table
WHERE trans_credit =
(select max(trans_date) from inclick_account_act as f
where f.user_id = table.user_id);
Thanks in advance
If I understand you correctly you just want to get the most recent transaction for all users.
SELECT user_id, trans_date, trans_credit
FROM `table`
GROUP BY user_id
ORDER BY trans_date DESC;
How about something like
SELECT t.*
FROM table t INNER JOIN
(
SELECT user_id,
MAX(trans_date) max_trans_date
FROM table
GROUP BY user_id
) MaxDates ON t.user_id = MaxDates.max_trans_date