Search MySQL database, order results by COUNT - php

I have a database table 'sales_list'. In this is rows of sales records attributed to a users_sales_guild_id. I'd like to query the table and order results by the number of sales made by each user, highest to lowest.
I thought this query would do it, but alas no...
$total_query = "SELECT *, COUNT(users_sales_guild_id) AS users_sales_guild_id_count FROM sales_list WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2014-11-30 23:59:59' ORDER BY users_sales_guild_id_count DESC";
$total_rs = mysql_query($total_query) or trigger_error ("Query: $total_query\n<br>MySQL Error: " .#mysql_error()); // Run the query.
$num_rs = mysql_num_rows($total_rs);
This query returns 1 record. rather than a selection of records ordered by the number of sales by each user.
Your assistance is much welcomed.

count(*) will return one row unless there is a group by clause, so the query should be as
SELECT *,
COUNT(*) AS users_sales_guild_id_count
FROM sales_list
WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2014-11-30 23:59:59'
group by users_sales_guild_id
ORDER BY users_sales_guild_id_count DESC
UPDATE : Its better to select col1,col2 ..... instead of * while doing group by - Point raised by InoSHeo
check this link
http://sqlfiddle.com/#!2/1201d/6

check this link if you would like to get details based on username http://sqlfiddle.com/#!2/1201d/4 here i have used type instead you can use username

Related

Multiple PHP subqueries not giving desired result

I have a MySQL table from which I want to extract attendance information(Student Id, course/subject for attendance, date range,whether the student was present or not). I have written the following query:
SELECT
COUNT(a_id),
(
SELECT COUNT(*) FROM attendance
WHERE state = 'present'
AND `dater` BETWEEN '$a' AND '$b'
) AS Count,
stud_id
FROM attendance
WHERE
stud_id =(SELECT id FROM users WHERE NAME = '$stud')
Which is giving me the correct results, but when I change the student,its not giving me the correct count for the days recorded for present. Not mention that I have not yet added the course parameter into the query
The MySQL table is as follows:
I need help for the query to return the desired results(Count the accurate days present for each student, as well as adding the course parameter into the query so that the query will look for attendance records for a specific course, for a specific student, for a specified date range).
Looks like you want to seperate your queries:
Select (select count(*) from <database>.attendance where state = 'present' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as present, (select count(*) from <database>.attendance where state = 'absent' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as absent from <database>.attendance WHERE stud_id =(SELECT id FROM users WHERE NAME = '$stud');
try this :)
Resolved it using JOIN as follows:
SELECT u.id, a.stud_id, a.course_id, count(*) FROM attendance a
JOIN users u ON u.id=a.stud_id
JOIN courses c ON c.c_id=a.course_id
WHERE a.state='present' and dater between '2017-09-01' and '2017-09-14'
GROUP BY a.stud_id, a.course_id;
Thanks for your help.

SQL Order By id and Count star not working

I would like to get number of all records and get last record :
$sql_count_sms = "SELECT count(*) as total,content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = $row_num_sms['total'];
$last_my_sms = $row_num_sms['content'];
I can get number of records but I can't get last content record .
It returns first record !
Where is my wrong ?
Below codes works fine, but I think count(*) is faster than mysql_num_rows .
$sql_count_sms = "SELECT content,id FROM android_users_sms WHERE user_id=$id ORDER BY id DESC";
$result_count_sms = mysql_query($sql_count_sms);
$row_num_sms = mysql_fetch_assoc($result_count_sms);
$num_sms = mysql_num_rows($result_count_sms);
$last_my_sms = $row_num_sms['content'];
Any solution?
The grain of the two results you want is not the same. Without using a sub-query you can't combine an aggregate and a single row into the same result.
Think of the grain as the base unit of the result. The use of GROUP BY and aggregate functions can influence that "grain"... one result row per row on table, or is it grouped by user_id etc... Think of an aggregate function as a form of grouping.
You could break it out into two separate statements:
SELECT count(*) as total FROM android_users_sms WHERE user_id = :id;
SELECT * FROM android_users_sms WHERE user_id = :id ORDER BY id DESC LIMIT 1;
Also, specific to your question, you probably want a LIMIT 1 in combination with the ORDER BY to get just the last row.
Now, counter intuitively perhaps, this should also work:
SELECT count(*), content, id
FROM android_users_sms
WHERE user_id = :id
GROUP BY id, content
ORDER BY id
LIMIT 1;`
This is because we've changed the "grain" with the GROUP BY. This is the real nuance and I feel like this could probably be explained better than I am doing now.
You could also do this with a sub query like so:
SELECT aus.*,
(SELECT count(*) as total FROM android_users_sms WHERE user_id = :id) AS s1
FROM android_users_sms AS aus
WHERE user_id = :id ORDER BY id DESC LIMIT 1;

How to select all from MySQL table where column between dates and order by column

I am working on a project to build an assessment leader board for a learning centre. I've got a table that looks like this
I am trying to write a query which will select all from the table by CLASS, within DATE range, add score per individual STUDENT_ID and then order in descending order by the added score to create the leader board. I've read a little on sub queries but can't quite understand the examples or exactly how they work, I also think I would need a SELECT DISTINCT student_id in my query but my knowledge here is also limited as I have only used it once.
Anyway this is what I have so far.
$classcheck = mysql_query("SELECT *
FROM assessment
WHERE class = '$class_info'
order by score DESC")
or die(mysql_error());
if(mysql_num_rows($classcheck) > 0){
while($row = mysql_fetch_array($classcheck)){
if(strtotime($row["date"]) > strtotime($fromdate) && strtotime($row["date"]) < strtotime($todate)){
echo $row['score'].'<p>';
}
}
}
But I need it to add SCORE and order by the added SCORE in the query somewhere which I cannot achieve with what I have written.
I know should start using PDO rather than mysql_query, knowledge limited again and I am running out of time. All feedback would be greatly appreciated. OH, and the score is really a percentage.
You don't need a subquery, you just need SUM and GROUP BY to total the scores by student, and a WHERE clause to restrict the dates.
SELECT student_name, SUM(score) AS total_score
FROM assessment
WHERE date BETWEEN '$fromdate' AND '$todate'
AND class = '$class_info'
GROUP BY student_id
ORDER BY total_score DESC
I think a GROUP BY might do the trick since you are trying to add up all the scores of an individual STUDENT_ID.
Please feel free to correct me if I'm wrong but the following SQL should get you what you are looking for.
SELECT SUM(score) AS ttl_score, student_name
FROM assessment
WHERE class='$class_info'
AND date>='$start' AND date<='$end'
GROUP BY student_id ORDER BY ttl_score DESC;
$classcheck = mysql_query("Select Student_id, sum(Score) as SummedScore from assessment where class='$class_info' and
date between '$fromdate' and '$todate' Group by Student_ID Order By SummedScore"
or die(mysql_error());
if(mysql_num_rows($classcheck) > 0){
while($row = mysql_fetch_array($classcheck)){
echo $row['SummedScore'].'<p>';}
}

How can I order by count in mysql when the count need data to calculate from this select statement?

Look at my code, I want the select statement order by the count percentage after I fetch the data from this select statement, obviously, it's not logical. What can I do? Help, appreciate.
<?php
//myslq connection code, remove it because it's not relate to this question
$stm =$db->prepare("SELECT id ,term_count, COUNT(user_id) as count FROM sign WHERE term IN (:term_0,:term_1) GROUP BY user_id ORDER by count DESC");
//trying replace order by count with $combine_count, but it's wrong
$term_0="$term[0]";
$term_1="$term[1]";
$stm->bindParam(":term_0", $term_0);
$stm->bindParam(":term_1", $term_1);
stm->execute();
$rows = $stm->fetchALL(PDO::FETCH_ASSOC);
foreach ($rows as rows) {
$count=$rows['count'];
$term_count_number=$rows['term_count'];
$count_percentage=round(($count/$count_user_diff)*100);
$count_key_match=round(($count/$term_count_number)*100);
$combine_count=round(($count_percentage+$count_key_match)/2);
//issue is here, I want the select statement order by $combine_count
}
?>
SELECT id ,term_count, COUNT(user_id) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
Since "count" is a function, it would be better to put backtics around the non-function "counts", as done above.
GROUP BY should list the field not aggregated. Otherwise, it does not know which id and term_count to fetch. So, depending on what you are looking for,
Either do
SELECT user_id, COUNT(*) as `count` -- I changed this line
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY user_id
ORDER by `count` DESC");
or do
SELECT id ,term_count, COUNT(*) as `count`
FROM sign
WHERE term IN (:term_0,:term_1)
GROUP BY id ,term_count -- I changed this line
ORDER by `count` DESC");
SQL Syntax Logic
SELECT column1, count(column1) AS amount
FROM table_name
GROUP BY column1
ORDER BY amount DESC
LIMIT 12

Search MySQL database table, order results by SUM

Similar to my question yesterday:
I have a database table 'sales_list'. In this is rows of sales records attributed to a users_sales_guild_id. I'd like to query the table and order results by the SUM of the 'sales_points' field by each user, highest points to lowest.
I found another question on SO that I thought would solve my issue - MySQL: how to sum up vaues of rows and sort the result? - but it doesn't seem to hit the mark entirely.
I thought this query would do it, but alas no...
$total_query = "SELECT users_sales_guild_new_id, SUM(sales_points) AS total_sales_points
FROM sales_list
WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2013-12-31 23:59:59'
GROUP BY users_sales_guild_new_id
ORDER BY total_sales_points DESC";
This query returns only 1 record. rather than a selection of records ordered by the SUM of sales points by each user.
Your assistance is much welcomed.
Try this-> You can't pass the alias to order by.
$total_query = "SELECT users_sales_guild_new_id, SUM(sales_points) AS total_sales_points
FROM sales_list
WHERE sales_entry_date BETWEEN '2013-10-01 00:00:00' AND '2013-12-31 23:59:59'
GROUP BY users_sales_guild_new_id
ORDER BY SUM(sales_points) DESC";

Categories