I'm trying to get the unique call counts (no dupe calls) by state. For example...
MO 249
OK 220
CA 216
TX 190
KS 158
The following works (no errors), but it's not removing the dupes.
SELECT DISTINCT CallFrom, FromState, count(*) AS cnt
FROM `calls`
WHERE DateCreated >= CURDATE() - INTERVAL 2 YEAR AND
(CallTo = '+15555555555' OR CallTo = '+15555555556' )
GROUP BY FromState
ORDER BY cnt DESC
Any ideas? Thanks in advance.
UPDATE: The following 'calls' table example was requested...
Index CallTo CallFrom FromState
1 +15555555555 18166283100 MO
2 +15555555556 13307059600 OH
3 +15555555555 17722631600 FL
4 +15555555556 16173024800 MA
5 +15555555556 16173024800 MA
6 +15555555556 16175025500 MA
Just realized I forgot to include the DateCreated column, but like I said, everything is working except for deduplicating. The output for this example would be...
MA 2
MO 1
OH 1
FL 1
Your wording is not very clear, but I think you're saying you want to count how many unique CallFrom numbers occurred in each state. There may be better ways to do this, but this will work. First it builds a list of unique CallFrom/State combinations, and then it groups and counts on that list, instead of on the raw data:
SELECT FromState, COUNT(*)
FROM
(SELECT DISTINCT CallFrom, FromState
FROM `calls`
WHERE
(CallTo = '+15555555555' OR CallTo = '+15555555556' )
) c
GROUP BY FromState
Demo:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=d057e3482ec9d5ad4519e58056232e58
Related
I have a table, it similar with this table
ID Name Age Status
1 John 32 Life
2 Andre 99 Life
3 Anton 89 Dead
4 Maria 99 Life
5 Mario 13 Life
6 Santi 89 Dead
7 Anggy 56 Dead
8 Amir 99 Life
I want to do something like this
1. Group rows by status (Life)
2. Get the max Age from that group (99) (only the max number need)
4. Make new group by age and sort it by ID.
The result will be
8 Amir 99 Life
4 Maria 99 Life
2 Andre 99 Life
Any way to use only 1 line query for that job? with some (php) data procesing its not to hard to get the result i want, but i want to make code as clean as posible, so maybe i can do that 3 step in just a single query?
I think the right logic is:
select t.id, t.name, t.age, t.status
from table t join
(select max(t2.age) from table t2 where t2.status = 'life') m
on t.age = m.age
where t.status = 'life'
order by id desc;
select id, name, age, status
from thetable
where age =
(select max(age)
from thetable
where status="Life"
)
where status="Life"
order by id desc
Use the below mentioned query :
SELECT
*
FROM
t4
CROSS JOIN
(SELECT
MAX(`age`) AS 'age'
FROM
t4
WHERE
`status` = 'Life') AS t5
WHERE
`status` = 'Life' AND t4.`age` = t5.age
ORDER BY `id` DESC;
Check SQLFiddle
Now I understand that this has been asked several times before, but I have tried to apply different existing solutions to my specific problems for quite a while without success. So I turn here in hope of some guidance.
I have a table called tblanswers, which contains answers linked to different questions in another table. What I want is to get the count for each answer for a specific question ID, but limit it to the n first answers each month.
Sample data from tblanswers:
id qid answer timestamp
72 162 2 1366027324
71 161 4 1343599200
70 162 2 1366014201
69 161 4 1366011700
68 162 2 1366006729
67 161 3 1366010948
66 162 2 1365951084
This is the query I have so far:
SELECT *, COUNT(*) c FROM(
SELECT answer, timestamp, YEAR(FROM_UNIXTIME(timestamp)) yr, MONTH(FROM_UNIXTIME(timestamp)) mo FROM tblanswers
WHERE qid = 161
ORDER BY timestamp ASC
) q GROUP BY YEAR(FROM_UNIXTIME(timestamp)), MONTH(FROM_UNIXTIME(timestamp)), answer
That would give me something like this: (the dates and numbers in sample data is not accurate)
answer yr mo c
1 2013 5 5
2 2013 5 3
3 2013 5 2
1 2013 6 5
2 2013 6 15
3 2013 6 7
Let's say I only want to see the first three answers in a month, then count could never be more than 3. How can I limit each month?
The final data should be a sum of each answer, like this:
answer num_answers
1 2
2 3
3 3
I think one of these solutions could work, but not how:
http://code.openark.org/blog/mysql/sql-selecting-top-n-records-per-group
http://code.openark.org/blog/mysql/sql-selecting-top-n-records-per-group-another-solution
Any help is appreciated. Thanks!
This solution is based on the top-N-per-group method here
SELECT answer, COUNT(*) num_answers
FROM (SELECT answer, yearmonth,
#rn := CASE WHEN #prevmonth = yearmonth
THEN #rn + 1
ELSE 1
END rn,
#prevmonth := yearmonth
FROM (SELECT #rn := NULL, #prevmonth := NULL) init,
(SELECT answer,
YEAR(FROM_UNIXTIME(timestamp))*100+MONTH(FROM_UNIXTIME(timestamp)) yearmonth
FROM tblanswers
WHERE qid = 220
ORDER BY timestamp) x) y
WHERE rn <= 3
GROUP BY answer
SQLFIDDLE
What about this solution:
SELECT qid, answer, YEAR(FROM_UNIXTIME(timestamp)) yr, MONTH(FROM_UNIXTIME(timestamp)) mo, COUNT(*) no
FROM tblanswers
WHERE qid = 161
GROUP BY answer, yr, mo
HAVING COUNT(*) <= 2
ORDER BY timestamp ASC;
and the fiddle: http://sqlfiddle.com/#!2/1541eb/126
There is no reason to reinvent a wheel and risk you have a buggy, suboptimal code. Your problem is trivial extension of common per group limit problem (see also tag limit-per-group). There are already tested and optimized solutions to solve this problem.
So I have seen this done with multiple tables, but am confused as to how this would work with multiple tables. I want to select the number of correct entries in a tournament. This works except if a user got none right. Then it returns NULL. I want this to return 0.
Table-tournament_entries
Column
=============
id
tournament_id
game_id
user_id
username
prediction
correct
Here is the query that I run, I am hoping to return all users even the ones who did not get any questions right.
SELECT
tournament_id, username, user_id, COUNT(`prediction`)
FROM
tournament_entries
WHERE
correct = 1 AND tournament_id = 1
GROUP BY
username
ORDER BY
COUNT(`prediction`) DESC
LIMIT 0,10
EDIT: Sorry for all the confusion so when I run my query I get this
username user_id CorrectAns
mj 455 10
charlie 1 8
bill 2 8
doug 51 7
but there are users who are not show who have received 0 right. When I run the queries suggested I receive the number of questions .
username user_id CorrectAns
mj 455 16
charlie 1 16
bill 2 16
doug 51 16
sydney 452 16
Joe 218 16
If you notice sydney and joe are not in the first output but are in the second one
Use this query:
$query ="SELECT tournament_id, username, user_id, COALESCE(COUNT(`prediction`),0) as cpred
FROM tournament_entries
WHERE tournament_id = 1
GROUP BY username
ORDER BY cpred DESC
LIMIT 0,10"
COALESCE will return the first non-null parameter given to it.
Cheers.
Based on your comments to the other answer, I think what you're actually looking for is something like this (although it's hard to be sure without sample data and output):
SELECT
username, user_id, Sum(correct) As TotalCorrect
FROM
tournament_entries
WHERE
tournament_id = 1
GROUP BY
username, user_id
ORDER BY
TotalCorrect DESC
LIMIT 0,10
I have tried this multiple distinct from MySQL and I cant seem to get anything to work... I have a table that is a history table. The appartments can be found many times from the same building with different status. I need to find the newest one for each appartment (the one with the highest id ORDER BY id)
id building appartment_id status
208 1 2 2
209 1 3 2
210 1 4 2
211 1 5 2
212 1 6 2
213 1 7 2
214 1 2 1
215 1 2 3
But how do I do that?! :S
I have tried this:
SELECT *, GROUP_CONCAT(appartment_id, building)
FROM `ib30_history`
group by appartment_id, building
order by id DESC
It seems to work but im not sure that is the right way of doing it and the code that uses the output seems to make funny things running through the data so im not sure it really works!
SELECT yourtable.id, yourtable.building, yourtable.appartment_id, yourtable.status
FROM yourtable
INNER JOIN (
SELECT MAX(id) AS id
FROM yourtable
GROUP BY building, appartment_id
) AS child ON yourtable.id = child.id
Get rid of distinct and use something like:
GROUP BY building , appartment_id
What you're looking for is called GROUP BY, and MySQL's documentation knows a lot about how it's to be used. At the timeI type this, the OP doesn't contain a query so I cannot give you an example...
SELECT a.*
FROM table_name a
INNER JOIN
(SELECT MAX(id) as max_id
FROM table_name
GROUP BY appartment_id) b
ON (b.max_id = a.id)
I am trying to select data from multiple tables which uses an AVG in the WHERE clause.
SELECT company_metrics.*, companies.company_name, companies.permalink
FROM company_metrics LEFT JOIN companies
ON companies.company_id = company_metrics.company_id
WHERE MONTH(date) = '04' AND YEAR(date) = '2011'
HAVING (SELECT avg(company_unique_visitors)
FROM (SELECT company_metrics.company_unique_visitors
FROM company_metrics
ORDER BY company_metrics.date DESC LIMIT 3)
average ) >'2000'
ORDER BY date DESC
Example Data:
###Company Metrics#### Table
company_id company_unique_visitors date
----------- ----------------------- ----
604 2054 2011-04-01
604 3444 2011-03-01
604 2122 2011-02-01
604 2144 2011-01-01
604 2001 2010-12-01
602 2011 2011-04-01
602 11 2011-03-01
602 411 2011-02-01
602 611 2011-01-01
602 111 2010-12-01
EDIT
I would like only the 3 latest numbers from company_unique_visitors AVG'ed
/EDIT
So the query would select company_id 604 but it wouldn't select company_id 602 because 602 doesn't have an AVG greater than 2000.
I need help writing the correct query to do as I have described. I can clarify if needed.
Thanks for your help!
There are several problems with your query as written. I'm not completely clear as to the structure of all the tables, but I believe I understand the gist based on the query you posted. Your first problem with the posted query is that you're not grouping by or using any aggregates in the query where you're using the HAVING clause. You use aggregates in one of the subqueries, but the HAVING where it is right now doesn't make much sense.
I believe you wanted to group by the company_id before you did an aggregate of the averages, so I made that the primary group by on the outer query. You were also using too many nested queries to accomplish what was was a seemingly simple task of only selecting the 3 most recent measurements. I moved that subquery into the primary join so that the data was only selected once and in a logical way.
And, without further ceremony, here's the fixed query:
SELECT limited_metrics.*, companies.company_name, companies.permalink,
avg(limited_metrics.company_unique_visitors) AS avg_visitors
FROM
(SELECT *
FROM company_metrics
ORDER BY company_metrics.date DESC LIMIT 3) AS limited_metrics
LEFT JOIN companies
ON companies.company_id = limited_metrics.company_id
WHERE MONTH(limited_metrics.date) = '04' AND YEAR(limited_metrics.date) = '2011'
GROUP BY companies.company_id
HAVING avg_visitors > 2000
Ok based off of Jared Harding's answer and this post: Moving average - MySQL
I was able to figure out the query.
SELECT metrics.*,companies.company_name,companies.permalink
FROM (SELECT company_id,AVG(company_unique_visitors) AS met_avg
FROM company_metrics
WHERE `date` BETWEEN DATE_SUB(NOW(), INTERVAL 4 MONTH) AND NOW()
GROUP BY company_id HAVING met_avg>2000) AS metrics
LEFT JOIN companies ON companies.company_id=metrics.company_id
Thanks Jared for all your help!