mysql order by count - ordering by value - mysql

I am attempting to count number of records in a database by grouping them. This works fine, but when I try to order by, it orders the count by a different method than wanted. Example Result:
Question - Answer - Count
Q1 - A1 - 1
Q2 - A2 - 11
Q3 - A3 - 2
Result wanted: I want 11 after 2-9, not before. The query is simply:
SELECT Question, Answer, count(*) as `Count` GROUP BY Question, Answer ORDER BY Question, Answer
A further example of the sort is that the mysql sorts like, 1,11,118,12,2,3 where I am expecting the increasing value like 1,2,3,11,12,118

try this query
SELECT Question, Answer, count(*) as `Count`
FROM table
GROUP BY Question, Answer
ORDER BY count(*) ASC

You have put in your query
ORDER BY Question, Answer
If you want 11 to come after 2, then surely you want
ORDER BY Count

The issue appears that I was trying to order by character value instead of integer value? I have to cast the answer as an integer and then it order properly. Here is the query that works:
SELECT Question, Answer, count(*) as `Count` GROUP BY Question, Answer ORDER BY Question, CAST( answer AS SIGNED INTEGER )
Found the answer here:
Sorting varchar field numerically in MySQL

Related

How select day name and max average with sql's database

I have the following columns in my database:
- day
- browser
- platforms
- visitors_number
I have to choose the day of the week for which the average number of visitors was maximum and display this maximum average. I searched the forum, found a similar thread, but the solution does not work, I get an error. I would add that I am sitting on it for the second day and I lack ideas. I will add that it works on phpMyAdmin.
This is my code:
select DAYNAME(DAY), avgVIS
from
(
select DAYNAME(DAY), avg(VISITORS_NUMBER) as avgVIS
from dane_2
group by DAYNAME(DAY)
)
where avgVIS = (select max(avgVIS)
from ( select DAYNAME(DAY), avg(VISITORS_NUMBER) as avgVIS
from dane_2
group by DAYNAME(DAY)))
this is output's error
#1064 - Something is wrong in your syntax obok 'where avgVIS = (select max(avgVIS)
from ( select DAYNAME(DAY), a'
Can someone helps me ?
Thank you in advance
You already have the aggregation query that computes the daily average. All that is let to do is sort and limit:
select dayname(d.DAY) day_name, avg(d.VISITORS_NUMBER) avg_vis
from dane_2 d
group by dayname(d.DAY)
order by avg_vis desc
limit 1
Note: DAY is a reserved word in MySQL, so not a good choice for a column name (I qualified it with the table alias to avoid errors).

Count per month if unique

I am trying to get a SQL query to count personid unique for the month, is a 'Returning' visitor unless they have a record of 'New' for the month as well.
month | personid | visitstat
---------------------------------
January john new
January john returning
January Bill returning
So the query I'm looking for should get a count for each unique personid that has "returning" unless a "new" exists for that personid as well - in this instance returning a count of 1 for
January Bill returning
because john is new for the month.
The query I've tried is
SELECT COUNT(distinct personid) as count FROM visit_info WHERE visitstat = 'Returning' GROUP BY MONTH(date) ORDER BY date
Unfortunately this counts "Returning" even if a "New" record exists for the person in that month.
Thanks in advance, hopefully I explained this clearly enough.
SQL Database Image
Chart of Data
You already wrote the "magic" word yourself, "exists". You can use exactly that, a NOT EXISTS and a correlated subquery.
SELECT count(DISTINCT vi1.personid) count
FROM visit_info vi1
WHERE vi1.visitstat = 'Returning'
AND NOT EXISTS (SELECT *
FROM visit_info vi2
WHERE vi2.personid = vi1.personid
AND year(vi2.date) = year(vi1.date)
AND month(vi2.date) = month(vi1.date)
AND vi2.visitstat = 'New')
GROUP BY year(vi1.date),
month(vi1.date)
ORDER BY year(vi1.date),
month(vi1.date);
I also recommend to include the year in the GROUP BY expression, as you otherwise might get unexpected results when the data spans more than one year. Also only use expressions included in the GROUP BY clause or passed to an aggregation function in the ORDER BY clause. MySQL, as opposed to virtually any other DBMS, might accept it otherwise, but may also produce weird results.
I also faced one of the same scenarios I was dealing with a database. The possible way I did was to use group by with having clause and a subquery.

Show date from a chain of characters

this is my first question here, thanks for your support.
I have an old database with many columns, but the is not a DATE column. Yes, my mistake.
But, I have a column called question_id with some data, that contains the date and time, like
2017113020440370769
where first 4 digits are YYYY, next 2 digits are MM and next 2 are DD.
I´m trying to make a query extracting those characters to count how many questions I had on specific dates.
I could, doing this for a specific date:
SELECT COUNT(*)
FROM questions
WHERE question_id LIKE '20171228%';
But I want to automatize this for TODAY, everyday, not typing each day the YYYYMMDD%
Is it possible? Using CURDATE? Or there is any specific TIMESTAMP I can use?
Thank you very much!
Yes it is possible, you can build the current dates with wild card as below:
SELECT COUNT(*)
FROM questions
WHERE question_id LIKE CONCAT(DATE_FORMAT(CURDATE(), '%Y%m%d'), '%');
That's for a specific day; today. For all dates you would have to do an aggregation on the date part of the question_id as illustrated below:
SELECT SUBSTR(question_id,1,8) ASKED_ON, COUNT(*) NUMBER_OF_QUESTIONS
FROM questions
GROUP BY SUBSTR(question_id,1,8);
You can get today's date with e.g. CURDATE()
You can format dates with DATE_FORMAT()
You con concatenate strings with CONCAT()
Those are all the bricks you need ;-)
Try this:
SELECT LEFT('20171228ASD',8) = CURRENT_DATE();
SELECT COUNT(*)
FROM questions
WHERE LEFT(question_id',8) = CURRENT_DATE();

Calculate difference in Dates for each cell with next cell

I have a Data as follows:
Order_id Created_on Comment
1 20-07-2015 18:35 Order Placed by User
1 20-07-2015 18:45 Order Reviewed by the Agent
1 20-07-2015 18:50 Order Dispatched
2 20-07-2015 18:36 Order Placed by User
And I am trying to find the difference between the
first and second Date
Second and third Date for each Order. How Do i Obtain this through a SQL query?
SQL is about horizontal relations - vertical relations do not exist. To a relational database they're just 2 rows, stored somewhere on a disk, and until you apply ordering to a result set the 'first and second' are just 2 randomly picked rows.
In specific cases it's possible to calculate the time difference within SQL, but rarely a good idea for performance reason, as it requires costly self-joins or subqueries. Just selecting the right data in the right order and then calculating the differences during postprocessing in C#/PHP/whatever is far more practical and faster.
I think you can use a query like this:
SELECT t1.Order_id, t1.Created_on, TIMEDIFF(mi, t1.Created_on, COALESCE(MIN(t2.Created_on), t1.Created_on)) AS toNextTime
FROM yourTable t1
LEFT JOIN yourTable t2 ON t1.Order_id = t2.Order_id AND t1.Created_on < t2.Created_on
GROUP BY t1.Order_id, t1.Created_on
Posting this even though another answer has been accepted already - and I don't disagree with the accepted answer - but there is in fact a fairly neat way to do this with mySQL variables.
This query will give you the time between stages in minutes - it can't be expressed as a datetime as it's an interval between two dates:
SELECT
Order_id,
Created_on,
Comment,
if (#last_id = Order_id, TIMESTAMPDIFF(MINUTE, #last_date, Created_on), 0) as StageMins,
#last_id := Order_id,
#last_date := Created_on
FROM tblData
ORDER BY Order_id, Created_on;
SQL Fiddle here: http://sqlfiddle.com/#!9/6ffdd/10
Info on mySQL TIMESTAMPDIFF function here: https://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timestampdiff

MYSQL SELECT * doesn't work with GROUP BY and HAVING [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 8 years ago.
SELECT * FROM or_mail
GROUP BY campaign_id
HAVING date_time = MAX(date_time);
SELECT campaign_id, date_time FROM or_mail
GROUP BY campaign_id
HAVING date_time = MAX(date_time);
The 1st query returns 13 records. The 2nd returns 35.
Why are records missing from the first query!? Why should what I'm selecting matter at all?
This is your query:
SELECT campaign_id, date_time
FROM or_mail
GROUP BY campaign_id
HAVING date_time = MAX(date_time);
You are aggregating by campaign_id. That means that the results will have one row per campaign_id. What date_time goes on the row? Well, an arbitrary value from one of the matching rows. Just one value, an arbitrary one. The same is true of the having clause. In other words, the query does not do what you expect it to do.
Whether you know it or not, you are using a group by extension that is particular to MySQL (you can read the documentation here). The documentation specifically warns against using the extension this say. (There would be no problem if date_time were the same on all rows with the same campaign_id, but that is not the case.)
The following is the query that you actually want:
SELECT campaign_id, date_time
FROM or_mail om
WHERE not exists (select 1
from or_mail om2
where om2.campaign_id = om.campaign_id and
om2.date_time > date_time
);
What this says is: Return results from all rows in or_mail with the property that there is no larger date_time with the same campaign_id.
HAVING date_time = MAX(date_time);
It shouldn't... Did you wait a while before running second query? If so, then a bunch of records could have been created.