Ok I am lost, I have no idea why those both querys have different output.
The table looks something like this:
+------------+--------+--------+
| date | kills | deaths |
+------------+--------+--------+
| 2016-05-03 | 123456 | 123456 |
+------------+--------+--------+
SELECT SUBDATE(CURRENT_DATE(),30), `kills`, `deaths`
FROM `bf4c_1558544842`
WHERE `date` <= SUBDATE(CURRENT_DATE(),30)
ORDER BY `date` DESC
LIMIT 1
SELECT SUBDATE(CURRENT_DATE(),30) AS "date", `kills`, `deaths`
FROM `bf4c_1558544842`
WHERE `date` <= SUBDATE(CURRENT_DATE(),30)
ORDER BY `date` DESC
LIMIT 1
The only difference is the AS "date", but why does that change the selection ?
The first gets me the intended first after the given border and the second gives me the last in the table.
Could pleas someone explain me why this happens ?
Thanks in advance, Feirell.
On the second query the expression SUBDATE(CURRENT_DATE(),30) is aliased as date. Later on, the selected rows are ORDER BY date and after the sort only the first row is returned.
The documentation of the SELECT statement explains:
A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.
...
MySQL resolves unqualified column or alias references in ORDER BY clauses by searching in the select_expr values, then in the columns of the tables in the FROM clause.
This basically means that aliases have higher priority than column names.
There is a column named date in the table. In the first query, ORDER BY date uses it for sorting and you get the results you expect.
On the second query, the date alias is used by the SORT BY date clause. But since it aliases the constant expression SUBDATE(CURRENT_DATE(),30) all the selected rows have the same value for the date expression. They are already sorted, no matter what their order is. Any result is possible in this case.
Edit:
A solution would be to add the table name in front of the date in the order by clause like this:
SELECT SUBDATE(CURRENT_DATE(),30) AS "date", `kills`, `deaths`
FROM `bf4c_1558544842`
WHERE `date` <= SUBDATE(CURRENT_DATE(),30)
ORDER BY `bf4c_1558544842`.`date` DESC
LIMIT 1
This way the interpreter knows that the column is meant not the new alias.
Related
I need to sort a table by date (descending), but all columns in the table are varchar, so I need to manipulate the data on the fly for sorting it correctly.
date sales
10/09/2014 100
13/09/2014 250
30/08/2014 200
Is that possible without altering the table? So the result will be like below, newest dates first?
date sales
13/09/2014 250
10/09/2014 100
30/08/2014 200
Like pseudocode
SELECT * FROM table ORDER BY (CONCAT(REGEXP(date, '[0-9]{4}'),
REGEXP(date, '/[0-9]{2}/'), REGEXP(date, '^[0-9]{4}/')) DESC
I think I need to use substring_index somehow, because regexp just returns 1 or 0, not the actual value found.
You need to convert your varchar-stored date objects into DATE objects, then use them to order.
This you can do on the fly like so
ORDER BY STR_TO_DATE(date,'%d/%m/%Y') DESC
But performance is going to be horrible. For best results store your dates in a DATE column in your table.
you can use STR_TO_DATE
SELECT *
FROM Table1
ORDER BY STR_TO_DATE(date, '%d/%m/%Y') desc,
sales desc
I'm atm seeing a strange behaviour in a sql request.
My table pointLog:
# Column Type
1 date timestamp
2 uid varchar(30)
3 ssid varchar(40)
4 reason varchar(50)
5 points int(5) No None
The statement:
SELECT date, count(date) as anzahl FROM pointLog WHERE uid = 1 order by date desc
returns following result
date anzahl
2012-09-01 12:21:16 14
But the statement:
SELECT date FROM pointLog WHERE uid = 1 order by date desc
Returns
2012-09-02 12:44:08
as first result.
So my question: why I'm not receiving the 2012-09-02 as first result in the first statement which includes a count ??
Thanks a lot!
edit
The count as anzahl is atm only used to verify that there are more than 0 entries in this example. I know its should be tested in the programm.
But my main problem is, that I can't explain, why I'm getting 2 different dates when it's sorted by the same (date). So the only difference is the count attribute. But that shouldn't normally change the sorting?
FINAL* The solution
SELECT MAX(date) AS maxdate, COUNT(date) AS anzahl FROM pointLog WHERE uid = 1
You're getting one results: a count of the dates, preceded by an arbitrary date. The ORDER BY statement is then ordering that, which is a no-op because there's only one line of output.
As #prosfilaes answered, your query does not return deterministic results, the date returned in an arbitrary one.
If you want the latest date and the count, you can use:
SELECT
MAX(date) AS maxdate,
COUNT(date) AS anzahl
FROM
pointLog
WHERE
uid = 1 ;
You need a GROUP BY in your SQL statement, otherwise the COUNT() will not give separate totals for each date.
I am using MySQL database. I have to make a stored procedure which accepts an integer type parameter. Depending upon the integer's value i have to 'order by' a different value like this..
**if(type == 1) than
order by Date Desc,
Quantity asc,
Amount asc
else if(type == 2)than
order by Date ASc,
Quantity asc,
Amount asc
else if(type == 3)than
order by
Quantity asc
Date desc,
Amount asc
However when i try this i am unable to do this its gives error also.
If you look at the syntax for SELECT, you'll see that the ORDER BY clause can't appear within a CASE statement.
If a column is a numeric type, you can write an expression that is 1 for ascending, -1 for descending and multiply the expression by the column to sort by, though this will impact performance as MySQL won't be able to use any indices for the sort.
SELECT ...
ORDER BY IF(?='d', -1, 1) * value
In general however, you'll have to use different statements to get different orderings.
If Date is a proper date or datetime you can do something like this:
ORDER BY
CASE type WHEN 3 THEN -1 * Date ELSE Date END asc,
Quantity asc, Amount asc
http://dev.mysql.com/doc/refman/5.0/en/case-statement.html
This works because date, time and the other MySQL date and time types are stored internally as integers:
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
Well i got the solution finally....
SELECT distinct
order_detail.*, -(1)*CAST(order_detail.Date as unsigned) as lOrderDate,
from order_detail
order by
CASE
WHEN type = 1 THEN lOrderDate
WHEN type = 2 THEN order_detail.Date
WHEN type = 3 THEN order_detail.Quantity
END,
CASE
WHEN type = 1 THEN order_detail.Quantity
WHEN type = 2 THEN order_detail.Quantity
WHEN type = 3 THEN lOrderDate
END,
CASE
WHEN type = 1 THEN order_detail.Amount
WHEN type = 2 THEN order_detail.Amount
WHEN type = 3 THEN order_detail.Amount
END;
Two ways:
Build your query - like a string, then use a prepared statements to execute it.
Use IF-ELSEIF-END IF statement to execute three different SELECT queries.
Not sure how this would work. I have a between query, but how would I run a query to list results that match each and every day. Example, enterys that exists on 2011-06-17, 2011-06-18, 2011-06-19 and 2011-06-20
SELECT lookup, `loc`, `octect1` ,`octect2` ,`octect3` ,`octect4`, date, time, count(`lookup`) as count FROM index
WHERE date between '2011-06-17' AND '2011-06-20'
GROUP BY lookup
ORDER BY count DESC
Thanks
Instead of BETWEEN, use comparison operators:
SELECT lookup, `loc`, `octect1` ,`octect2` ,`octect3` ,`octect4`,
date, time, count(`lookup`) as count
FROM index
WHERE date > '2011-06-17' AND date < '2011-06-20'
GROUP BY lookup
ORDER BY count DESC
The following code works, but I want the groups to show their latest query by datetime not the first datetime query. I've tried changing around the ORDER BY from ASC/DESC, but that just changes the order of all the groups, not the data within the groups. I need for both all the inside data of the groups and all the groups to order by the latest datetime.
$query="SELECT * FROM emails
WHERE sentto='$sid'
GROUP BY sentto
ORDER BY datetime DESC LIMIT $eu, $limit ";
Instead of it showing groups and ordering them by the first query:
Message from Sam Richards on January 22, 2011 (this is a group)
Message from John Smith on January 5, 2011 (this is a group)
I want it to show groups and order them by the latest query:
Message from John Smith on April 19, 2011 (this is a group)
Message from Sam Richards on March 10, 2011 (this is a group)
Please help.
I think part of your problem is that you are selecting non-aggregate columns with a group-by query. You should be explicit about which values you want it to return in the aggregate query result.
SELECT sentto, MAX(datetime) AS datetime FROM emails
GROUP BY sentto
ORDER BY datetime desc LIMIT $eu, $limit;
I'm still not sure that this gives you what you want. It sounds like you want to actually retrieve the rows for each individual email and just use the GROUP BY maximum for sorting. To do that, you'd probably need to do the above query, then go back and do a second query for each sentto. I can't think of a way offhand to do it in a single query.
SELECT * FROM emails
WHERE sentto=$sid
ORDER BY datetime DESC;
(For each sentto returned in the first query.)
How about:
ORDER BY sentto ASC, datetime DESC
To sort the data with in the groups you need to include sentto in the ORDER BY clause.
Try this:
SELECT * FROM emails
WHERE sentto='$sid'
GROUP BY sentto
ORDER BY sentto, datetime DESC LIMIT $eu, $limit