This SQL 'ORDER BY' is not working properly - sql

SELECT test_column FROM test_table ORDER BY test_column gives me this:
1
12
123
2
3
Why not:
1
2
3
12
123
How can I sort strings like numbers?

Try
SELECT test_column
FROM test_table
ORDER BY cast(test_column as int)
But you should look into changing the column types to the correct ones.

This worked for me:
ORDER BY cast(test_column as SIGNED)
here, cast function convert value from string to integer(SIGNED) then it applied ORDER BY. https://dev.mysql.com/doc/refman/8.0/en/cast-functions.html

The sort is working. It's a lexicographic sort (alphabetical). It appears that that column has a text (char, varchar, ...) type, so the ordering you'll get is textual and not numeric.
If you want a numerical sort, use a numeric column type (e.g. int). (Or cast the column appropriately.)

Check if the type of the column is varchar or something similar. It looks like it is being ordered by string value, not by numeric value. If the column only contains numbers it should better be of type int.

I think , we need to do the cast as part of the select statement , because if we use distinct then casting in the order by statement does not work:
SELECT cast(test_column as int) as test_column
FROM test_table
ORDER BY test_column
and
SELECT DISTINCT cast(test_column as int) as test_column
FROM test_table
ORDER BY test_column

Related

Get maximum value in a column in sql query if the column is alphanumeric

This is the table which I have by name project and it contains 3 columns:
estimateId
name
projectName
I want to fetch data from SQL database based on maximum value of estimateId
but here estimateid is alphanumeric. How can I achieve this.
I need a SQL query to achieve this:
For example estimateId contains values like:
Elooo1
Elooo2
......
Elooo10
and so on. So how can I achieve this?
Setup Testing Data
DECLARE #tmpTable TABLE ( estimateId NVARCHAR(MAX));
INSERT into #tmpTable(estimateId) VALUES ('Elooo1'),('Elooo2'),('Elooo3'),('Elooo4'),('Elooo5'),('Elooo6');
Split data based on the pattern
SELECT T.prefix AS prefix, MAX(T.suffix) AS suffix, MAX(estimateId) AS estimateId FROM (SELECT estimateId,LEFT(estimateId, PATINDEX('%[a-zA-Z][^a-zA-Z]%', estimateId )) AS prefix,LTRIM(RIGHT(estimateId, LEN(estimateId) - PATINDEX('%[a-zA-Z][^a-zA-Z]%', estimateId ))) As suffix FROM #tmpTable) T GROUP BY T.prefix
Result
prefix suffix estimateId
Elooo 6 Elooo6
Reference
split alpha and numeric using sql
I just started SQL like today.. so i'm totally a newbie, but I think I could solve your problem. I would do something like this
SELECT name, projectName FROM table ORDER BY estimateId ASC
or (I think you will need ORDER BY ... DESC)
SELECT name, projectName FROM table ORDER BY estimateId DESC
You seem to be looking to extract the numeric part of the strings. Assuming that the strings have variable length, and that the numbers are always at the end, you can do:
try_cast(
substring(estimateId, patindex('%[0-9]%', estimateId), len(estimateId))
as int
)
This captures everything from the the first number in the string to the end of the string, and attempts to convert it to a number (if the conversion fails, try_cast() returns null rather than raising an error).
It is not very clear what you want to use this information for. For example, if you wanted to sort your data accordingly, you would do:
select *
from mytable
order by try_cast(
substring(estimateId, patindex('%[0-9]%', estimateId), len(estimateId))
as int
)

Finding max value for a column containing hierarchical decimals

I have a table where the column values are like '1.2.4.5', '3.11.0.6',
'3.9.3.14','1.4.5.6.7', N/A, etc.. I want to find the max of that particular column. However when i use this query i am not getting the max value.
(SELECT max (CASE WHEN mycolumn = 'N/A'
THEN '-1000'
ELSE mycolumn
END )
FROM mytable
WHERE column like 'abc')
I am getting 3.9.3.14 as max value instead of 3.11....
Can someone help me?
Those aren't really decimals - they're strings containing multiple dots, so it's unhelpful to think of them as being "decimals".
We can accomplish your query with a bit of manipulation. There is a type build into SQL Server that more naturally represents this type of structure - hierarchyid. If we convert your values to this type then we can find the MAX fairly easily:
declare #t table (val varchar(93) not null)
insert into #t(val) values
('1.2.4.5'),
('3.11.0.6'),
('3.9.3.14'),
('1.4.5.6.7')
select MAX(CONVERT(hierarchyid,'/' + REPLACE(val,'.','/') + '/')).ToString()
from #t
Result:
/3/11/0/6/
I leave the exercise of fully converting this string representation back into the original form as an exercise for the reader. Alternatively, I'd suggest that you may want to start storing your data using this datatype anyway.
MAX() on values stored as text performs an alphabetic sort.
Use FIRST_VALUE and HIERARCHYID:
SELECT DISTINCT FIRST_VALUE(t.mycolumn) OVER(
ORDER BY CONVERT(HIERARCHYID, '/' + REPLACE(NULLIF(t.mycolumn,'N/A'), '.', '/') + '/') DESC) AS [Max]
FROM #mytable t

select max of mixed string/int column

I have a table who returns me a value as bellow
id_unique name serie timeB timeD
155488EA-FF70-49D7-99AB-AFD4125F3435 dell 14296188 05:51 06:19
1B640883-0DB6-4255-B1ED-770B6578064C dell 14295943 04:37 04:39
I want the max of the value i have tried a sql as bellow :
select max(cast(id_unique as varchar(36))),
max(name),max(serie),max(timeB),max(timeD) from mytable group by name
i got this result
1B640883-0DB6-4255-B1ED-770B6578064C dell 14296188 05:51 06:19
But the result that i need is this one :
155488EA-FF70-49D7-99AB-AFD4125F3435 dell 14296188 05:51 06:19
This any metho to fix that ?
My guess is that you want something like this using row_number:
select *
from (
select *, row_number() over (order by somevalue desc) rn
from yourtable
) t
where rn = 1
Where somevalue is the column you need the max of. I presume you are currently trying to use max for every field -- that would explain your output...
If these are really stored as strings, I'm guessing that you want to cast the first column as a uniqueidentifier before finding the max, otherwise they will be evaluated alphabetically.
SQL Server 2012 and above
You can directly get the min/max of uniqueidentifiers:
select max(cast(id_unique as uniqueidentifier))
from MyTable
Previous Versions
You should cast as binary(16) before finding the min/max. I'm then casting back to uniqueidentifier for readability of the results:
select cast(max(cast(cast(id_unique as uniqueidentifier) as binary(16))) as uniqueidentifier)
from MyTable

Some rows of Order by column is null. How to make Order by column optional on that situation

I have a prob in following Select query.
select *
from ".$table2." a,purpose_details b
where b.purpose_code=a.purpose and purpose_code in(1,4,6,7,10)
and ((fromdt<='$frmdate'and todt>='$frmdate')
or (fromdt<='$frmdate' and todt='1111-11-11'))
and substr(a.appno,4,1)!=6
order by purpose_priority,
cast(substr(a.case_no,12,4) as int) ,cast(substr(a.case_no,4,1) as int),
cast(substr(a.case_no,5,7) as int),cast(substr(a.appno,12,4) as int) ,
cast(substr(a.appno,4,1) as int),cast(substr(a.appno,5,7) as int)";
the problem is the rows in the table2 may or may not have value of appno. (ie) appno value may be NULL for some of rows.
Due to appno is one among in the order by column this particular code retuns invalid input error.
Finally What i want is the select query arrange the columns by appno only when the appno value is not null.
Note: The order by clause for the rest of the columns should be applied on both situations.
Pls help me to sort it out. Thanks in Advance.
Order by can definitly handle null values but substr cannot.
You should replace your
Substr (col, ...
With
Case when col is null then null else substr (col, ...

Check if field is numeric, then execute comparison on only those field in one statement?

This may be simple, but I am no SQL whiz so I am getting lost. I understand that sql takes your query and executes it in a certain order, which I believe is why this query does not work:
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1
and cast(purchase_order_number as int) >= 7
MOST of the purchar_order_number fields are numeric, but we introduce alphanumeric ones recently. The data I am trying to get is to see if '7' is greater than the highest numeric purchase_order_number.
The Numeric() function filters out the alphanumeric fields fine, but doing the subsequent cast comparison throws this error:
Conversion failed when converting the nvarchar value '124-4356AB' to data type int.
I am not asking what the error means, that is obvious. I am asking if there is a way to accomplish what I want in a single query, preferably in the where clause due to ORM constraints.
does this work for you?
select * from purchaseorders
where (case when IsNumeric(purchase_order_number) = 1
then cast(purchase_order_number as int)
else 0 end) >= 7
You can do a select with a subselect
select * from (
select * from purchaseorders
where IsNumeric(purchase_order_number) = 1) as correct_orders
where cast(purchase_order_number as int) >= 7
try this:
select * from purchaseorders
where try_cast(purchase_order_number as int) >= 7
have to check which column has numeric values only.
Currently, in a table every field is setted with nvarchar(max) Like tableName (field1 nvarchar(max),field2 nvarchar(max),field3 nvarchar(3)) and tableName has 25lac Rows.
But on manually Check Field2 Contain the numeric Values Only... How to Check With t-sql that in the Complete Column (Field2) has numeric Value or not/null value with Longest Length in the Column!