How to get first n numbers from float - sql

I have table A with two columns id(int) and f_value(float). Now I'd like to select all rows where f_value starts from '123'. So for the following table:
id | f_value
------------
1 | 12
2 | 123
3 | 1234
I'd like to get the second and third row. I tried to use LEFT with cast but that was a disaster. For the following query:
select f_value, str(f_value) as_string, LEFT(str(f_value), 2) left_2,
LEFT(floor(f_value), 5) flor_5, LEFT('abcdef', 5) test
from A
I got:
f_value | as_string | left_2 | flor_5 | test
------------------------------------------------
40456510 | 40456510 | | 4.045 | abcde
40454010 | 40454010 | | 4.045 | abcde
404020 | 404020 | | 40402 | abcde
40452080 | 40452080 | | 4.045 | abcde
101020 | 101020 | | 10102 | abcde
404020 | 404020 | | 40402 | abcde
The question is why left works fine for 'test' but for other returns such weird results?
EDIT:
I made another test I now I'm even more confused. For query:
Declare #f as float
set #f = 40456510.
select LEFT(cast(#f as float), LEN(4045.)), LEFT(404565., LEN(4045.))
I got:
|
------------
4.04 | 4045
Is there a default cast which causes this?
Fiddle SQL

Seems like your query is a bit wrong. The LEFT part should go in the WHERE-Clause, not the SELECT-part.
Also, just use LIKE and you should be fine:
SELECT f_value, str(f_value) as_string, LEFT(str(f_value), 2) left_2,
LEFT(floor(f_value), 5) flor_5
WHERE f_value LIKE '123%'

CREATE TABLE #TestTable(ID INT, f_value FLOAT)
INSERT INTO #TestTable
VALUES (1,22),
(2,123),
(3,1234)
SELECT *
FROM #TestTable
WHERE LEFT(f_value,3)='123'
DROP TABLE #TestTable
I hope this will help.

The replace get rid of the period in the float, by multiplying by 1 any 0 in front will be removed.
SELECT f_value
FROM your_table
WHERE replace(f_value, '.', '') * 1 like '123%'

I found the solution. The problem was that SQL Server uses the exponential representation of floats. To resolve it you need to first convert float to BigInt and then use Left on it.
Example:
Select * from A where Left(Cast(float_value as BigInt), 4) = xxxx

/*
returns significant digits from #f (a float) as an integer
negative sign is stripped off
*/
declare #num_digits int = 3; /* needs to be positive; accuracy diminishes with larger values */
with samples(num, f) as (
select 1, cast(123.45 as float) union
select 2, 123456700 union
select 3, -1.234567 union
select 4, 0.0000001234
)
select num, f,
case when f = 0 or #num_digits < 1 then 0 else
floor(
case sign(log10(abs(f)))
when -1 then abs(f) * power(10e0, -floor(log10(abs(f))) + #num_digits - 1)
when 1 then abs(f) / power(10e0, ceiling(log10(abs(f))) - #num_digits)
end
)
end as significant_digits
from samples
order by num;
sqlfiddle

Convert the FLOAT value to DECIMAL then to VARCHAR using CAST AND use LIKE to select the value starting with 4045.
Query
SELECT * FROM tbl
WHERE CAST(CAST(f_value AS DECIMAL(20,12)) AS VARCHAR(MAX)) LIKE '4045%';
Fiddle demo for reference

Related

Replace values in a column for all rows

I have a column with entries like:
column:
156781
234762
780417
and would like to have the following:
column:
0000156781
0000234762
0000780417
For this I use the following query:
Select isnull(replicate('0', 10 - len(column)),'') + rtrim(column) as a from table)
However, I don't know how to replace the values in the whole column.
I already tried with:
UPDATE table
SET column= (
Select isnull(replicate('0', 10 - len(column)),'') + rtrim(column) as columnfrom table)
But I get the following error.
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The answer to your question is going to depend on the data type of your column. If it is a text column for example VARCHAR then you can modify the value in the table. If it is a number type such as INT it is the value and not the characters which is stored.
We can also express this by saying that "0" + "1" = "01" whilst 0 + 1 = 1.
In either case we can format the value in a query.
create table numberz(
val1 int,
val2 varchar(10));
insert into numberz values
(156781,'156781'),
(234762,'234762'),
(780417,'780417');
/* required format
0000156781
0000234762
0000780417
*/
select * from numberz;
GO
val1 | val2
-----: | :-----
156781 | 156781
234762 | 234762
780417 | 780417
UPDATE numberz
SET val1 = isnull(
replicate('0',
10 - len(val1)),'')
+ rtrim(val1),
val2 = isnull(
replicate('0',
10 - len(val2)),'')
+ rtrim(val2);
GO
3 rows affected
select * from numberz;
GO
val1 | val2
-----: | :---------
156781 | 0000156781
234762 | 0000234762
780417 | 0000780417
select isnull(
replicate('0',
10 - len(val1)),'')
+ rtrim(val1)
from numberz
GO
| (No column name) |
| :--------------- |
| 0000156781 |
| 0000234762 |
| 0000780417 |
db<>fiddle here
Usually, when we need to show values in specificity format these processes are performed using the CASE command or with other functions on the selection field list, mean without updating. In such cases, we can change our format to any format and anytime with changing functions. As dynamic fields.
For example:
select id, lpad(id::text, 6, '0') as format_id from test.test_table1
order by id
Result:
id format_id
-------------
1 000001
2 000002
3 000003
4 000004
5 000005
Maybe you really need an UPDATE, so I wrote a sample query for an UPDATE command too.
update test.test_table1
set
id = lpad(id::text, 6, '0');

How to convert string to number based on units

I am trying to change the following strings into their respective numerical values, by identifying the units (millions or billions) and then multiplying accordingly. I believe I am having issues with the variable types but can't seem to find a solution. Any tips?
1.44B to 1,440,000,000
1.564M to 1,564,000
UPDATE [_ParsedXML_Key_Stats]
SET [Value] = CASE
WHEN right(rtrim([_ParsedXML_Key_Stats].[Value]),1) = 'B' And [_ParsedXML_Key_Stats].[NodeName] = 'EBITDA'
THEN substring(rtrim([_ParsedXML_Key_Stats].[Value]),1,len([_ParsedXML_Key_Stats].[Value])-1) * 1000000000
WHEN right(rtrim([_ParsedXML_Key_Stats].[Value]),1) = 'M' And [_ParsedXML_Key_Stats].[NodeName] = 'EBITDA'
THEN substring(rtrim([_ParsedXML_Key_Stats].[Value]),1,len([_ParsedXML_Key_Stats].[Value])-1) * 1000000
ELSE 0
END
With your original query I got a conversion error as the multiplication was treating the decimal value as an int, I guess you might have experienced the same problem.
One remedy that fixed it was to turn the factor into a decimal by adding .0 to it.
If you want to get the number formatted with commas you can use format function like so: FORMAT(CAST(value AS DECIMAL), 'N0') (be sure to specify appropriate length and precision for the decimal type).
Sample test data and output from SQL Fiddle below:
SQL Fiddle
MS SQL Server 2014 Schema Setup:
CREATE TABLE [_ParsedXML_Key_Stats] (value VARCHAR(50), NodeName VARCHAR(50));
INSERT [_ParsedXML_Key_Stats] VALUES
('111', 'SOMETHING ELSE'),
('999', 'EBITDA'),
('47.13B', 'EBITDA'),
('1.44B', 'EBITDA'),
('1.564M', 'EBITDA');
WITH cte AS
(
SELECT
Value,
CAST(LEFT([Value],LEN([Value])-1) AS DECIMAL(28,6)) AS newValue,
RIGHT(RTRIM([Value]),1) AS c
FROM [_ParsedXML_Key_Stats]
WHERE [NodeName] = 'EBITDA'
AND RIGHT(RTRIM([Value]),1) IN ('B','M')
)
UPDATE cte
SET [Value] =
CASE
WHEN c = 'B' THEN newValue * 1000000000.0
WHEN c = 'M' THEN newValue * 1000000.0
END;
Query 1:
SELECT *, FORMAT(CAST(Value AS DECIMAL(18,0)),'N0') AS formattedValue
FROM _ParsedXML_Key_Stats
Results:
| value | NodeName | formattedValue |
|--------------------|----------------|----------------|
| 111 | SOMETHING ELSE | 111 |
| 999 | EBITDA | 999 |
| 47130000000.000000 | EBITDA | 47,130,000,000 |
| 1440000000.000000 | EBITDA | 1,440,000,000 |
| 1564000.000000 | EBITDA | 1,564,000 |

I have single row should convert into columns

Please tell how to display them like
|NumberOfQuotesGenerated | 11 |
TotalAmountOfQuotes | 78100 |
NumberOfInvoiceGenerated | 9 |
TotalAmountOfInvoice | 8222
Thank you in advance
you can try Unpivot syntax like below
-- create table t(NumberOfQuotesGenerated int,TotalAmountOfQuotes int,NumberOfInvoiceGenerated int, TotalAmountOfInvoice int)
-- insert into t values (11, 78100, 9, 8222)
select * from
(select * from t) s
unpivot
(
data for
colname in
([NumberOfQuotesGenerated],[TotalAmountOfQuotes],[NumberOfInvoiceGenerated],[TotalAmountOfInvoice])
)up
Live SQL demo

Search an SQL table that already contains wildcards?

I have a table that contains patters for phone numbers, where x can match any digit.
+----+--------------+----------------------+
| ID | phone_number | phone_number_type_id |
+----+--------------+----------------------+
| 1 | 1234x000x | 1 |
| 2 | 87654311100x | 4 |
| 3 | x111x222x | 6 |
+----+--------------+----------------------+
Now, I might have 511132228 which will match with row 3 and it should return its type. So, it's kind of like SQL wilcards, but the other way around and I'm confused on how to achieve this.
Give this a go:
select * from my_table
where '511132228' like replace(phone_number, 'x', '_')
select *
from yourtable
where '511132228' like (replace(phone_number, 'x','_'))
Try below query:
SELECT ID,phone_number,phone_number_type_id
FROM TableName
WHERE '511132228' LIKE REPLACE(phone_number,'x','_');
Query with test data:
With TableName as
(
SELECT 3 ID, 'x111x222x' phone_number, 6 phone_number_type_id from dual
)
SELECT 'true' value_available
FROM TableName
WHERE '511132228' LIKE REPLACE(phone_number,'x','_');
The above query will return data if pattern match is available and will not return any row if no match is available.

Mysql: How to get every rows that have more than a certain number of decimal after the dot

I have a table that contains float values.
table
+ id | value |
+--------|---------|
+ 1 | 19.22 |
+ 2 | 32.333 |
+ 3 | 1.2332 |
+ 4 | 0.22334 |
+ 5 | 4.55 |
I want to extract every row that contains more than 3 decimal after the dot.
The result I would expect is:
+ id | value |
+--------|---------|
+ 2 | 32.333 |
+ 3 | 1.2332 |
+ 4 | 0.22334 |
Cast the value column as a varchar and use string comparison.
This worked for me:
SELECT *
FROM table
WHERE column <> ROUND (column,2)
or:
SELECT *
FROM table
WHERE column <> CAST (column AS DECIMAL(36,2))
This regex (MySQL 5.0+) worked for me, based on the data you provided:
SELECT t.*
FROM YOUR_TABLE t
WHERE t.`value` REGEXP '[0-9]+.[0-9][0-9][0-9]+'
Reference:
http://www.regular-expressions.info/
This worked for me
SELECT *
FROM `table`
WHERE LENGTH(SUBSTR(`value`,INSTR(`value`,"."))) >3
Counting the decimal .01 is 3, .011 is 4
Try this:
select value, LEN(value) - CHARINDEX('.', value) as DecimalCount from Table
where LEN(value) - CHARINDEX('.', value) > 2
NOTE: I'm not using mySQL, I have MSSQL. let me know if this works for you - just noticed you asked for a mySQL solution.
UPDATE: Felt bad for answering for the wrong platform. A bit of research got me this for mySQL:
select * from Table
where LENGTH(SUBSTRING_INDEX(value, '.', -1)) > 2
SELECT *
FROM table t
WHERE floor(t.columnname)!=t.columnname
SQL Server:
To extract values with more than 3 decimal places from the "quantity" column in a SQL table with the "quantity" column using float data type, you can use the following query:
SELECT *
FROM `table`
WHERE ROUND(quantity, 3) <> quantity;