Price with , in VARCHAR to DECIMAL - mysql

In my SQL database I have the prices in VARCHAR but I've problem when I try to order by price..
I have try to use this query but doesn't work..!
CAST(price AS DECIMAL) DESC
If I launch this query the result order is:
1.123,45
122,00
2.543,21
656,00
etc

Use a replace to create a decimal point, then cast it with the precision and scale...
cast(replace(Price, ',', '.') as decimal(9,2))

you can use the direct "convert" in order by
ORDER BY convert( [name column], decimal)

I have find the problem.. The numbers > of 999,99 ha the . under the miles..
For example:
1.000,00
I have replaced all . with this query:
UPDATE computers SET prezzo = REPLACE(prezzo, '.', '')

Create a one example as per bolow:
Create a table
create table table1(
id integer,
price varchar(20)
)
Insert record price into varchar:
insert into table1 values(1, '10.1');
insert into table1 values(1, '100.1');
insert into table1 values(1, '20.1');
insert into table1 values(1, '200.1');
Sorting on varchar price as per numeric field:
SELECT * FROM `table1` order by cast(replace(price, ',', '.') as decimal(9,2))

I think that if your commas are thousands separators then you need to replace them with empty strings. If your commas are decimal separators then you need to replace them with decimal points.
Try this if your commas are thousands separators:
SELECT
price
FROM
prices
ORDER BY
CAST(REPLACE(price,',','') AS DECIMAL)
This should give you:
price
543,21
123,45
1,001
6,00
2,00
If your commas are decimal separators then this:
SELECT
price
FROM
prices
ORDER BY
CAST(REPLACE(price,',','.') AS DECIMAL)
Will give you:
price
543,21
123,45
6,00
2,00
1,001

Check This.
select * ,REPLACE( price, ',', '' ) from money
order by CAST(REPLACE(price,',','') AS DECIMAL)
Check Demo Here : Link

Related

Substring regex matching in mysql

I've one complex question that been struggle me for couple hours and seeking help from mysql expert. :)
Thank you in advanced.
Table : t1 ; Column: name
Given table:
name
-----
$abc|def|$cde
efd|$acd
$gcb|$bvv|ggg
Expected outcome (pull only the string without $ prefix, pipe indicates the field values separator):
name
-----
def
efd
ggg
-- Sql to create and insert
create table t1 (name varchar(100));
insert into t1 (name) values ('$abc|def|$cde');
insert into t1 (name) values ('efd|$acd');
insert into t1 (name) values ('$gcb|$bvv|ggg');
Mysql version: 5.6.40
SELECT DISTINCT
name, SUBSTRING_INDEX(SUBSTRING_INDEX(t1.name, '|', num), '|', -1) one_value
FROM t1
/* max 3 subnames per name - expand if needed */
CROSS JOIN (SELECT 1 num UNION SELECT 2 UNION SELECT 3) numbers
HAVING one_value NOT LIKE '$%';
fiddle
On MySQL 8+, you could try:
SELECT
col,
REGEXP_REPLACE(CONCAT('|', col, '|'), '^.*\\|([a-z]+)\\|.*$', '$1') AS col_out
FROM yourTable;
The idea here is to start with this slightly modified column value:
|$abc|def|$cde|
Then, we search for a letter-only sequence surrounded by pipes, and replace with that captured group.
Demo

How to sort the string on the basis of numbers?

I am working on the sql query in which I want to sort the string on the basis of numbers.
I have one column (Column Name is Name) table in which there are multiple fields. On using ORDER BY NAME, it prints in the following way:
hello_world
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
hello_world4
hello_world5
For the above query, I have used ORDER BY NAME; but it doesn't seem to print on the basis of numbers.
Problem Statement:
I am wondering what sql query I need to write or what changes I need to make in my sql query above so that it prints everything on the basis of numbers, the o/p should be this:
hello_world
hello_world4
hello_world5
hello_world10
hello_world11
hello_world12
hello_world13
hello_world14
hello_world15
you want a numeric ordering, then you need to create a numeric value to order on.
currently you have strings.
if the pattern is true, then you can use a combination of string manipulation to trim off the first characters, which should leave only numbers, then use TO_NUMBER() to convert for the ordering
something like
select name
from mytable
order by to_number( replace( name, 'hello_world','' ))
I think the simplest solution for this particular case (where all the values have the same prefix) is:
order by length(name), name
Try this:
SELECT name,
CASE WHEN REGEXP_INSTR(name, '[0-9]') = 0 THEN 0
ELSE CAST(SUBSTR(name, REGEXP_INSTR(name, '[0-9]')) AS INT)
END AS progressive
FROM my_table
ORDER BY progressive;
we can order it using replace and cast methods.
I tried the following query
select Name, cast(REPLACE(Name, 'hello_world', '') as UNSIGNED ) as repl from Users order by repl;
To generage sample data
CREATE TABLE Users (
Name varchar(255) NOT NULL
);
insert into Users(Name) values
('hello_world'),
('hello_world4'),
('hello_world5'),
('hello_world10'),
('hello_world11'),
('hello_world12'),
('hello_world13'),
('hello_world14'),
('hello_world15')
;
EDIT
query without replaced column,
select City from Persons order by cast(REPLACE(City, 'hello_world', '') as UNSIGNED );
Though the question is about mysql.
I tried in sql server.
create table #t1 (id varchar(100));
insert into #t1 (id) values ('Pq1'),('pq3'),('pq2')
select * from #t
order by
CAST(SUBSTRING(id + '0', PATINDEX('%[0-9]%', id + '0'), LEN(id + '0')) AS INT)

Grab a number in between a varchar in SQL

I am trying to grab a number by using SQL query. I need to grab the number before it says 'LEADS'
Sample of entry I might encounter:
PDIP300MIL-14LEADS
QFN6X6-40LEADS
QFN6X6-240LEADS
WSOIC/16LEADS
So as you can see the prefix can be any length. Also sometimes the delimeter is / or -. But it is fix that the suffix is LEADS.
On a sidenote. Other entries are like ICL7665 BCSA so it has no leads so it has to be skipped.
Edit: I am very sorry if I am not that clear. The one I am trying to grab is the number between the delimeter and Leads.
So in the four examples I am trying to grab: 14, 40, 240, 16.
You can do something like using substring_index
select
substring_index(
substring_index(
replace(col,'/','-')
,'LEADS'
,1),
'-'
,-1
)
from table1
DEMO
To skip entries you can filter result by using having clause
select
substring_index(
substring_index(
replace(col,'/','-')
,'LEADS'
,1),
'-'
,-1
) num
from table1
having num * 1 > 0
DEMO 2
https://dev.mysql.com/doc/refman/5.1/en/regexp.html
SELECT * FROM table WHERE field REGEXP '[0-9]+LEADS$'

MySQL: Using sum on a varchar with comma?

I have a column, called net_amount, it contains values like 244,98. Its a varchar column. When I try to sum it using the sum function, it only sums the 244 and skipts the decimal places. I tried casting it to decimal like this:
select cast(net_amount as decimal) from mytable
This skips the decimal places as well ... any idea what might be wrong?
Thanks!
You could use REPLACE to replace comma to dot:
SELECT REPLACE('244,98', ',', '.') * 1
or you can use CAST like this:
cast(REPLACE(net_amount, ',', '.') as decimal(8,2))

Checking for doubled entries in value separated by commas?

Is there a way to get a value like this one: "300, 400, 500, 300" check each number separated with comma and if it is doubled delete it. So the value will look like this : "300, 400, 500".
I could do it in PHP script but I just wonder if it is possible using MySQL.
Create a temp table with unique index, insert values ignoring duplicate errors, select all records from the temp table, delete the table.
Quick play, but to get the unique values for each row you could use something like this
SELECT Id, GROUP_CONCAT(DISTINCT aWord ORDER BY aWord ASC)
FROM (SomeTable.Id, SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(concat(SomeColumn, ','), ' ', aCnt), ',', -1) AS aWord
FROM SomeTable
CROSS JOIN (
SELECT a.i+b.i*10+c.i*100 + 1 AS aCnt
FROM integers a, integers b, integers c) Sub1
WHERE (LENGTH(SomeColumn) + 1 - LENGTH(REPLACE(SomeColumn, ',', ''))) >= aCnt) Sub2
GROUP BY ID
This relies on having a table called integers with a single column called i with 10 rows with the values 0 to 9. It copes with up to ~1000 words but can easily be altered to cope with more
Probably easiest to use an INSERT / ON DUPLICATE KEY UPDATE to use this to make the values unique.