How can I chance custno: 5.0256926E7 into a normal integer / number in Impala SQL?
This is what I've tried so far:
SELECT * FROM z9_strategy.dstool_model_data_m
WHERE snapshot_date_key = 20170630
AND custtype_ind = 1
AND retailer_retail = 1
AND CAST((custno AS FLOAT) AS int);
I also tried SELECT CAST(CAST(custno AS FLOAT) AS int)
Use CAST:
CAST(custno AS int);
Related
I am creating a Snowflake SQL UDF. I keep running into SQL compilation error: Unsupported subquery type cannot be evaluated. I have tried to do several things to go around the issue, this being my latest try.
How can I make this break out of the subquery'ing error?
The UDF should allow one to input their preferred year. Thinking to create a solution by if a year is not provided, the default would be the present year.
create or replace function new_value(PRICE float, TYPE varchar, YR_CREATED int, YEAR int)
returns float
as
$$
with AGE_OF_PRODUCT as (
select any_value((YEAR - YR_CREATED)) as AGE ),
FORMULA as (
select any_value(AGE) as AGE,
any_value(case
when AGE <= 1 then 1
else 2
end) as FUNCTION
from AGE_OF_PRODUCT
)
select
any_value(case
when F.FUNCTION = 1 then (PRICE - (PRICE * R.R1))
else (PRICE * (1 - (R.R1))) * pow((1-(R.R2)), ((F.AGE - YR_CREATED)-1))
end) as VALUE
from FORMULA as F, RATES as R
where TYPE = R.TYPE_OF_PRODUCT
$$;
So the main problem is you are likely using the function like:
select v.*,
new_value(v.price, v.type, v.yr_create, v.year) as awesome
from table_with_values as v
also your UDF can be rewritten as it stands as:
create or replace function new_value(
PRICE float,
TYPE varchar,
YR_CREATED int,
YEAR int)
returns float
as
$$
select
YEAR - YR_CREATED as age,
case age <= 1
when true then (PRICE - (PRICE * r.r1))
else (PRICE * (1 - (r.r1))) * pow((1-(r.r2)), ((age - YR_CREATED)-1))
end as value
from rates as r
where TYPE = r.type_of_product
$$;
but if we move the join to rates outside the UDF
create or replace function new_value(
PRICE float,
YR_CREATED int,
YEAR int,
rate1 float,
rate2 float)
returns float
as
$$
select
case (YEAR - YR_CREATED) <= 1
when true then (PRICE - (PRICE * r.r1))
else (PRICE * (1 - (rate1))) * pow((1-(rate2)), (((YEAR - YR_CREATED) - YR_CREATED)-1))
end as value;
$$;
then we can call it like:
select v.*,
new_value(v.price, v.yr_create, v.year, r.r1, r.r2) as awesome
from table_with_values as v
join rates as r
on v.type = r.type_of_product
I have an sql query as below. I want to convert this to hive query, is this possible? Using cloudera/hadoop. Thanks
DECLARE
#sd_y FLOAT,
#sd_x1 FLOAT,
#sd_x2 FLOAT,
SELECT
#sd_y = SUM(Y_w*Y),
#sd_x1 = SUM(Y_w*X1),
#sd_x2 = SUM(Y_w*X2)
FROM dbo.c
UPDATE dbo.c
SET
Y = SQRT(Y_w)*(Y-#sd_y),
X1 = SQRT(Y_w)*(X1-#sd_x1),
X2 = SQRT(Y_w)*(X2-#sd_x2)
SELECT
#sd_y,
#sd_x1,
#sd_x2
I have a SQL table with one float column populated with values like these:
1.4313
3.35
2.55467
6.22456
3.325
I need to select rows containing only values with more than 4 decimals. In this case, the select must return:
2.55467
6.22456
Ideas? Thanks!
This is what I have tried so far
select *
from table
where CAST(LATITUDE AS DECIMAL(10,5)) - LATITUDE = 0
DECLARE #tbl TABLE (val float)
INSERT INTO #tbl SELECT 1234.567
INSERT INTO #tbl SELECT 1234.5678
INSERT INTO #tbl SELECT -1234.5678
INSERT INTO #tbl SELECT 1234.56789
SELECT *
from #tbl
where (((val*10000) - CONVERT(INT,(val*10000))) <> 0)
Why cant we make it simple by this query:-
SELECT * FROM table WHERE val LIKE '%.____%'
This selects what we want
Another solution also:
SELECT * from table
where (round(value,2) - round(value,4) <> 0)
Given answers did not work for me with MaxDb, but this did:
where FLOOR(value * 10000) != value * 10000
Source
Reduce/Increase 0`s for less/more precision.
This works on Postgres 11:
SELECT * FROM mytable WHERE mycolumn != ROUND(mycolumn::numeric,2)
http://sqlfiddle.com/#!3/abadc/3/0
Seems like something like this should work...
all it does is convert the number to an integer to drop off decimals after multiplying it * 10 to power of decimals you need then it compares that int version of the number to the base number after it too was multiplied by 10 to the power of # of decimals.
If the numbers don't match, then you have decimals beyond 4. If they do match, then it was 4 or fewer.
Select *
from foo
where cast(myNum*power(10,4) as int) <> myNum*power(10,4)
Please try something like:
select * from table
where RIGHT(CAST(value as DECIMAL(10,5)), value), 1) != 0
SELECT *
FROM table WHERE
(abs(val)*100000)%10 <> 0
It's an older question but it checks out.
select val
from table
where ((val * 100) % 1) > 0
Change 100 to your precision.
You can multiply it with 10000 and subtract it from the original number replacing . with ''.
Fiddle
select * from tablename
where replace(numcolumn,'.','') - numcolumn * 10000 > 0
Below is the Code that will check the precision for 4 decimal places:
Replace MyNum, with column you are checking for precision
Replace MyTbl, with the table you are using
Replace 4, with whatever precision you are checking for
Sql:
SELECT MyNum
, LEN(CAST (MyNum AS CHAR))
, -------1. length of decimal number, after conversion to CHAR
CHARINDEX('.', CAST (MyNum AS CHAR))
, ---2.length of numbers after the '.'
LEN(CAST (MyNum AS CHAR)) - CHARINDEX('.', CAST (MyNum AS CHAR)) -----subtracting 1-2, to get the length of numbers after decimal point '.'
FROM MyTbl
WHERE LEN(CAST(MyNum AS CHAR)) - CHARINDEX('.', CAST(MyNum AS CHAR)) > 4; --checking if there are more than 4 numbers after the decimal point '.'
Cast the number as text
Split the text using '.' as separator
Use the 2nd index and apply a length
Filter
--i.e. with postgreSQL.
--1)
select data_numeric, length(arr[2]) as str_length
from (
select data_numeric, regexp_split_to_array(data_numeric::text, '\.') as arr from TABLE
) temp;
--2)
with t1 as (
select data_numeric, regexp_split_to_array(data_numeric::text, '\.') as arr from TABLE
), t2 as (
select data_numeric, arr[2] as decimals, length(arr[2]) as length from t1
)
select * from t2;
Select numbers with more than 2 decimal places:
I had an example, where ((abs(val)*100) and CONVERT(INT,(abs(val)*100)) for value "2.32" in float type column returned two different values.
(abs(2.32)*100) = 232
CONVERT(INT,(abs(2.32)*100)) = 231
That caused wrong select query answers in case for comparing to 0.
I suppose that MSSQL CONVERT() function round numbers in such way that for some float number cases, posted solution would not work.
Here is how I did it for more than 2 decimal places:
DECLARE #tbl TABLE (val float)
INSERT INTO #tbl SELECT 2.32
INSERT INTO #tbl SELECT 1234.54
INSERT INTO #tbl SELECT 1234.545
INSERT INTO #tbl SELECT 1234.5456
INSERT INTO #tbl SELECT 1234.54567
select * from #tbl where abs(val-round((val),2)) > 0.001
You can use the scale function, since postgresql 9.6.
select LATITUDE FROM TABLE where scale(LATITUDE) > 4;
If your data type is float you will get SQL Error [42883]: ERROR: function scale(double precision) does not exist. Below would fix it.
select LATITUDE FROM TABLE where scale(cast(LATITUDE as numeric)) > 4;
This is the simplest solution, Use WITH (NOLOCK) if it's necessary in your case otherwise you can remove it. This will return the records having at least 4 decimal points in ColumnName table.
SELECT * FROM TableName WITH (NOLOCK) WHERE ColumnName LIKE '%.____'
Basically I would like a select statement that would function like this
SELECT *
FROM table
WHERE column IS NOT INT
Is there a condition like this or how do you check for non-integers in an nvarchar(10) column?
In SQL Server you can do:
SELECT *
FROM mytable
WHERE CASE WHEN IsNumeric(mycolumn) = 1 THEN CASE WHEN CAST(mycolumn AS FLOAT) <> CAST(CAST(mycolumn AS FLOAT) AS INT) THEN 1 END ELSE 1 END = 1
You could also use
SELECT *
FROM T
WHERE C = ''
OR C LIKE '%[^0-9-]%' /*Contains a char other than - or 0-9*/
OR C LIKE '_%-%' /*Contains the - char other than 1st position*/
I am grabbing a postcode from a form. I can then convert this postcode to lng,lat coordinates as I have these stored in a table.
SELECT lng, lat from postcodeLngLat WHERE postcode = 'CV1'
I have another table which stores the lng,lat of a selection of venues.
SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, 'HAVERSINE' AS distance FROM venuepostcodes v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance
What I am trying to do is create a datagrid which shows the distance of each venue from the postcode (CV1 in this case). I know that the Haversine formula should do what I am trying to achieve but I'm lost as to where I should start incorporating it into my query. I think the formula needs to go where I've put 'HAVERSINE' in the query above.
Any ideas?
EDIT
SELECT o.outcode AS lead_postcode, v.venue_name, 6371.0E * ( 2.0E *asin(case when 1.0E < (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) then 1.0E else (sqrt(square(sin(((RADIANS(CAST(o.lat AS FLOAT)))-(RADIANS(CAST(v.lat AS FLOAT))))/2.0E)) + (cos(RADIANS(CAST(v.lat AS FLOAT))) * cos(RADIANS(CAST(o.lat AS FLOAT))) * square(sin(((RADIANS(CAST(o.lng AS FLOAT)))-(RADIANS(CAST(v.lng AS FLOAT))))/2.0E))))) end )) AS distance FROM venuepostcodes v, outcodepostcodes o WHERE o.outcode = 'CB6' ORDER BY distance
I think you'd do best putting it in a UDF and using that in your query:
SELECT v.lat, v.lng, v.name, p.lat, p.lng, p.postcode, udf_Haversine(v.lat, v.lng, p.lat, p.lng) AS distance FROM venuepostcodes v, postcodeLngLat p WHERE p.outcode = 'CB6' ORDER BY distance
create function dbo.udf_Haversine(#lat1 float, #long1 float, #lat2 float, #long2 float) returns float begin
declare #dlon float, #dlat float, #rlat1 float, #rlat2 float, #rlong1 float, #rlong2 float, #a float, #c float, #R float, #d float, #DtoR float
select #DtoR = 0.017453293
select #R = 3937 --3976
select
#rlat1 = #lat1 * #DtoR,
#rlong1 = #long1 * #DtoR,
#rlat2 = #lat2 * #DtoR,
#rlong2 = #long2 * #DtoR
select
#dlon = #rlong1 - #rlong2,
#dlat = #rlat1 - #rlat2
select #a = power(sin(#dlat/2), 2) + cos(#rlat1) * cos(#rlat2) * power(sin(#dlon/2), 2)
select #c = 2 * atn2(sqrt(#a), sqrt(1-#a))
select #d = #R * #c
return #d
end
Alternatively uou could also use SQL Server 2008 geography datatypes. If you currently store the longitude/latitide as varchar() in the DB, you will have to store them as geograpghy datatype and then use a function like STIntersects() to get the distance.