How do I convert HEXADECIMAL to DECIMAL in SAS? - sql

I have:
A string with hexadecimal values ​​every 4 positions
00F701C101C900EC01E001D2
I need:
Separate these values ​​from 4 in 4 positions and convert to decimal numbers in this way:
247, 449, 457, 480, 466
My column can have up to 1200 hexadecimal positions
Can you help me?
Tks!!!

This works:
data out;
hex = "00F701C101C900EC01E001D2";
do while(hex ne "");
valHex = substr(hex, 1, 4);
hex = substr(hex, 5);
valDec = input(valHex, hex4.);
output;
end;
run;
but you'll want to add more error checking etc for your real solution.

Sorry, I was to fast. This is SQL-Server syntax, probably not working for you, but you might get an idea...
Try it like this:
DECLARE #YourString VARCHAR(100)='00F701C101C900EC01E001D2';
WITH Separated AS
(
SELECT CAST(LEFT(#YourString,4) AS VARCHAR(MAX)) AS SourceString
,CAST(SUBSTRING(#YourString,5,10000) AS VARCHAR(MAX)) AS RestString
UNION ALL
SELECT LEFT(RestString,4)
,SUBSTRING(RestString,5,10000)
FROM Separated
WHERE LEN(RestString)>=4
)
SELECT *
,CAST(sys.fn_cdc_hexstrtobin(SourceString) AS VARBINARY(2))
,CAST(CAST(sys.fn_cdc_hexstrtobin(SourceString) AS VARBINARY(2)) AS INT)
FROM Separated
The result
+--------------+----------------------+--------------------+--------------------+
| SourceString | RestString | (Kein Spaltenname) | (Kein Spaltenname) |
+--------------+----------------------+--------------------+--------------------+
| 00F7 | 01C101C900EC01E001D2 | 0x00F7 | 247 |
+--------------+----------------------+--------------------+--------------------+
| 01C1 | 01C900EC01E001D2 | 0x01C1 | 449 |
+--------------+----------------------+--------------------+--------------------+
| 01C9 | 00EC01E001D2 | 0x01C9 | 457 |
+--------------+----------------------+--------------------+--------------------+
| 00EC | 01E001D2 | 0x00EC | 236 |
+--------------+----------------------+--------------------+--------------------+
| 01E0 | 01D2 | 0x01E0 | 480 |
+--------------+----------------------+--------------------+--------------------+
| 01D2 | | 0x01D2 | 466 |
+--------------+----------------------+--------------------+--------------------+

Related

Snowflake automatically rounding number during COPY INTO transformation

I am using an AWS S3 stage to load .csv data into my Snowflake database.
The .csv columns are as follows:
My COPY INTO command is this:
copy into MY_TABLE(tot_completions, tot_hov, parent_id)
from (select t.$1, to_decimal(REPLACE(t.$2, ',')), 1 from #my_stage t)
pattern='.*file_path.*' file_format = my_file_format ON_ERROR=CONTINUE;
The Tot. HOV column is being automatically rounded to 40 and 1 respectively. The data type is decimal, and I tried it as a float as well, even though they should both be able to store decimals.
My desired result is to store the decimal as is displayed on the .csv without rounding. Any help would be greatly appreciated.
You need to specify the precision and scale:
create or replace table number_conv(expr varchar);
insert into number_conv values ('12.3456'), ('98.76546');
select expr, to_number(expr), to_number(expr, 10, 1), to_number(expr, 10, 8) from number_conv;
+----------+-----------------+------------------------+------------------------+
| EXPR | TO_NUMBER(EXPR) | TO_NUMBER(EXPR, 10, 1) | TO_NUMBER(EXPR, 10, 8) |
|----------+-----------------+------------------------+------------------------|
| 12.3456 | 12 | 12.3 | 12.34560000 |
| 98.76546 | 99 | 98.8 | 98.76546000 |
+----------+-----------------+------------------------+------------------------+
and:
select column1,
to_decimal(column1, '99.9') as d0,
to_decimal(column1, '99.9', 9, 5) as d5,
to_decimal(column1, 'TM9', 9, 5) as td5
from values ('1.0'), ('-12.3'), ('0.0'), (' - 0.1 ');
+---------+-----+-----------+-----------+
| COLUMN1 | D0 | D5 | TD5 |
|---------+-----+-----------+-----------|
| 1.0 | 1 | 1.00000 | 1.00000 |
| -12.3 | -12 | -12.30000 | -12.30000 |
| 0.0 | 0 | 0.00000 | 0.00000 |
| - 0.1 | 0 | -0.10000 | -0.10000 |
+---------+-----+-----------+-----------+
See more here

Postgresql Select Query solution

Can anyone help me with this scenario ?
Actual Table
rrno | filename | type | amount | element
--------------------------------------------------------
000000000001 | 00dww | 0200 | 500 | 45
000000000001 | d00dww | 0200 | 700 | 456
000000000001 | addww | 0100 | 250 | 7236
000000000001 | qc5gdw | 0400 | 431 | 173
012600003598 | q979wa | 0110 | 050 | --
Current Query
select rrno,filename,type,amoumt
from table
where type in ('0220)
and amount in ('500','700');
Result for Current query
rrno | filename | type | amount | element
--------------------------------------------------------
000000000001 | 00dww | 0200 | 500 | 45
000000000001 | d00dww | 0200 | 700 | 456
after getting the above results i want to check whether
rrno field 000000000001 has type '0100' with amount 050.
How to create it in single query ?
I suspect that you want exists:
select rrno, filename, type, amoumt
from mytable t
where type = '0220' and amount in ('500', '700') and exists (
select 1
from mytable t1
where t1.rrno = t.rrno and t1.type = '0100' and t1.amount = '050'
)
Starting from your existing query, this filters the resultset on rows for which another row exists in the table with the same rrno, type '0100' and amount '050'.
I find quite suprising that a column called amount would be of a string datatype. If it's a number, then remove the single quotes around the values.

Alphanumberic output from ST_MakeLine

I'm trying to convert lat/lon to linestring. Basically, grouping the columns lat and lon, making a point, and creating a linestring.
Table:
+------------+----------+-----------+------------+---------+--------+
| link_id | seq_num | lat | lon | z_coord | zlevel |
+------------+----------+-----------+------------+---------+--------+
| "16777220" | "0" | "4129098" | "-7192948" | | 0 |
| "16777220" | "999999" | "4129134" | "-7192950" | | 0 |
| "16777222" | "0" | "4128989" | "-7193030" | | 0 |
| "16777222" | "1" | "4128975" | "-7193016" | | 0 |
| "16777222" | "2" | "4128940" | "-7193001" | | 0 |
| "16777222" | "3" | "4128917" | "-7192998" | | 0 |
| "16777222" | "4" | "4128911" | "-7193002" | | 0 |
+------------+----------+-----------+------------+---------+--------+
My code:
select link_id, ST_SetSRID(ST_MakeLine(ST_MakePoint((lon::double precision / 100000), (lat::double precision / 100000))),4326) as geometry
from public.rdf_link_geometry
group by link_id
limit 50
geometry output column example:
"0102000020E6100000020000004F92AE997CFB51C021E527D53EA54440736891ED7CFB51C021020EA14AA54440"
^^ What is this? how did it get formatted in such a way? I expected a linestring, something like
geometry
7.123 50.123,7.321 50.321
7.321 50.321,7.321 50.321
Data format for link_id is bingint, and for geometry it says geometry
SOLUTION:
select link_id, ST_AsText(ST_SetSRID(ST_MakeLine(ST_MakePoint(
(lon::double precision / 100000), (lat::double precision / 100000))),4326)) as geometry
from public.rdf_link_geometry
group by link_id
limit 50
The output is a geometry, which you can display as text using st_asText
select st_asText('0102000020E6100000020000004F92AE997CFB51C021E527D53EA54440736891ED7CFB51C021020EA14AA54440');
st_astext
--------------------------------------------------
LINESTRING(-71.92948 41.29098,-71.9295 41.29134)
That being said, should you have more than 2 points, you could order them to create a meaningful line:
select st_makeline(geom ORDER BY seqID) from tbl;

Find words with numbers sql like

There is a table1
| ID | Attr |
+-----+------------+
| 169 | Jur9 |
| 169 | Jur9_name |
| 169 | Jur10 |
| 169 | Jur10_name |
And query:
select *
from table1
where ID = 169
and ATTR like 'Jur_';
Result:
| ID | Attr |
+-----+------------+
| 169 | Jur9 |
I expect the result:
| ID | Attr |
+-----+------------+
| 169 | Jur9 |
| 169 | Jur10 |
The _ wildcard matches exactly one character. So this expression:
WHERE ATTR like 'Jur_'
Is looking for ATTR values that are four characters that start with 'Jur'.
You can do what you want using LIKE and NOT LIKE:
WHERE ATTR LIKE 'Jur%' AND ATTR NOT LIKE 'JUR%$_%' ESCAPE '$'
That is, followed by anything but not followed by an underscore.
Or, you can use regexp_like():
WHERE REGEXP_LIKE(ATTR, '^JUR[^_]+$')
You can try below -
select *
from table1
where ID = 169
and ATTR not like '%_name'

casting a REAL as INT and comparing

I am casting a real to an int and a float to an int and comparing the two like this:
where
cast(a.[SUM(PAID_AMT)] as int)!=cast(b.PAID_AMT as int)
but i am still getting results where the two are equal. for example:
+-----------+-----------+------------+------------+----------+
| accn | load_dt | pmtdt | sumpaidamt | Bpaidamt |
+-----------+-----------+------------+------------+----------+
| A133312 | 6/7/2011 | 11/28/2011 | 98.39 | 98.39 |
| A445070 | 6/2/2011 | 9/22/2011 | 204.93 | 204.93 |
| A465606 | 5/19/2011 | 10/19/2011 | 560.79 | 560.79 |
| A508742 | 7/12/2011 | 10/19/2011 | 279.65 | 279.65 |
| A567730 | 5/27/2011 | 10/24/2011 | 212.76 | 212.76 |
| A617277 | 7/12/2011 | 10/12/2011 | 322.02 | 322.02 |
| A626384 | 6/16/2011 | 10/21/2011 | 415.84 | 415.84 |
| AA0000044 | 5/12/2011 | 5/23/2011 | 197.38 | 197.38 |
+-----------+-----------+------------+------------+----------+
here is the full query:
select
a.accn,
a.load_dt,
a.pmtdt,
a.[SUM(PAID_AMT)] sumpaidamt,
sum(b.paid_amt) Bpaidamt
from
[MILLENNIUM_DW_DEV].[dbo].[Millennium_Payment_Data_May2011_July2012] a
join
F_PAYOR_PAYMENTS_DAILY b
on
a.accn=b.ACCESSION_ID
and
a.final_rpt_dt=b.FINAL_REPORT_DATE
and
a.load_dt=b.LOAD_DATE
and
a.pmtdt=b.PAYMENT_DATE
where
cast(a.[SUM(PAID_AMT)] as int)!=cast(b.PAID_AMT as int)
group by
a.accn,
a.load_dt,
a.pmtdt,
a.[SUM(PAID_AMT)]
what am i doing wrong? how do i return only records that are NOT equal?
I don't see why there is an issue.
The query is returning the sum of the payments in b (sum(b.paid_amt) Bpaidamt). The where clause is comparing individual payments. This just means that there is more than one payment.
Perhaps your intention is to have a HAVING clause instead:
having cast(a.[SUM(PAID_AMT)] as int)!=cast(sum(b.PAID_AMT) as int)
You can do a round and a cast statement.
cast(round(sumpaidamt,2) as money) <> cast(round(Bpaidamt,2) as money)
Sql Fiddle showing how it would work http://sqlfiddle.com/#!3/4eb79/1