I have this query that I use in order to get records from several tables, using JOIN.
SELECT c.id AS contestant_id,
c.created_date,
c.name AS contestant_name,
counter.total AS score,
c.email
FROM submission AS s,
(SELECT ans.id AS ans_id, sub.contestant_id, count(sub.id) AS total
FROM submission AS sub
JOIN (SELECT id, is_true FROM answer) AS ans
WHERE sub.answer_id = ans.id
AND ans.is_true = 1
GROUP BY sub.contestant_id) AS counter
JOIN (SELECT id, name, email, type, created_date
FROM contestant
WHERE contest_type = 1
AND submission_status = 1) AS c
WHERE counter.contestant_id = c.id
GROUP BY c.id
ORDER BY c.created_date DESC
The problem is that each record in table contestant will have 30 record in the submission table. So, when I retrieve 1000 contestant or more, the server hangs.
Please try the following restructured query:
SELECT
c.id AS contestant_id,
c.created_date,
c.name AS contestant_name,
counter.total AS score,
c.email
FROM
(
SELECT
sub.contestant_id, count(sub.id) AS total
FROM
submission AS sub
JOIN answer AS ans
ON sub.answer_id = ans.id AND ans.is_true = 1
GROUP BY
sub.contestant_id
)
AS counter
JOIN contestant c
ON c.contest_type = 1 AND c.submission_status = 1 AND c.id = counter.contestant_id
WHERE
counter.contestant_id = c.id
GROUP BY
c.id
ORDER BY
c.created_date DESC
It is possible to change the query result row limit, or remove the limit entirely.
Go to "Edit -> Preferences... -> SQL Editor (tab)"
Locate the "Query Results" section and untick the "Limit Rows" checkbox
Click "OK"
Re-run your query
Exporting query results in MySQL Workbench beyond 1000 records
Related
I want to select the columns with the max number of canceled trip. I know how to count the number of trips using the SQL statement, however, when I try to use the max function it gives the invalid group function error.
my SQL statement is as below:enter image description here
select t.ServiceNumber, t.RouteNumber, remark,
max(count(if(Cancelled =1 ,1,null))) as"Total Cancelled Trip"
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber
group by t.ServiceNumber, t.RouteNumber,remark;
If you want just one row with the maximum, you can do:
select t.ServiceNumber, t.RouteNumber, remark,
count(*) as "Total Cancelled Trip"
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber
where Cancelled = 1
group by t.ServiceNumber, t.RouteNumber, remark
order by count(*) desc
limit 1;
Getting all such rows in the event of ties is tricky in MySQL. Perhaps the easiest way uses variables:
select tr.*
from (select t.ServiceNumber, t.RouteNumber, remark,
count(*) as "Total Cancelled Trip",
(#maxtct = greatest(#maxtct, count(*))
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber cross join
(select #maxtct := 0) params
where Cancelled = 1
group by t.ServiceNumber, t.RouteNumber, remark
) tr
where `Total Cancelled Trip` = #maxtct;
I have the following schema:
http://sqlfiddle.com/#!9/bd3a4/1
I would like to
group by date() and add where user_id = ?..
per day and count the results per day.
required result Day|TotalRequests|TotalOrders
Since you could have an order on Day 1, and a request on Day 8, you may have entries on one side but not the other. To qualifify your needs, I would do a UNION of all orders and requests individually by date. Then roll those values up. The inner Pre-Aggregate result query is where the WHERE clause per user would be applied. The pre-aggregate query also has a recSource column to indicate where the record originated from as 'O' from orders and 'R' from requests, so the roll-up knows which column to store the total count respectively.
select
preAgg.recDate,
SUM( case when preAgg.recSource = 'O' then preAgg.recCount else 0 end ) as OrderCount,
SUM( case when preAgg.recSource = 'R' then preAgg.recCount else 0 end ) as RequestCount
from
( select
date(o.created_at) recDate,
'O' as recSource,
count(*) as recCount
from
orders o
where
o.user_id = 3
group by
date(o.created_at)
UNION ALL
select
date(r.created_at) recDate,
'R' as recSource,
count(*) as recCount
from
requests r
where
r.user_id = 3
group by
date(r.created_at) ) preAgg
group by
preAgg.recDate
order by
preAgg.recDate
For query optimization, I would ensure your order and request table both have have an index on ( user_id, created_at ).
SQL Fiddle result
You can use the following query:
SELECT
DATE(o.created_at) AS Day
,COUNT(r.id) AS TotalRequests
,COUNT(o.id) AS TotalOrders
FROM orders o
LEFT JOIN
requests r ON
r.id = o.request_id
WHERE o.user_id = 3
GROUP BY DATE(r.created_at), DATE(o.created_at),o.user_id
I have 3 left joined tables in MySql.
contratos, which stores customer data
funcionario, which stores employee data
cobranca, which stores every customer charge.
I want to generate a report based on charge status. But each customer charge has many status, and i want to retrieve the current status.
The following code returns the last update from cobrancas table.
SELECT cob.status, cob.created, con.data_venda, cpn.contrato, con.razao_social, con.cnpj, con.valor, f.nick
FROM cobrancas cob
LEFT JOIN contratos con
ON c.id = cob.contrato
LEFT JOIN funcionarios f
ON f.id = cob.cobrador
WHERE 1=1
ORDER BY cob.created DESC
LIMIT 1
But it returns without a status filter. If i put a WHERE clause like cob.status = 'x', it returns the last record with this status, but it may not be the current. So how can i check if cob.status is the current status in WHERE clause to decide if i will put it in the list? Something like:
WHERE IF(cob.status == the last status inserted AND cob.status == 'x')
Can you understand what i want to do? Thank you.
One solution to use subquery
select * from
(
SELECT cob.status, cob.created, con.data_venda, cpn.contrato, con.razao_social, con.cnpj, con.valor, f.nick
FROM cobrancas cob
LEFT JOIN contratos con
ON c.id = cob.contrato
LEFT JOIN funcionarios f
ON f.id = cob.cobrador
WHERE 1=1
ORDER BY cob.created DESC
LIMIT 1
) where status = 'X'
I'm have trouble counting/grouping the results of an inner join
I have two tables
results_dump: Which has two columns: email and result (the result value can be either open or bounce)
all_data: Which has three columns: email, full_name and address
The first goal is to query the result_dump table and count and group the number of times the result is "open" for a specific email.
This query works great:
SELECT `email`, COUNT(*) AS count
FROM `result_dump`
WHERE `date` = "open"
GROUP BY `email`
HAVING COUNT(*) > 3
ORDER BY count DESC
The second goal it to take those results (anyone who "open" more then 3 time) and pull in the 'full_name' and 'address' so I will have details on who opened an email 3+ times.
I have this query and it works as far as getting the data together - But I can't figure out how to get the COUNT, HAVING and ORDER to work with the INNER JOIN?
SELECT *
FROM all_data
INNER JOIN result_dump ON
all_data.email = result_dump.email
where `result` = "open"
SELECT email,name,count(*)
FROM all_data
INNER JOIN result_dump ON
all_data.email = result_dump.email
where `result` = "open"
group by result_dump.email
having count(*)>3
ORDER by count DESC
Nothing wrong with this one I think.
Try with following query:
SELECT * FROM all_data AS a
INNER JOIN
(SELECT * FROM result_dump where email IN
(SELECT `email`
FROM `result_dump`
WHERE `date` = "open"
GROUP BY `email`
HAVING count(email) >3
ORDER BY count(email) DESC)) AS b
ON a.email = b.email
WHERE b.`result` = "open"
This is Works Fine...! Try to this..
SELECT title.title
,count(*)
,title.production_year
,title.id as movie_id
,title.flag as language
,movie_info.info
FROM title INNER JOIN movie_info ON title.id=movie_info.movie_id;
I have the following query, but after some time when users start putting in more and more items in the "ci_falsepositives" table, it gets really slow.
The ci_falsepositives table contains a reference field from ci_address_book and another reference field from ci_matched_sanctions.
How can I create a new query but still being able to sort on each field.
For example I can still sort on "hits" or "matches"
SELECT *, matches - falsepositives AS hits
FROM (SELECT c.*, IFNULL(p.total, 0) AS matches,
(SELECT COUNT(*)
FROM ci_falsepositives n
WHERE n.addressbook_id = c.reference
AND n.sanction_key IN
(SELECT sanction_key FROM ci_matched_sanctions)
) AS falsepositives
FROM ci_address_book c
LEFT JOIN
(SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id) AS p
ON c.id = p.addressbook_id
) S
ORDER BY folder asc, wholename ASC
LIMIT 0,15
The problem has to be the SELECT COUNT(*) FROM ci_falsepositives sub-query. That sub-query can be written using an inner join between ci_falsepositives and ci_matched_sanctions, but the optimizer might do that for you anyway. What I think you need to do, though, is make that sub-query into a separate query in the FROM clause of the 'next query out' (that is, SELECT c.*, ...). Probably, that query is being evaluated multiple times - and that's what's hurting you when people add records to ci_falsepositives. You should study the query plan carefully.
Maybe this query will be better:
SELECT *, matches - falsepositives AS hits
FROM (SELECT c.*, IFNULL(p.total, 0) AS matches, f.falsepositives
FROM ci_address_book AS c
JOIN (SELECT n.addressbook_id, COUNT(*) AS falsepositives
FROM ci_falsepositives AS n
JOIN ci_matched_sanctions AS m
ON n.sanction_key = m.sanction_key
GROUP BY n.addressbook_id
) AS f
ON c.reference = f.addressbook_id
LEFT JOIN
(SELECT addressbook_id, COUNT(match_id) AS total
FROM ci_matched_sanctions
GROUP BY addressbook_id) AS p
ON c.id = p.addressbook_id
) AS s
ORDER BY folder asc, wholename ASC
LIMIT 0, 15