auto order by ID in mySQL query result - mysql

I'm trying to solve an issue. When I write a query
SELECT ID, STOCK_ID, FILE_NAME FROM motor_images where STOCK_ID = 25
It does not sort my record. It shows random order. I want to sort it as per ID. I've also tried ORDER BY keyword but it does not work. Please help.
Query Result

if your id isn't an auto generated int; it will sort by strings meaning 1,2,3...123, 124,125 etc will be ordered as
1,123,124,125,2,3 etc.
what you need to do in this case is use a cast by int
SELECT id, stock_id, file_name FROM motor_images WHERE stock_id = 25 ORDER BY CAST(id as UNSIGNED)
Keep in mind the UNSIGNED is an integer; read more in the mysql documentation on casting. I could be wrong but there's no other reason I could think of that would cause the ids not to order correctly. http://ftp.nchu.edu.tw/MySQL/doc/refman/5.0/en/cast-functions.html#function_cast

Related

DENSE_RANK() OVER and IFNULL()

Let's say I have a table like this -
id
number
1
1
2
1
3
1
I want to return the second largest number, and if there isn't, return NULL instead. In this case, since all the numbers in the table are the same, there isn't the second largest number, so it should return NULL.
These codes work -
SELECT IFNULL((
SELECT number
FROM (SELECT *, DENSE_RANK() OVER(ORDER BY number DESC) AS ranking
FROM test) r
WHERE ranking = 2), NULL) AS SecondHighestNumber;
However, after I changed the order of the query, it doesn't work anymore -
SELECT IFNULL(number, NULL) AS SecondHighestNumber
FROM (SELECT *, DENSE_RANK() OVER(ORDER BY number DESC) AS ranking
FROM test) r
WHERE ranking = 2;
It returns blank instead of NULL. Why?
Explanation
This is something of a byproduct of the way you are using subquery in your SELECT clause, and really without a FROM clause.
It is easy to see with a very simple example. We create an empty table. Then we select from it where id = 1 (no results as expected).
CREATE TABLE #foo (id int)
SELECT * FROM #foo WHERE id = 1; -- Empty results
But now if we take a left turn and turn that into a subquery in the select statement - we get a result!
CREATE TABLE #foo (id int)
SELECT (SELECT * FROM #foo WHERE id = 1) AS wtf; -- one record in results with value NULL
I'm not sure what else we could ask our sql engine to do for us - perhaps cough up an error and say I can't do this? Maybe return no results? We are telling it to select an empty result set as a value in the SELECT clause, in a query that doesn't have any FROM clause (personally I would like SQL to cough up and error and say I can't do this ... but it's not my call).
I hope someone else can explain this better, more accurately or technically - or even just give a name to this behavior. But in a nutshell there it is.
tldr;
So your first query has SELECT clause with an IFNULL function in it that uses a subquery ... and otherwise is a SELECT without a FROM. So this is a little weird but does what you want, as shown above. On the other hand, your second query is "normal" sql that selects from a table, filters the results, and lets you know it found nothing -- which might not be what you want but I think actually makes more sense ;)
Footnote: my "sql" here is T-SQL, but I believe this simple example would work the same in MySQL. And for what it's worth, I believe Oracle (back when I learned it years ago) actually would cough up errors here and say you can't have a SELECT clause with no FROM.

How to avoid overwrite in query results when a where condition like: "in (23,24,22,23)"

I have one such sql:
select name from A where id in (23,24,22,23)
When I run it in Navicat, the result only have one result of 23.
My question is, how to keep the number and order of the query results remains the same as (23,24,22,23).
If you want to maintain the order of the result then use order by clause like
select name from A
where id in (23,24,22)
order by id;
Again, assuming that id is a primary key column in your table A then there will be only one row with id = 23. How do you expect the same row to get repeated automatically unless you make it explicit by using a UNION ALL
If you really really want to fetch the records like this, you can use field function to get 23,24,22 and order by this sort:
select name from A where id in (23,24,22) order by field(id, '23,24,22')
then use union all get another 23:
(select name from A where id in (23,24,22) order by field(id, '23,24,22'))
union all
select name from A where id = 23

Mysql order by not working properly

I am using simple order by clause to show products according to available quantity
Below is the query I am using:
SELECT * FROM productsinfo ORDER BY quantity desc
Query giving no error but sorting order is not correct.Anyone please tell me where I am wrong.
EDIT
Have checked my quentity clumn is varchar type.I am storing values in 1,215 10,456 format.
Might be your quantity column is varchar type so it's not sorting as numbers.Please check.
You need to cast it in integer type
Try below:
SELECT * FROM productsinfo ORDER BY CAST(quantity AS UNSIGNED ) desc
OR Use below trick.
SELECT * FROM productsinfo ORDER BY quantity+0 DESC
I think you define quantity as VarChar. Because if it's a Number (int, smallint, decimal,..) the order will be definitely correct.
SELECT *, CAST(quantity AS int) QuantityA
FROM productsinfo
ORDER BY QuantityA desc
You'll have to first remove the , from the value and turn the result into a number. Give this a try:
SELECT * FROM productsinfo
ORDER BY REPLACE(quantity, ',', '')+0 DESC
The exect answer is:-
for varchar data type it compares integert data from left to right that means it treat 100 less the the 11.
So thats why comparing and sorting on varchar data type for integer data is a bad choice.
Convert it to int using cast in a query or alter your table.

I need some help getting MySql to output some results using a subquery

I'm storing a list of numbers inside a table as a varchar(255) and want to use this list in another query's "IN() clause.
Here's what I mean:
Table Data:
CREATE TABLE IF NOT EXISTS `session_data` (
`visible_portf_ids` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `session_data` (`visible_portf_ids`) VALUES
('45,44,658,659,661,45,44,658,659,661')
I want to run a query like this to return a list of portfolio's "QUERY #1":
SELECT portfolio_hierarchy_id, account_id, name, leaf_node_portf_id
FROM portfolio_hierarchy
WHERE account_id = 1
AND leaf_node_portf_id IN
(
(SELECT visible_portf_ids
FROM session_data
WHERE username = 'ronedog')
)
ORDER BY name ASC
The result of the query above returns only 1 row, when there are a total of 3 that should have been returned.
If I run the subquery alone like this:
(SELECT visible_portf_ids
FROM session_data
WHERE username = 'ronedog')
it will return a list like this:
45,44,658,659,661,45,44,658,659,661
But, when I run Query #1 above, only one row of data, which is associated with the "visible_portf_ids" of "45" is returned.
If I replace the subquery with hard coded values like this:
SELECT portfolio_hierarchy_id, account_id, name, leaf_node_portf_id
FROM portfolio_hierarchy
WHERE account_id = 1
AND leaf_node_portf_id IN (45,44,658,659,661,45,44,658,659,661)
ORDER BY name ASC
then I get all 3 rows I'm expecting.
I'm guessing that MySql is returning the list as a string because its stored as a varchar() and so it stops processing after the first "visible_portf_ids" is found, which is "45", but I'm not really sure.
Anyone got any ideas how I can fix this?
Thanks in advance.
You should think about restructuring your tables storing each value in a new row, instead of concatenating them.
Until then, you can use the FIND_IN_SET() function:
AND FIND_IN_SET(leaf_node_portf_id,
(SELECT visible_portf_ids
FROM session_data
WHERE username = 'ronedog'
LIMIT 1)
) > 0
Unfortunately MySQL does not have a function to split a delimited string. Your IN argument is a single string with the result of your subquery. The reason it works when you hard-code it is that MySQL is parsing the values.
I suggest that you redesign your data base to store the visible ports list as separate rows in a separate table. Then you can retrieve them and use them in subqueries like you tried.

How to get the max value of a field without grouping in MySql

I have a query with many wheres and orders criterias. One of the fields of the select is 'price' (element price) but I would like to have also (in every row) the maximun price of all the selected elements.
I tried to include MAX aggregate function on select hoping that this will return desired value, but insetead of that, price and MAX(price) returns the same. Searching into MySql doc I found the reason:
If you use a group function in a
statement containing no GROUP BY
clause, it is equivalent to grouping
on all rows.
Is there a way to solve this problem?
Thanks in advance!
There's a similar question (but not resolving this): find max value without aggregate operator in mysql
You can do this:
SELECT
id,
price,
(SELECT MAX(price) FROM your_table) AS max_price
FROM your_table
I'm not sure why you'd want to return that value on every row though... I'd probably do this in two separate queries, or else use a UNION ALL:
SELECT id, price FROM your_table
UNION ALL
SELECT NULL, MAX(price) FROM your_table
Maybe you could use a stored procedure like so:
CREATE PROCEDURE QueryWithMax ([parameter list if necessary])
BEGIN
-- Obtain the maximum price
DECLARE x INT UNSIGNED; -- change datatype if appropriate
SET x = SELECT
MAX(price)
FROM
...
WHERE
...
;
-- Now do your query
SELECT
price,
[other columns],
x AS MaxPrice
FROM
...
WHERE
...
GROUP BY
...
;
END
I haven't tried this, but if you had a subquery that extracts the maximum price (so you get one row), and then do a cross join (cartesian product) with it. You should get something like what you want. I can't vouch for how fast this would be.