Sorting alphanumeric data - sql

Hi i want to sort alphanumeric data in ascending order .
data like this :
1mac , apple , dom , 007bind , pcworld , 8basic , nothing.
But here I want the result such as :
apple, dom ,nothing, pcworld , 007bind , 1mac , 8basic
can anyone tell me the sql query to show such result.
Any help will be appreciated.
Thanks In Advance..

SELECT your_field FROM your_table ORDER BY (your_field + 0 <> 0 OR your_field = '0') ASC, your_field + 0, your_field

You have to check if your database vendor supports such a collation and set the collation accordingly.
http://www.collation-charts.org
E.g. oracle has http://www.collation-charts.org/oracle10g/ora10g.CL8MSWIN1251.GENERIC_BASELETTER.html

Here's one way to do it:
select col from sometable where left(col, 1) < '0' or left(col, 1) > '9' order by col
union all
select col from sometable where left(col, 1) >= '0' and left(col, 1) <= '9' order by col

Related

How to include the code into a REPLACE function in oracle?

User #psaraj12 helped me with a ticket here about finding ascii character in a string in my DB with the following code:
with test (col) as (
select
'L.A.D'
from
dual
union all
select
'L.􀈉.D.'
from
dual
)
select
col,
case when max(ascii_of_one_character) >= 65535 then 'NOT OK' else 'OK' end result
from
(
select
col,
substr(col, column_value, 1) one_character,
ascii(
substr(col, column_value, 1)
) ascii_of_one_character
from
test cross
join table(
cast(
multiset(
select
level
from
dual connect by level <= length(col)
) as sys.odcinumberlist
)
)
)
group by
col
having max(ascii_of_one_character) >= 4000000000;
The script looks for characters of a certain range GROUPs them and marks displays them.
Is it possible to include this in a REPLACE statement of a similar sort:
REPLACE(table.column, max(ascii_of_one_character) >= 4000000000, '')
EDIT: As per #flyaround answer this is the code I use changed a little bit:
with test (col) as (
select skunden.name1
from skunden
)
select col
, REGEXP_REPLACE(col, 'max(ascii_of_one_character)>=4000000000', '') as cleaned
, CASE WHEN REGEXP_COUNT(col, 'max(ascii_of_one_character)>=4000000000') > 0 THEN 0 ELSE 1 END as isOk
from test;
Coming back to your original code, because my suggested REGEX_REPLACE is not working sufficient with high surrogates. Your approach is already very effective, so I jumped into it to have a solution here.
MERGE
INTO skunden
USING (
select
id as innerId,
name as innerName,
case when max(ascii_of_one_character) >= 65535 then 0 else 1 end isOk,
listagg(case when ascii_of_one_character <65535 then one_character end , '') within group (order by rn) as cleaned
from
(
select
id,
name,
substr(name, column_value, 1) one_character,
ascii(
substr(name, column_value, 1)
) ascii_of_one_character
, rownum as rn
from
skunden cross
join table(
cast(
multiset(
select
level
from
dual connect by level <= length(name)
) as sys.odcinumberlist
)
)
)
group by
id, name
having max(ascii_of_one_character) >= 4000000000
)
ON (skunden.id = innerId)
WHEN MATCHED THEN
UPDATE
SET name = cleaned
;
On MERGE you can't use the referencing column for an update. Therefore you should use the unique key (I used 'id' in my example) of your table.
The resulting value will be 'L..D' for your example value of 'L.􀈉.D.'
If I got your question correctly you would like to remove characters with a higher decimal representation of characters than specified.
You could check to use REGEXP_REPLACE for this, like:
with test (col) as (
select
'L.A.D'
from
dual
union all
select
'L.􀈉.D.'
from
dual
)
select col
, REGEXP_REPLACE(col, '[^\u00010000-\u0010FFFF]+$', '') as cleaned
, CASE WHEN REGEXP_COUNT(col, '[^\u00010000-\u0010FFFF]+$') > 0 THEN 0 ELSE 1 END as isOk
from test;

SQL - Reverse Part of Column

I want to reverse part of column. Ex;
SELECT Column FROM Table ORDER BY Column ASC
Output:
Column
------
Kaan001
Kaan002
Kaan003
Turan001
Turan002
If I use DESC instead of ASC;
Column
------
Turan002
Turan001
Kaan003
Kaan002
Kaan001
But I want this;
Column
------
Turan001
Turan002
Kaan001
Kaan002
Kaan003
Is it possible or not? Please Help me... Thank you..
You can use:
order by left(columnname, len(columnname) - 3) desc,
right(columnname, 3)
You are required to use DESC. It will return the result by the mentioned column in the descending order.
SELECT ColumnName FROM TableName ORDER BY ColumnName DESC
If you are not explicitly mentioned the Column's ORDER BY it will consider as ASC (ascending order) by default.
Demo on db<>fiddle
As per your edited question, the following query will work using PATINDEX
SELECT ColumnName
FROM TableName
ORDER BY LEFT(ColumnName, PATINDEX('%[0-9]%', ColumnName) - 1) DESC,
RIGHT(ColumnName, LEN(ColumnName) - PATINDEX('%[0-9]%', ColumnName) + 1) ASC
Updated db<>fiddle demo
You can try the below query.
create table #temp (
id int identity(1,1),
testCol Varchar(20)
)
insert into #temp values ('Turan002'),('Turan001'),('Kaan003'),('Kaan002'),('Kaan001')
SELECT
* from
#temp order by RTRIM(SUBSTRING( testCol , 1 , CHARINDEX( '0' , testCol) - 1)) desc,
RTRIM(SUBSTRING( testCol , CHARINDEX( '0' , testCol ), LEN( testCol) - (CHARINDEX( '0' , testCol) - 1))) asc
drop table #temp
You can find the demo Here.
From my understanding,
select * from (
values
('Kaan001')
,('Kaan002')
,('Kaan003')
,('Turan001')
,('Turan002')
) d (val)
order by left (val, PATINDEX ('%[0-9]%', val) - 1) desc
, right (val, PATINDEX ('%[0-9]%', val)) -- Here, Patindex returns the first appearance of integer.

Add some numbers in front of a column

I have a column in SQL server and I want to add 7 for the words which begin by a and add 8 for the words which begin by t.
Here is my column:
add-on
above
tv
their
french
And I want this:
7add-on
7above
8tv
8their
french
I am looking for a query which could do that.
Thank you very much!
You can use left() & do the concatenation :
select t.*,
(case left(col, 1)
when 'a' then concat(7, col)
when 't' then concat(8, col)
else col
end)
from table t;
Use a case expression with substring to get the results you require.
select concat(
(case when substring(col,1,1)='a' then '7'
when substring(col,1,1)='t' then '8'
end
)
,col
) as modified_col
from table
You need 2 update queries. Try like:
UPDATE myTable SET myColumn='7'+myColumn WHERE myColumn LIKE 'a%';
UPDATE myTable SET myColumn='8'+myColumn WHERE myColumn LIKE 't%'
Use CASE statement to check the first char, returned by SUBSTRING function, and calculate a prefix to add to your data:
select
case substring(column, 1, 1)
when 'a' then '7'
when 't' then '8' else '' end + column as NewColumn
from table
In sql server 2008 :
select
case when substring(column,1,1)='a' then ( '7 ' + column)
case when substring(column,1,1)='t' then ( '8 ' + column)
else column end as column from table
In sql server 2012 or above :
select
case when substring(column,1,1)='a' then concat( '7 ',column)
case when substring(column,1,1)='t' then concat( '8 ',column)
else column end as column from table

Replace last character in sql column

I have data in table this way. If the ; is at the end I would like that replaced with a blank string if not I would leave data same way.
abc;
123;ghi;789
test123;
thisowns;
wer;567;457;test
Result should be
abc
123;ghi;789
test123
thisowns
wer;567;457;test
Try this:
UPDATE <YOUR_TABLE>
SET col1 = LEFT(col1, LEN(col1) - 1)
WHERE RIGHT(col1, 1) = ';'
Hope this help!
You can do:
select (case when col like '%;' then left(col, len(col) - 1) else col end)
You can use RIGHT() function like
case when RIGHT(col1, 1) = ';' then LEFT(col1, LEN(col1) - 1) end
Hope this helps.
;WITH cte_TestData (String)
AS
(
SELECT 'abc;' UNION ALL
SELECT '123;ghi;789' UNION ALL
SELECT 'test123;' UNION ALL
SELECT 'thisowns;' UNION ALL
SELECT 'wer;567;457;test'
)
SELECT CASE
WHEN RIGHT(String, 1) = ';'
AND LEN(String) >= 1
THEN SUBSTRING(String, 1, LEN(String) - 1)
ELSE String
END
FROM cte_TestData

Split string and take last element

I have a table with this values:
Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx
OurStory/MeettheFoodieandtheMD.aspx
TheFood/OurMenu.aspx
I want to get this
Diet.aspx
MeettheFoodieandtheMD.aspx
OurMenu.aspx
How can i do this?
The way to do it in SQL :
SELECT SUBSTRING( string , LEN(string) - CHARINDEX('/',REVERSE(string)) + 2 , LEN(string) ) FROM SAMPLE;
JSFiddle here http://sqlfiddle.com/#!3/41ead/11
SELECT REVERSE(LEFT(REVERSE(columnName), CHARINDEX('/', REVERSE(columnName)) - 1))
FROM tableName
SQLFiddle Demo
ORHER SOURCE(s)
REVERSE
LEFT
CHARINDEX
Please try:
select url,(CASE WHEN CHARINDEX('/', url, 1)=0 THEN url ELSE RIGHT(url, CHARINDEX('/', REVERSE(url)) - 1) END)
from(
select 'Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx' as url union
select 'OurStory/MeettheFoodieandtheMD.aspx' as url union
select 'MeettheFoodieandtheMD.aspx' as url
)xx
Try this. It's easier.
SELECT RIGHT(string, CHARINDEX('/', REVERSE(string)) -1) FROM TableName
SELECT REVERSE ((
SELECT TOP 1 value FROM STRING_SPLIT(REVERSE('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/')
)) AS fName
Result: Diet.aspx
Standard STRING_SPLIT does not allow to take last value.
The trick is to reverse the string (REVERSE) before splitting with STRING_SPLIT, get the first value from the end (TOP 1 value) and then the result needs to be reversed again (REVERSE) to restore the original chars sequence.
Here is the common approach, when working with SQL table:
SELECT REVERSE ((
SELECT TOP 1 VALUE FROM STRING_SPLIT(REVERSE(mySearchString), '/')
)) AS myLastValue
FROM myTable
A slightly more compact way of doing this (similar to ktaria's answer but in SQL Server) would be
SELECT TOP 1 REVERSE(value) FROM STRING_SPLIT(REVERSE(fullPath), '/') AS fileName
The equivalent for PostgreSQL:
SELECT reverse(split_part(reverse(column_name), '/', 1));
Please try the code below:
SELECT SUBSTRING( attachment, LEN(attachment)
- CHARINDEX('/', REVERSE(attachment)) + 2, LEN(attachment) ) AS filename
FROM filestable;
more simple and elegant :
select reverse(SPLIT_PART(reverse('Articles/Search/ArtMID/2681/ArticleID/2218/Diet.aspx'), '/',1))
You can try this too
( SELECT TOP(1) value
FROM STRING_SPLIT(#string, '/')
ORDER BY CHARINDEX('/' + value + '/', '/' + #string+ '-') DESC)
I corrected jazzytomato's solution for single character tokens (D) and for single tokens (Diet.aspx)
SELECT SUBSTRING( string , LEN(string) - CHARINDEX('/','/'+REVERSE(string)) + 2 , LEN(string) ) FROM SAMPLE;
The easiest way in MySQL:
SELECT SUBSTRING_INDEX(string, '/', -1) FROM SAMPLE;
I have more simple solve
SELECT SUBSTRING_INDEX(string, 'SUBSTRING_INDEX(string, '/', -1)', 1) FROM SAMPLE;
reverse(SUBSTRING(reverse(yourString),0,CHARINDEX('/',reverse(yourString)))) as stringLastPart
Create Table #temp
(
ID int identity(1,1) not null,
value varchar(100) not null
)
DECLARE #fileName VARCHAR(100);
INSERT INTO #temp(value) SELECT value from STRING_SPLIT('C:\Users\Documents\Datavalidation\Input.csv','\')
SET #fileName=(SELECT TOP 1 value from #temp ORDER BY ID DESC);
SELECT #fileName AS File_Name;
DROP TABLE #temp