Snowflake how to accommodate an unparseable JSON row - json

Suppose this query
select gestimate, (get(parse_json(gestimate) :duration,'value')) / 60.0 AS rc_estimate
from mytable;
blows up because 120M rows in, there is an unparseable row. How to adjust this query so it places a 0 into rc_estimate if it is unparseable?

Using TRY_PARSE_JSON:
select gestimate, (get(try_parse_json(gestimate) :duration,'value')) / 60.0 AS rc_estimate
from mytable;
COALESCE(expr, 0), ZEROIFNULL(expr) could be used to change the result from NULL to 0.

Related

Why is my query returning "OK" instead of rows?

I have the following query:
SELECT
(sign(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time)) AS h2h_win_one_time_1,
(abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time) ^ 2) AS h2h_win_one_time_2
FROM belgarath.match_result AS mr
LIMIT 10
Which returns:
However, when I try to multiply the two fields:
SELECT
(
sign(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time)
) *
(
abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time) ^ 2
) AS h2h_win_one_time_comb
FROM belgarath.match_result AS mr
LIMIT 10
Workbench simply returns OK instead of any rows.
Doing some investigation I can get the first two rows to display if I use LIMIT 2. Looking at the returned values above I guess there must be some issue with multiplying the minus values or zero values from rows 3-10. However, this can be done simply on a calculator so what am I missing?
Maybe you think that the operator ^ is the power operator when in fact it is the Bitwise XOR operator.
MySql has the function pow() for your case:
pow(abs(mr.p1_h2h_win_one_time - mr.p2_h2h_win_one_time), 2)

Selecting a value based on how another field was generated

I'm selecting some data;
select c.*,
coalesce(s.column1, ...),
coalesce(s.column2, ...),
FROM
(SELECT ...)
Basically, if s.column1 or s.column2 is null then I am putting in some logic to take the average of that column and use it instead.
I want to have another field so I can know weather or not that value was computing using the average or not - perhaps a boolean? Lets say the average for column1 was 120, the table would look like;
column1 column2 avg
54 10 0
200 40 0
120 180 1
499 160 0
This allows me to see that the third row was generated using the avg of all rows as it was initially null.
How could the logic for the avg column work?
Your question seems fairly moot to me because:
The AVG function ignores NULL values by default, so the average using the overall average for NULL slots is the same as leaving out those slots entirely, and
If you just want to mark the rows which had a NULL value, you can use a CASE expression
So, to get what you want, just use this:
SELECT
column1,
column2,
CASE WHEN column1 IS NULL THEN 1 ELSE 0 END AS avg
FROM yourTable;
And know that SELECT AVG(column1) FROM yourTable would return the same value whether NULL rows were omitted, or the overall average were used.

How to create query with simple formula?

Hey is there any way to create query with simple formula ?
I have a table data with two columns value_one and value_two both are decimal values. I want to select this rows where difference between value_one and value_two is grater then 5. How can i do this?
Can i do something like this ?
SELECT * FROM data WHERE (MAX(value_one, value_two) - MIN(value_one, value_two)) > 5
Example values
value_one, value_two
1,6
9,3
2,3
3,2
so analogical difs are: 5, 6, 1, 1 so the selected row would be only first and second.
Consider an example where smaller number is subtracted with a bigger number:
2 - 5 = -3
So, the result is a difference of two numbers with a negation sign.
Now, consider the reverse scenario, when bigger number is subtracted with the smaller number:
5 - 2 = 3
Pretty simple right.
Basically, the difference of two number remains same, if you just ignore the sign. This is in other words called absolute value of a number.
Now, the question arises how to find the absolute value in MySQL?
Answer to this is the built-in method of MySQL i.e. abs() function which returns an absolute value of a number.
ABS(X):
Returns the absolute value of X.
mysql> SELECT ABS(2);
-> 2
mysql> SELECT ABS(-32);
-> 32
Therefore, without worrying about finding min and max number, we can directly focus on the difference of two numbers and then, retrieving the absolute value of the result. Finally, check if it is greater than 5.
So, the final query becomes:
SELECT *
FROM data
WHERE abs(value_one - value_two) > 5;
You can also do complex operations once the absolute value is calculated like adding or dividing with the third value. Check the code below:
SELECT *
FROM
data
WHERE
(abs(value_one - value_two) / value_three) + value_four > 5;
You can also add multiple conditions using logical operators like AND, OR, NOT to do so. Click here for logical operators.
SELECT *
FROM
data
WHERE
((abs(value_one - value_two) / value_three) + value_four > 5)
AND (value_five != 0);
Here is the link with various functions available in MySQL:
https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html
No, you would just use a simple where clause:
select *
from data
where abs(value_one - value_two) > 5;

MySQL VARCHAR Type won't CONVERT to Integer

I have a column of data of type VARCHAR, that I want to CONVERT or CAST to an integer (my end goal is for all of my data points to be integers). However, all the queries I attempt return values of 0.
My data looks like this:
1
2
3
4
5
If I run either of the following queries:
SELECT CONVERT(data, BINARY) FROM table
SELECT CONVERT(data, CHAR) FROM table
My result is:
1
2
3
4
5
No surprises there. However, if I run either of these queries:
SELECT CONVERT(data, UNSIGNED) FROM table
SELECT CONVERT(data, SIGNED) FROM table
My result is:
0
0
0
0
0
I've searched SO and Google all over for an answer to this problem, with no luck, so I thought I would try the pros here.
EDIT/UPDATE
I ran some additional queries on the suggestions from the comments, and here are the results:
data LENGTH(data) LENGTH(TRIM(data)) ASCII(data)
1 3 3 0
2 3 3 0
3 3 3 0
4 3 3 0
5 3 3 0
It appears that I have an issue with the data itself. For anyone coming across this post: my solution at this point is to TRIM the excess from the data points and then CONVERT to UNSIGNED. Thanks for all of the help!
FURTHER EDIT/UPDATE
After a little research, turns out there were hidden NULL bytes in my data. The answer to this question helped out: How can I remove padded NULL bytes using SELECT in MySQL
What does SELECT data, LENGTH(data), LENGTH(TRIM(data)), ASCII(data) FROM table return? It's possible your numeric strings aren't just numeric strings.
Alternately, are you using multi-byte character encoding?
I believe the query you have is fine; as it worked for me: sqlfiddle.com/#!2/a15ec4/1/3.
Makes me think you have a data problem. Are you sure there's not a return or space in the data somewhere?
you can check the data by trying to do a length or a ascii on the data to see if you have more than expected:
select ascii(data) from foo where ascii(data) not between 48 and 57 or
select length(data) as mLEN from table having mlen>1 for length.
I believe this is the correct form:
SELECT CAST(data AS UNSIGNED) FROM test;
SELECT CAST(data AS SIGNED) FROM test;
Tested here: http://sqlfiddle.com/#!8/8c481/1
Try these syntax
SELECT CONVERT(data, UNSIGNED INTEGER) FROM table
or
SELECT CAST(data AS UNSIGNED) FROM table

mysql double values checking problem

I wanna make a query that fetches only the rows that has 'cost' value grader than zero.The cost column has double data type.When i write a query like that,
select cost from xxx where cost>0;
it retrieves the rows only that has value grader than or equal to one.For example it doesnt take like 0.02 or 0.3 values.The query sees these type values as zero.How can i achieve my goal?
Thanks for advance...
I can't replicate your problem using mysql 5.41.
Show us the result of describe table xxx;
What happens if you issue the query:
select cost from xxx where cost > 0.0;
Is your query actually:
select ceil(cost) from xxx where cost > 0.0;
If so, for values of cost > 0 but <= 1, you'd get a result set of 1.