Strang Issue with MySQL Query - mysql

I am trying to find the count of rows returned by below query:
SELECT Count(id) AS fcount,
user_id
FROM customer_followups
WHERE id > 0
AND Date(followup_date) >= Str_to_date("24-09-2012", "%d-%m-%y")
AND Date(followup_date) <= Str_to_date("24-09-2012", "%d-%m-%y")
GROUP BY user_id
ORDER BY user_id
It returns me 5 Rows.
However if I fire the query WITHOUT the count function I only get one record. See below:
SELECT id,
user_id
FROM customer_followups
WHERE id > 0
AND Date(followup_date) >= Str_to_date("24-09-2012", "%d-%m-%y")
AND Date(followup_date) <= Str_to_date("24-09-2012", "%d-%m-%y")
GROUP BY user_id
ORDER BY user_id
What could be the reason? ideally the count should return 1 ??

COUNT gives you the number of the records for a group which satisfies the condition.
The COUNT function is an aggregate function that simply counts all the items that
are in a group.
Whereas in your second query you just find the id and user_id for that group. Remember if the group has different user-id it will return any of them to find all the user_id you can use GROUP_CONCAT() i.e. GROUP_CONCAT(user_id)

Related

MySQL: Remove rows from a GROUP BY result if it only grouped 1 row

When selecting data, I'm able to show how many rows were grouped from using GROUP BY by running:
SELECT id, created, COUNT(id) `count` FROM table
GROUP BY id
LIMIT 0,30
The count field easily outputs how many rows were affected by the GROUP BY. In MySQL is it possible to automatically not include any row which only has a count value of 1?
You should consider using a HAVING clause which lets you add conditions after the grouping has been done.
SELECT id, created, COUNT(id) cnt FROM table
GROUP BY id
HAVING cnt > 1
LIMIT 0,30
Another thing to mention is that the grouping might not be correct. If you group by id and you select id, created then the value for created is undetermined. MySQL will choose any of them for a given id if they differ. You might be interested in grouping by that field too or applying an aggregate function (eg: max(created)).
A second thing to mention is that COUNT(id) won't count the amount of rows but rather the amount of rows that have id not null. If id is never null then it would result in the same value as doing count(*).
Yes. You can use HAVING to limit the results of an aggregate function like COUNT (MAX,MIN,SUM, etc).
SELECT id, created, COUNT(id) `count`
FROM table
GROUP BY id
HAVING COUNT(id) > 1
LIMIT 0,30
Show the manual and find HAVING
... HAVING COUNT(id) > 1
http://dev.mysql.com/doc/refman/5.1/de/select.htmlhavinh

Sql Query to count same date entries

All I want to count entries based on date.(i.e entries with same date.)
My table is
You can see 5th and 6th entry have same date.
Now, the real problem as i think is the same date entry have different time so i am not getting what I want.
I am using this sql
SELECT COUNT( created_at ) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY created_at
LIMIT 0 , 30
What I am getting is this.
I want entries as 2 for date 2012-02-22
The reason you get what you get is because you also compare the time, down to a second apart. So any entries created the same second will be grouped together.
To achieve what you actually want, you need to apply a date function to the created_at column:
SELECT COUNT(1) AS entries, DATE(created_at) as date
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30
This would remove the time part from the column field, and so group together any entries created on the same day. You could take this further by removing the day part to group entries created on the same month of the same year etc.
To restrict the query to entries created in the current month, you add a WHERE-clause to the query to only select entries that satisfy that condition. Here's an example:
SELECT COUNT(1) AS entries, DATE(created_at) as date
FROM wp_frm_items
WHERE user_id = 1
AND created_at >= DATE_FORMAT(CURDATE(),'%Y-%m-01')
GROUP BY DATE(created_at)
Note: The COUNT(1)-part of the query simply means Count each row, and you could just as well have written COUNT(*), COUNT(id) or any other field. Historically, the most efficient approach was to count the primary key, since that is always available in whatever index the query engine could utilize. COUNT(*) used to have to leave the index and retrieve the corresponding row in the table, which was sometimes inefficient. In more modern query planners this is probably no longer the case. COUNT(1) is another variant of this that didn't force the query planner to retrieve the rows from the table.
Edit: The query to group by month can be created in a number of different ways. Here is an example:
SELECT COUNT(1) AS entries, DATE_FORMAT(created_at,'%Y-%c') as month
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE_FORMAT(created_at,'%Y-%c')
You must eliminate the time with GROUP BY
SELECT COUNT(*) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30
Oops, misread it.
Use GROUP BY DATE(created_at)
Try:
SELECT COUNT( created_at ) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30

Error in subquery

im stuck here and i don't know how to fix it.
I have a db table which has users ID, user grade and date when someone has voted for that user (3 fields).
Im trying to read the user that has the highest average grade for todays date, limited to one.
But the problem is that i want to read only users that have 5 or more votes.
My query looks like this, but im getting an error:
SELECT
idusers,
AVG(votes) AS Grade
FROM rank
WHERE (data = '{$dbDate}')
AND ((SELECT count(ID) + 1 FROM rank) AS tmpcount WHERE tmpcount>4)
GROUP BY idusers
ORDER BY Grade DESC
LIMIT 1
Without the tmpcount>4 clause this query is working ok, but I need to count the Id's.
You have to use HAVING to filter the result set on aggregated values such as COUNT (SUM, MIN, MAX, AVG, …):
SELECT idusers, AVG(votes) AS Grade
FROM rank
WHERE (data = '{$dbDate}')
GROUP BY idusers
HAVING COUNT(*) > 4
ORDER BY Grade DESC
LIMIT 1

Determine total amount of top result returned

I would like to determine two things from a single query:
Most prevalent column in a table
The amount of times such column was located upon querying the table
Example Table:
user_id some_field
1 data
2 data
1 data
The above would return user_id # 1 as being the most prevalent in the table, and it would return (2) for the total amount of times that it was located in the table.
I have done my research and I came across two types of queries.
GROUP BY user_id ORDER BY COUNT(*) DESC
SUM
The problem is that I can't figure out how to use these two queries in conjunction with one another. For example, consider the following query which successfully returns the most prevalent column.
$top_user = "SELECT user_id FROM table_name GROUP BY user_id ORDER BY COUNT(*) DESC";
The above query returns "1" based on the example table shown above. Now, I would like to be able to return "2" for the total amount of times the user_id (1) was found in the table.
Is this by any chance possible?
Thanks,
Evan
You can include count(*) in the SELECT list:
SELECT user_id, count(*) as totaltimes from table_name
GROUP BY user_id ORDER BY count(*) DESC;
If you want only the first one:
SELECT user_id, count(*) as totaltimes from table_name
GROUP BY user_id ORDER BY count(*) DESC LIMIT 1;

MySQL count() query returns rows instead of total?

What might be wrong with this query:
select count(customer_email) as num_prev
from _pj_cust_email_by_date
where order_date < '2011-02'
and customer_email is not null
group by customer_email having count(order_date) > 0;
Which returns row results such as:
1
2
3
2
1
5
4
When I'm trying to get a full count of how many customers in total purchased during the specified date range?
_pj_cust_email_by_date is a view that returns only email address and order date in YYYY-MM-DD format. I do not have access to use anything save for this view.
The GROUP BY is causing that.
It causes one result row to be returned per group, in this for each distinct value of customer_email.
If you want the total number of distinct email addresses, then you need to drop the GROUP BY clause and change the COUNT to COUNT(DISTINCT customer_email).
You need to subquery it further
select count(*) CustomerCount
from (
select count(customer_email) as num_prev
from _pj_cust_email_by_date
where order_date < '2011-02'
and customer_email is not null
group by customer_email having count(order_date) > 0;
) as innercount
That would normally be the approach, but since you're using having count(order_date) > 0, I think you only need
select count(distinct customer_email) as num_prev
from _pj_cust_email_by_date
where order_date < '2011-02' and customer_email is not null
Because the HAVING clause will never detail with empty order_dates which makes the HAVING clause a dud, actually.