MYSQL group and order query - mysql

I have a table with name and order date. I am trying to come up with a query to show the last time each name ordered in reverse order. So each names newest order but sorted by the name that ordered earliest.
So with this data
Tom,10/01/2013
Bob,09/24/2013
Tom,11/03/2013
Tom,10/24/2013
Bill,11/01/2013
Bob,10/22/2013
I want this
Bob,10/22/2013
Bill,11/01/2013
Tom,11/03/2013
I have tried SELECT * from orders group by name order by -odate
that got either random or older than the newest dates
I then tried SELECT * from orders order by -odate group by name
thinking it would sort first but it returned nothing
Thanks
Ed

SELECT name, MAX(odate) odate FROM orders GROUP BY name ORDER BY odate

The key thing here is to GROUP BY the name, but to select the maximum value that you need.
When grouping you can perform range functions on other fields.
Using the ORDER BY DESC puts the most recent first.
SELECT name, MAX(odate) AS odate FROM orders GROUP BY name ORDER BY odate DESC
see SQL Fiddle

Try using MAX function for your date column
SELECT name, MAX(odate) from orders group by name order by odate

Related

MySQL error- COUNT does not exist, error 1630

I have been working in mySQL and I have been having issues with the COUNT function. I have already tried removing the spaces and the error persists.
SELECT COUNT(payment) FROM paymentType
GROUP BY payment
ORDER BY COUNT (payment) DESC
LIMIT 1;
I am trying to find the most common payment entry in the table paymentType.
If you want the most common payment, then I think you want:
SELECT payment
FROM paymentType
GROUP BY payment
ORDER BY COUNT(*) DESC
LIMIT 1;
this will work:
SELECT Count(payment),payment FROM paymentType
GROUP BY payment
ORDER BY COUNT DESC
LIMIT 1;
Note: the column you will get after the COUNT function will be a new column… And it has to have a name – so SQL automatically names it “count” (check the latest screenshot above). When you refer to this column in your ORDER BY clause, you have to use this new name
Something like this maybe?
select *
from (
select payment, count(*) as c from paymentType group by payment
) x
order by c desc
limit 1
Don't put the space in HAVING clause between COUNT and (
Try this:
ORDER BY COUNT(payment) DESC
Count aggregate function SQL

The MAX(Date) returned incorrect column data in MySQL

In my query below I got the correct return on MAX(Date) but It has incorrect return on BidModifier column. Is there a line that I need to add so that I can get the correct data corresponds to my MAX(Date)?
Here is my query:
SELECT AdGRoupId, Criteria, MAX(DATE) LatestDate , CpcBid, CpcBidSource,
BidModifier
FROM aw_placementbid
WHERE DATE
IN (
SELECT DATE
FROM aw_placementbid
GROUP BY AdGroupId, Criteria
)
GROUP BY AdGroupId, Criteria
ORDER BY BidModifier DESC
Try this query:
SELECT AdGRoupId, Criteria, DATE, CpcBid, CpcBidSource, BidModifier
FROM
(
SELECT AdGRoupId, Criteria, DATE, CpcBid, CpcBidSource, BidModifier
FROM aw_placementbid
ORDER BY DATE DESC
) AS t
GROUP BY AdGroupId, Criteria
ORDER BY BidModifier DESC
Firstly, you select all the data you need and order by DATE, thus records with a big DATE will be ranked in the top.
Then, you divide the temporary table above into several groups(via GROUP BY AdGroupId, Criteria).
At last, you just fetch the first row of each group(it must be the row with a MAX(DATE) as you have sorted all records before).

How to sort and group data in mysql by 2 different columns?

I've a table cart which structure is following: id, item_id, session_id, date, num, so I need rows to be grouped by session_id column and sorted by date column in the same time, is it possible?
Yes it is possible.
... order by session_id, date
This will order firstly by session_id, and then by date. I believe that is what you want?
Try this:
SELECT * FROM YourTable
GROUP BY session_id ORDER BY date DESC;
Hope this helps!
You cant group by session_id and in the same time order by date.
You will get:
ORDER BY clause because it is not contained in either an aggregate function or the GROUP BY clause
what you can do is:
SELECT [session_id],[date]
From TableName
group by [session_id], [date]
order by [date] desc

Return the values of max count of rows with the same values

I have table_schedule(id,instructorNumber,time,date,cpNumber,user_id);
Is it possible to output the values of instructorNumber,time, etc. with the same highest occurence with same values?
sorry I am new in sql, so I am hoping that someone can help me to the query
Just group by all the fields you need for "same value comparison", order by count desc (so the result with most occurences will be first), and take first.
select
instructorNumber, time, date, cpNumber
from table_schedule
group by instructorNumber, time, date, cpNumber
order by count(*) desc
LIMIT 1
you may use this as a join on a main query if you want more than one result.
First group by the values you want to compare by and count. Get the maximum count (in MySQL you can use LIMIT for that). Then do the same group-by query again and take only the results HAVING the maximum count. Use GROUP_CONCAT to get a list of IDs in a string.
select instructorNumber, time, date, cpNumber, user_id, group_concat(id) as ids
from table_schedule
group by instructorNumber, time, date, cpNumber, user_id
having count(*) =
(
select count(*)
from table_schedule
group by instructorNumber, time, date, cpNumber, user_id
order by count(*) desc limit 1
);

ORDER BY date and time BEFORE GROUP BY name in mysql

i have a table like this:
name date time
tom | 2011-07-04 | 01:09:52
tom | 2011-07-04 | 01:09:52
mad | 2011-07-04 | 02:10:53
mad | 2009-06-03 | 00:01:01
i want oldest name first:
SELECT *
ORDER BY date ASC, time ASC
GROUP BY name
(->doesn't work!)
now it should give me first mad(has earlier date) then tom
but with GROUP BY name ORDER BY date ASC, time ASC gives me the newer mad first because it groups before it sorts!
again: the problem is that i can't sort by date and time before i group because GROUP BY must be before ORDER BY!
Another method:
SELECT *
FROM (
SELECT * FROM table_name
ORDER BY date ASC, time ASC
) AS sub
GROUP BY name
GROUP BY groups on the first matching result it hits. If that first matching hit happens to be the one you want then everything should work as expected.
I prefer this method as the subquery makes logical sense rather than peppering it with other conditions.
As I am not allowed to comment on user1908688's answer, here a hint for MariaDB users:
SELECT *
FROM (
SELECT *
ORDER BY date ASC, time ASC
LIMIT 18446744073709551615
) AS sub
GROUP BY sub.name
https://mariadb.com/kb/en/mariadb/why-is-order-by-in-a-from-subquery-ignored/
I think this is what you are seeking :
SELECT name, min(date)
FROM myTable
GROUP BY name
ORDER BY min(date)
For the time, you have to make a mysql date via STR_TO_DATE :
STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s')
So :
SELECT name, min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
FROM myTable
GROUP BY name
ORDER BY min(STR_TO_DATE(date + ' ' + time, '%Y-%m-%d %h:%i:%s'))
This worked for me:
SELECT *
FROM your_table
WHERE id IN (
SELECT MAX(id)
FROM your_table
GROUP BY name
);
Use a subselect:
select name, date, time
from mytable main
where date + time = (select min(date + time) from mytable where name = main.mytable)
order by date + time;
If you wont sort by max date and group by name, you can do this query:
SELECT name,MAX(date) FROM table group by name ORDER BY name
where date may by some date or date time string. It`s response to you max value of date by each one name
Another way to solve this would be with a LEFT JOIN, which could be more efficient. I'll first start with an example that considers only the date field, as probably it is more common to store date + time in one datetime column, and I also want to keep the query simple so it's easier to understand.
So, with this particular example, if you want to show the oldest record based on the date column, and assuming that your table name is called people you can use the following query:
SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date > p2.date
WHERE p2.date is NULL
GROUP BY p.name
What the LEFT JOIN does, is when the p.date column is at its minimum value, there will be no p2.date with a smaller value on the left join and therefore the corresponding p2.date will be NULL. So, by adding WHERE p2.date is NULL, we make sure to show only the records with the oldest date.
And similarly, if you want to show the newest record instead, you can just change the comparison operator in the LEFT JOIN:
SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date < p2.date
WHERE p2.date is NULL
GROUP BY p.name
Now, for this particular example where date+time are separate columns, you would need to add them in some way if you want to query based on the datetime of two columns combined, for example:
SELECT p.* FROM people p
LEFT JOIN people p2 ON p.name = p2.name AND p.date + INTERVAL TIME_TO_SEC(p.time) SECOND > p2.date + INTERVAL TIME_TO_SEC(p2.time) SECOND
WHERE p2.date is NULL
GROUP BY p.name
You can read more about this (and also see some other ways to accomplish this) on the The Rows Holding the Group-wise Maximum of a Certain Column page.
I had a different variation on this question where I only had a single DATETIME field and needed a limit after a group by or distinct after sorting descending based on the datetime field, but this is what helped me:
select distinct (column) from
(select column from database.table
order by date_column DESC) as hist limit 10
In this instance with the split fields, if you can sort on a concat, then you might be able to get away with something like:
select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted
Then if you wanted to limit you would simply add your limit statement to the end:
select name,date,time from
(select name from table order by concat(date,' ',time) ASC)
as sorted limit 10
In Oracle, This work for me
SELECT name, min(date), min(time)
FROM table_name
GROUP BY name
work for me mysql
select * from (SELECT number,max(date_added) as datea FROM sms_chat group by number) as sup order by datea desc
This is not the exact answer, but this might be helpful for the people looking to solve some problem with the approach of ordering row before group by in mysql.
I came to this thread, when I wanted to find the latest row(which is order by date desc but get the only one result for a particular column type, which is group by column name).
One other approach to solve such problem is to make use of aggregation.
So, we can let the query run as usual, which sorted asc and introduce new field as max(doc) as latest_doc, which will give the latest date, with grouped by the same column.
Suppose, you want to find the data of a particular column now and max aggregation cannot be done.
In general, to finding the data of a particular column, you can make use of GROUP_CONCAT aggregator, with some unique separator which can't be present in that column, like GROUP_CONCAT(string SEPARATOR ' ') as new_column, and while you're accessing it, you can split/explode the new_column field.
Again, this might not sound to everyone. I did it, and liked it as well because I had written few functions and I couldn't run subqueries. I am working on codeigniter framework for php.
Not sure of the complexity as well, may be someone can put some light on that.
Regards :)