SQL query long execute (count in nested select) - mysql

I have such a query:
SELECT DISTINCT type, (SELECT count(*) FROM ads WHERE ad_type = description_table.type)
as count FROM description_table;
It takes for about 5 minutes to execute. What can be the problem here?
EDIT: Changed the table name from 'desc' to 'description_table' to avoid complication.

You need to join your table description_table with ads table. Try this:
SELECT DISTINCT type, (SELECT count(ads.type) FROM ads join description_table on ads.type = description_table.type)
as count FROM `description_table`;
and instead of counting *, try to count some column like id or type
EDIT:
As per your comment you can try this query:
SELECT a.type, count(d.type) as count
FROM description_table d left join ads a on d.type = a.type
group by d.type;

Related

Getting the top sales

How to i get the top vendor for each country? I have this code and it shows the connection between the two tables, now I have to get the largest gmv per country.
Here is my working code:
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name;
The top 3 should show this:
Assuming you can save that SELECT into a table called vendors, you need to use it as the subquery in the FROM clause.
You could use this:
SELECT vendors.country_name, vendors.vendor_name, MAX(vendors.total_gmw)
FROM
(
SELECT DISTINCT a.country_name, b.vendor_name,
SUM(a.gmv_local) as total_gmw
from `my-project-67287.order1.order2`a
join `my-project-67287.vendor1.vendor2` b on a.vendor_id = b.id
group by a.country_name, b.vendor_name
) AS vendors
GROUP BY vendors.country_name;
I must mention I have not tested your query, since I do not have your tables, so I assumed it's correct.
I only created the vendors table with the required fields and values from your picture. This should print:
SELECT odr.c_name,vdr.v_name,odr.gmv
FROM(
SELECT *
FROM(
SELECT c_name,v_id,gmv
FROM `order`
ORDER BY gmv DESC
)
GROUP BY c_name
)AS odr
LEFT JOIN vender AS vdr ON vdr.id = odr.v_id
GROUP BY odr.c_name
c_name short for country_name

Select all rows present in Table A OR Table B

I would like to get the resulting row if the foreign id present in Table A or in Table B.
I have 3 tables: events, pdf_results and live_Results. I would like to select all events with pdf_results OR live_Results.
I have tried following query but it's not working when results are available in both tables.
SELECT
events.*,
live_results.id,
pdf_results.id
FROM events
LEFT JOIN pdf_results
ON pdf_results.eventId = events.id
LEFT JOIN live_Results
ON live_Results.eventId = events.id;
Here is SQL Fiddle Demo
How about just using exists?
SELECT e.*
FROM events e
WHERE EXISTS (SELECT 1 FROM pdf_results pr WHERE pr.eventId = e.id) OR
EXISTS (SELECT 1 FROM live_Results lr WHERE lr.eventId = e.id);
You can join with a UNION query:
SELECT e.*, r.result_type
FROM events AS e
JOIN (SELECT eventId, 'pdf' AS result_type FROM pdf_results
UNION ALL
SELECT eventId, 'live' AS result_type FROM live_results) AS r
ON e.id = r.eventId
Adding the result_type column allows us to know which results table it matched, and we'll get two rows if it matches both.
You could also use your original query, and add:
WHERE pdf_results.eventId IS NOT NULL OR live_results.eventId IS NOT NULL
You won't get two rows when it matches twice, but you'll be able to tell from the two eventId columns which results table it was found in.

MySQL SUM() with JOIN and LIMIT

The concerned schema and query is on SQL fiddle here http://sqlfiddle.com/#!2/312d3/16
The JOIN query below gets the result that I want.
SELECT p.*, payer.username as payer_username, payee.username as
payee_username FROM (`payments_history` p) JOIN (SELECT * FROM users)
AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT * FROM
users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp`;
Doing a sum() on the "p.amount" column for all the rows works fine too.
SELECT SUM(p.amount) FROM (`payments_history` p) JOIN (SELECT * FROM
users) AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT *
FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp`;
But doing a sum() on the same column for the rows on each page (offset,limit) returns an empty result (I would like to have the total of the "amount" column for the rows on each page).
SELECT SUM(p.amount) FROM (`payments_history` p) JOIN (SELECT * FROM
users) AS payer ON `payer`.`user_id` = `p`.`payer_id` JOIN (SELECT *
FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id` ORDER BY
`p`.`created_timestamp` limit 0,2;
Also in the sum() query, when the offset starts from anything greater than 0 (try LIMIT 2,2), it returns an empty result.
What am I doing wrong?.
Thank you.
Give this a try:
SELECT SUM(l.amount) FROM (
SELECT p.amount FROM payments_history p
INNER JOIN users payer ON payer.user_id=p.payer_id
INNER JOIN users payee ON payee.user_id=p.payee_id
ORDER BY p.created_timestamp
LIMIT 0,10
) l
I'm not sure if you plan to add other fields to the query, or have further conditions in a WHERE clause, but having those joins in there doesn't seem all that useful right now.
Your question is just a little vague. What will be on the page that you want to have sums on? Is it a report for the specific user? If so, then you can just add a WHERE clause to your query to limit the sum to just that user. Something like:
SELECT SUM(p.amount)
FROM (`payments_history` p)
JOIN (SELECT * FROM users) AS payer ON `payer`.`user_id` = `p`.`payer_id`
JOIN (SELECT * FROM users) AS payee ON `payee`.`user_id` = `p`.`payee_id`
WHERE payer.user_id = [the user id]
ORDER BY `p`.`created_timestamp`;
If that's not what you want, then you may want to clarify the question a little bit. It's unclear.
Question:
Are you trying to get the sum of just one row? (your answer in the comments makes it seem that way) If so, that's just the value in the amount. You can't sum a single value.

mysql select count union

I have something like this:
(SELECT COUNT(*) AS total FROM `transactions` WHERE
`asset`='u_{$user_id}' GROUP BY id)
UNION DISTINCT
(SELECT COUNT(*) AS total FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}'
GROUP BY tr.id)
It gives 1
Now works like this:
SELECT
(SELECT COUNT(*) FROM `transactions`
WHERE `asset`='u_{$user_id}')
+
(SELECT COUNT(*) FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}')
It gives 6
But i need to get 5.., sow how to make a right query?
Sure, i can do this by php, but..HOW by sql..?
Really "and" and "or" conditions does not matter, they works correctly, the problem is in counting UNION`ed query. The second query correctly counts summ (1+5), but values ​​intersect queries. The first one gives result of just first subquery. So, i need to unique results before count...
In php, it should look like that: i get transactions id list by inner join with payments, than construct a long query in a loop, to get something like SELECT COUNT(*) FROM transactions WHERE (*what i have now* OR id=$id_1 OR id=$id_2 OR id=$id_3 etc..)
UPD: cutted
RESOLVED!=)
SELECT COUNT(*) FROM(
SELECT tr.* FROM transactions tr
WHERE tr.asset='u_{$user_id}' OR (tr.liability='g' AND tr.l_info='{$user_name}')
UNION SELECT tr.* FROM transactions tr
INNER JOIN payments pa ON tr.asset = CONCAT('p_', pa.id)
WHERE pa.user_id = '{$user_id}' AND pa.status='100')
AS total
AS total is importantly!
I gone through your question, and i think you want to fetch the maximum from the union clause, well i am not aware of the mySql, so i have solved your question in MS-SQL.
Logic:- I have used CTE, and afterwards performed UNION operation and then i have selected MAXIMUM from the two.
WITH COUNTT AS (SELECT 1 AS TEST
UNION
SELECT 5 AS TEST)
SELECT MAX(TEST) FROM COUNTT
And, in place of hardcoded "1" and "5", you can use your count query, i think it is what you are looking for. And, please mark it as an answer.

Subquery returns more than 1 row

im geting this error when trying to do 2 counts inside of my query
first ill show you the query:
$sql = mysql_query("select c.id, c.number, d.name,
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount,
(select count(*) from `parts` where `id_container`=c.id) as partcount
from `containers` as c
left join `destinations` as d on (d.id = c.id_destination)
order by c.number asc") or die(mysql_error());
now the parts table has 2 fields that i need to use in the count:
id_car
id_container
id_car = the ID of the car the part is for
id_container = the ID of the container the part is in
for packcount all i want is a count of the total cars per container
for partcount all i want it a count of the total parts per container
It's because of GROUP BY You're using
Try something like
(select count(distinct id_car) from `parts` where `id_container`=c.id)
in You're subquery (can't check right now)
EDIT
PFY - I think UNIQUE is for indexes
Your grouping in your first sub-query is causing multiple rows to be returned, you will probably need to run separate queries to get the results you are looking for.
This subquery may return more than one row.
(select count(*) from `parts` where `id_container`=c.id group by `id_car`) as packcount, ...
so, i'd suggest to try something of the following:
(select count(DISTINCT `id_car`) from `parts` where `id_container`=c.id) as packcount, ...
see: COUNT(DISTINCT) on dev.mysql.com
and: QA on stackoverflow