Hive casting function - sql

In a hive table how can I add the '-' sign in a field, but for random records? If I use the syntax below it changes all the records in the field to negative, but I want to change random records to negative.
This is the syntax I used which changed all the records to negative:
CAST(CAST(-1 AS DECIMAL(1,0)) AS DECIMAL(19,2))
*CAST(regexp_replace(regexp_replace(TRIM(column name),'\\-',''),'-','') as decimal(19,2)),

If you want to change random values to negative, why not use a case expression?
select (case when rand() < 0.5 then - column_name else column_name end)
Despite your query, this assumes that the column is a number of some sort, because negating strings doesn't make much sense.

Related

SQL - How to sort numbers in a VARCHAR column with empty strings as entries

I have a postgres column which is like so:
It only has numbers or empty string.
I want to be able to sort the numbers by the numbers but as I go to cast the column to a float, it will give me the following error:
ERROR: invalid input syntax for type double precision: ""
Is there a way I can do this sort, and having the empty strings be treated as 0?
This is my query that's failing:
SELECT C.content
FROM row R
LEFT JOIN cell C ON C.row_id = R.row_id
WHERE R.database_id = 'd1c39d3a-0205-4ee3-b0e3-89eda54c8ad2'
AND C.column_id = '57833374-8b2f-43f3-bdf5-369efcfedeed'
ORDER BY cast(C.content as float)
when its an empty string you need to either treat it as null or 0 and then it will work, try putting a case statement like so in the order by
ORDER BY
case when C.content = '' then 0
else cast(C.content as float)
end
If it's sure this column will never have negative values, a simple option is just adding a leading zero.
If the column is NULL or has an empty string, it will be sorted as 0.
Otherwise, the value will be sorted as it is because adding a leading zero doesn't change anything.
SELECT yourcolumn
FROM yourtable
ORDER BY CAST(CONCAT('0',yourcolumn) AS FLOAT);
If negative values can appear, this would fail, so I would then use CASE WHEN.
But I propose to also take 0 for NULL values, not only for empty strings:
SELECT yourcolumn
FROM yourtable
ORDER BY
CASE WHEN yourcolumn = '' OR yourcolumn IS NULL
THEN 0
ELSE CAST(yourcolumn AS FLOAT)
END;
Otherwise, NULL values would be sorted as highest number which is likely not intended.
And yes, I know you wrote there are numbers and empy strings only in your table, but maybe this can change (unless the column is not nullable). So adding this condition doesn't hurt.

sql server logic to workout the right most position of the numeric field will have a sign OVER it designating positive or negative

Example of the data in csv
Column_header
000000025000{
000000007185E
The doucmention I have
*The right most position of the numeric field will have a sign OVER it
designating positive or negative.
Example of Data
I dont understand how write the logic to support the the symbol,number,letter to get the correct value.
I'd create a table (or view) with the static mapping of character-value, meaning:
Symbol
Value
J
-1
A
+1
about the data rows themselves, it seems to me there is always a symbol at the end, therefore you can split the data into two columns, value, and symbol...
I have no idea about how the data are inserted but it seems logically easy
SELECT
_YourValue_
,LEFT(_YourValue_, LENGTH(_YourValue_)-1) as Value
,RIGHT(_YourValue_, 1) as Symbol
FROM _Whatever_
you can also cast to whatever datatype is correct for those data.
Finally you can join the tables and show/calculate whatever is needed
select value , if(value LIKE '%{%' or value LIKE '%J%' or value LIKE '%E%' or value LIKE '%C%',concat(SUBSTRING(value,1,char_length(value)-1),'+'),concat(SUBSTRING(value,1,char_length(value)-1),'-')) as new_value from yourtablename
Output
value
New Value
000000025000{
000000025000+
000000007185E
000000007185+
Add all other character on first parameter of if clause for positive designation.

Average Row [SQL]

Actually I'm a bit confused about what should i wrote in the subject.
The point is like this, I want to average the Speed01,Speed02,Speed03 and Speed04 :
SELECT
Table01.Test_No,
Table01.Speed01,
Table01.Speed02,
Table01.Speed03,
Table01.Speed04,
I want to create new column that consists of this average -->>
AVG(Table01.Speed01, Table01.Speed02, Table01.Speed03,Table01.Speed04) as "Average"
I have tried this, but it did not work.
From
Table01
So, the contain of the Speed column could be exist but sometimes the Speed02 don't have number but the others are have numbers. sometimes speed04 data is also missing and the others is exist, sometimes only one data (example: only Speed01) have the data. lets say it depends on the sensor ability to catch the speed of the test material.
It will be a big help if you can find the solution. I'm newbie here.
THANK YOU ^^
AVG is a SQL aggregate function, therefore not applicable. So simply do the math. Average is sum divided by count:
(SPEED01 + SPEED02 + SPEED03 +SPEED04)/4
To deal with missing values, use NULLIF or COALESCE:
(COALESCE(SPEED01, 0) + COALESCE(SPEED02, 0) + COALESCE(SPEED03, 0) + COALESCE(SPEED04, 0))
That leaves the denominator. You need to add 1 for every non null. For example:
(COALESCE(SPEED01/SPEED01,0) + COALESCE(SPEED02/SPEED02,0) + ...)
You can also use CASE, depending on the supported SQL dialect, to avoid the possible divide by 0:
CASE WHEN SPEED01 IS NULL THEN 0 ELSE 1
OR you can normalize the data, extract all SPEEDs into a 1:M relation and use the AVG aggregate, avoiding all these issues. Not to mention the possibility to add a 5th measurement, then a 6th and so on and so forth!
Just add the columns and divide them by 4. To deal with the "missing" values use coalesce to treat NULL values as zero:
SELECT Test_No,
(coalesce(Speed01,0) + coalesce(Speed02,0) + coalesce(Speed03,0) + coalesce(Speed04,0)) / 4 as "Average"
FROM Table01;
You didn't mention your DBMS (Postgres, Oracle, ...), but the above is ANSI (standard) SQL and should run on nearly every DBMS.
As I understood your question, I supposed that Table01.Speed01, Table01.Speed03, Table01.Speed04 are nullable and of type int whereas Table01.Speed02 is nullable and of type nvarchar:
SELECT
Table01.Test_No,
(
ISNULL(Table01.Speed01, 0) +
CASE ISNUMERIC(Table01.Speed02) WHEN 0 THEN 0 ELSE CAST(Table01.Speed02 AS int) END +
ISNULL(Table01.Speed03, 0) +
ISNULL(Table01.Speed04, 0)
)/4 AS AVG
FROM Table01

Absolute maxvalue comparison of columns in Firebird SQL

I want to perform comparison for the specified columns in database, the comparison logic should compare the numbers regardless of their signs and will retrieve the result original with its sign.
For example, below code works well but as can be seen in the select block it returns the absolute value of columns. Is there any trick, cheat in Firebird 2.1 to overcome that?
SELECT a.ELM_NUM,a.COMBO, maxvalue(abs(a.N_1),abs(a.N_2)) as maxN from ntm a order by a.ELM_NUM
You can use a CASE condition:
SELECT a.ELM_NUM,a.COMBO,
CASE WHEN abs(a.N_1) > abs(a.N_2) THEN a.N_1 ELSE a.N_2 END as maxN
from ntm a
order by a.ELM_NUM

Query for dropping value from field

I have a query that looks at duty and vat information and does calculation based on the returned value.
The column that tells me the duty rates is in the table formatted as either, for example 3.7% or 8% in both bases I need remove the % from my return value. Otherwise my SUM clasue fails.
I have sorted the problem for the 3.7% example with the follwoing:
CASE WHEN CustomsTariff.CommodityCode.StandardDuty = 'Free' THEN '0.0' ELSE SUBSTRING(CustomsTariff.CommodityCode.StandardDuty, 1, 3) END AS DutyRate,
This drops the % for any returns where there is decimal palce but I need to add to the CASE to say if the StandardDuty value has no decimal places drop the % character as well without messing up the first statement that looks to the 1st 3 digits.
Thanks.
Did you try a replace() on the % character? Replace
CASE WHEN CustomsTariff.CommodityCode.StandardDuty = 'Free'
THEN '0.0' ELSE REPLACE(CustomsTariff.CommodityCode.StandardDuty, N'%', N'')
END AS DutyRate,