Orderby MYSQL Syntax Wrong Data - mysql

I have a Table with a Column 'Rechnungnr' and 'Date'
Example 2016/204, 2016/202, 2016/100, 2015/12, 2016/231
and i need the last highest number. Here -> 2016/231.
SELECT * FROM TABLE Where YEAR(Date) = '2016' ORDER BY length(`Rechnungnr`) DESC LIMIT 1
But thats not working :(
Greetz, Malte

Use a combination of char_length() and the value of rechnungnr to get the max value this way:
SELECT * FROM TABLE
Where YEAR(Date) = 2016 ORDER BY char_length(`Rechnungnr`) DESC, `Rechnungnr` DESC LIMIT 1
char_length() will order the results by the number of characters within Rechnungnr field, and then within the equally long strings, we order by the value of the field itself.

Try using column name date surrounded by backtics
SELECT * FROM TABLE Where YEAR(`Date`) = '2016' ORDER BY length(`Rechnungnr`) DESC LIMIT 1

With your existing data set (if I understand the schema correctly) you can try something like this to get the day of year, cast it to an int and then sort on it:
SELECT *, CAST(RIGHT(LENGTH(`Rechnungnr`) - (INSTR(`Rechnungnr`, '/') + 1)) AS UNSIGNED) AS `DayOfYear` FROM TABLE Where YEAR(Date) = '2016' ORDER BY `DayOfYear` DESC LIMIT 1

Related

How to get the max timestamp row from a given table

I am trying to get the max timestamp rows based of a group of software_image_build_id and variant
Here is my SQL fiddle link http://sqlfiddle.com/#!9/6ed643/1 ,it should output the max timestamp rows for a combination for software_image_build_id and variant ,I tried as follows but it is not helping,can anyone provide guidance on how to fix it?
SELECT software_image_build,MAX(timestamp) FROM software_image_builds where software_image_id=1452
group by software_image_build
You need to use inner query to get the data along with max timestamp and then using an outer query get the data by software_image_id and variant to ensure you are getting correct data with their max timestamp.
SELECT OUTSIDE.*
FROM software_image_builds OUTSIDE,
(SELECT software_image_id, variant, MAX(timestamp) as maxtimestamp
FROM software_image_builds
GROUP BY software_image_id, variant) AS INSIDE
WHERE OUTSIDE.software_image_id = INSIDE.software_image_id
AND OUTSIDE.variant = INSIDE.variant
AND OUTSIDE.timestamp = INSIDE.maxtimestamp
The result seems correct , what result do you want?
This sql get the software_image_build and the max timestamp every software_image_build.
If you want to get the max timestamp across all data ,dont't use group by.
SELECT software_image_build,MAX(timestamp) FROM software_image_builds where software_image_id=1452
If you want to get every software_image_build,and split the max timestamp every row,try the following query:
SELECT S.software_image_build,A.max_timestamp
FROM software_image_builds AS S,
(SELECT software_image_build,MAX(timestamp) as max_timestamp
FROM software_image_builds where software_image_id=1452)
AS A
group by S.software_image_build
output this :
software_image_build max_timestamp
CI_LA.UM.5.8-02200-8x98.1-16 2017-07-14T21:51:02Z
CI_LA.UM.5.8-02200-8x98.1-20 2017-07-14T21:51:02Z
CI_LA.UM.5.8-60402-8x98.1-1 2017-07-14T21:51:02Z
Try this
SELECT * FROM software_image_builds where software_image_id=1452
AND timestamp = (SELECT MAX(timestamp) as timestamp from
software_image_builds
where software_image_id=1452)
check in fiddle http://sqlfiddle.com/#!9/729532/44
The SQL you have now posted:
SELECT software_image_build,max(timestamp)
FROM software_image_builds
WHERE software_image_id=1452
GROUP BY software_image_build,variant
LIMIT 1
outputs:
software_image_build timestamp
CI_LA.UM.5.8-02200-8x98.1-16 2017-07-13T18:38:41Z
CI_LA.UM.5.8-02200-8x98.1-20 2017-07-14T21:51:02Z
CI_LA.UM.5.8-60402-8x98.1-1 2017-02-28T15:08:10Z
which appears to be exactly what you now say you wanted. If not, further clarification is required.
You can order the results by the timestamp column and then use limit to return only the first result.
SELECT software_image_build, timestamp FROM software_image_builds where
software_image_id=1452 group by software_image_build order by timestamp DESC
limit 1
select * from software_image_builds where timestamp in (SELECT MAX(timestamp)
FROM software_image_builds group by
software_image_id, variant );

Query to Display records except Initial Record

For my project, i have a requirement where i have to display all the records in descending order except the first record. I am kind of messed up. Anyways, i have tried the following:
SELECT * FROM ins_nr nl WHERE nl.nl_status = '2' ORDER BY nl.nl_id DESC
Here, i have a table called ins_nr which will display all the records with status 2 and the id which is the primary key(unique). It is displaying in desc order perfectly.
I dont want the first record from the top alone. What should i do? How to modify the above query..?
Use OFFSET. Then you can skip 1 records and select the remaining ones until the end.
Example:
SELECT * FROM ins_nr nl WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC LIMIT 99999999999 OFFSET 1;
OR ( You could also use a shorter syntax to achieve the same result: )
$sql = "SELECT * FROM table_name LIMIT 1, 999999999";
You can generate dynamic rownum and filter on it to omit the first row, e.g.:
SELECT *
FROM (
SELECT nl.*, #r := #r + 1 AS `rn`
FROM ins_nr nl, (SELECT #r := 0)
WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC
) a
WHERE a.rn > 1;
Another way is to get the max id from subquery and put it in a where clausole
You are looking for the offset clause. This looks like:
SELECT *
FROM ins_nr nl
WHERE nl.nl_status = '2'
ORDER BY nl.nl_id DESC
LIMIT 999999999 OFFET 1;
Unfortunately, LIMIT is required. For this situation, it is traditional to just put in a very large number.
Also, if nl_status is numeric, then use nl.nl_status = 2. Don't compare strings to numbers.

Mysql time difference UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timestamp)

My current sql statement is like follows..
SELECT * FROM `Main`
WHERE username = '$username'
AND fromsite = '$website'
ORDER BY `votes`.`timestamp` DESC
LIMIT 0 , 1
however the timestamp column shows a timestamp like " "2014-03-19 12:00:43" ...Following another question I had an answer along the lines of using ...
SELECT UNIX_TIMESTAMP() - UNIX_TIMESTAMP(timestamp) AS seconds_ago
However not great with mysql and still don't see how I can still use the original select statement and work in a function like above, so that converts the timestamp column and shows as seconds ago instead.
Just ditch the * and list the columns and expressions you want returned.
SELECT m.username
, m.fromsite
, m.timestamp
, UNIX_TIMESTAMP()-UNIX_TIMESTAMP(m.timestamp) AS seconds_ago
, m.votes
FROM `Main` m
WHERE m.username = '$username'
AND m.fromsite = '$website'
ORDER BY m.votes, m.timestamp DESC
LIMIT 0,1

Sorting a column in ascending and descending order depending on the current date

Please help. Here my mySQL query
SELECT *
FROM (`products`)
ORDER BY (
CASE WHEN `ExpiredDate` > NOW()
THEN 1
ELSE 0
END) DESC , `ExpiredDate` ASC
I'm going to sort the array result as the available products like this:
12-10-2013
12-15-2013
12-28-2013
12-09-2013 -- Today
12-08-2013
12-04-2013
12-01-2013
But the current result is now the expired products is order by ascending like this:
12-10-2013
12-15-2013
12-28-2013
12-09-2013 -- Today
12-01-2013
12-04-2013
12-08-2013
This should do the trick:
SELECT * FROM products
ORDER BY ExpiredDate < NOW(), ABS(TIMESTAMPDIFF(SECOND, expiredDate, NOW()))
Fiddle here
You should use following query instead of yours,
SELECT *
FROM (products)
ORDER BY (
CASE WHEN DATE_FORMAT(ExpiredDate,'%Y-%m-%d') > NOW()
THEN 1
ELSE 0
END) DESC , ExpiredDate ASC
More details can be found at
http://www.mysqltutorial.org/mysql-date_format/

ORDER BY separately positive & negative numbers in MySQL statement

I have a MySQL table and would like to return the rows based on a column value in this order:
First ascending order if the column >=0
Then descending order if the column <0
E.g. 0,2,4,7,-2,-3,-5
Can use SIGN to sort the positive numbers to the top, then take the absolute value with ABS to get the desired ASC/DESC.
SELECT * FROM theTable
ORDER BY SIGN(col) DESC, ABS(col)
EDIT
As Nahuel pointed out, the above will sort 0's to the middle between positive and negative. To instead group them with the positives, you can use a CASE instead (or, if your column is only integers, the slightly magical SIGN(col + 1))
SELECT * FROM theTable
ORDER BY
CASE WHEN col >= 0 THEN 1 ELSE 2 END,
ABS(col)
SELECT columnName1 FROM Tbl
WHERE columnName1 >= 0
ORDER BY columnName1 ASC
UNION
SELECT columnName1 FROM Tbl
WHERE columnName1 < 0
ORDER BY columnName1 DESC
Should work