How to select from a json encoded field that contains nested data? - mysql

The fields looks like this:
[{"Tester":"Bonnie","Credentials":"MS","Date":"2013-02-19"},
{"Tester":"Karen","Credentials":"Teacher","Date":"2016-01-20"}]
I need to select based on the year of the 'Date' value: < > or =
I have found the json_extract function and it's shortcuts such that this will get the data (from the MySQL docs) "autowrapped as an array" and it works:
json_field->"$[*].Date" returns ["2013-02-19", "2016-01-20"]
Great, so I has the dates from the json data, but now I need to format the WHERE. How do I select the record if either of the years is 2016 for instance? I don't see any json function that do that.

I would highly recommend you to drop this JSON column and build another table, then you can search in your table using JOIN. JSON in column is a bad idea.
Just to answer your question:
I think this should work -
WHERE YEAR(STR_TO_DATE(json_field->"$.Date", '%Y-%m-%d')) = '2016'

Related

Big Query JSON Extract Function

I'm extracting 2 fields from a JSON using JSON_EXTRACT using BQ as the following:
select JSON_EXTRACT_SCALAR('Event_Value','$.user_id') as cid, JSON_EXTRACT_SCALAR('Event_Value','$.tsts') as ts
if the JSON format is missing one of the field I'm receiving NULLs all over the place.
Is there a way to overcome it?
I feel the fix is quite simple:
select JSON_EXTRACT_SCALAR(Event_Value,'$.user_id') as cid, JSON_EXTRACT_SCALAR(Event_Value,'$.tsts') as ts
So, there are extra ' around Event_Value - thus Event_Value was treated not as a column name but rather as string

Snowflake interpreting timestamp wrong?

I'm loading a bunch of semi-structured data (JSON) into my database through Snowflake. The timestamp values in the entries are javascript timestamps that look like this:
"time": 1621447619899
Snowflake automatically converts this into a timestamp variable that looks like this:
53351-08-15 22:04:10.000.
All good so far. However, I think that the new timestamp is wrong. The actual datetime should by May 19, 2021 around 12pm MDT. Am I reading it wrong? Is it dependent on the timezone that my Snowflake instance is in?
When comparing the following options manually in SQL:
with x as (
SELECT parse_json('{time:1621447619899}') as var
)
SELECT var:time,
var:time::number,
var:time::varchar::timestamp,
1621447619899::timestamp,
'1621447619899'::timestamp,
var:time::timestamp
FROM x;
It appears that what you want to do is execute the following:
var:time::varchar::timestamp
Reviewing the documentation it does look like the to_timestamp is looking for the number as a string, so you need to cast to varchar first, and then cast to timestamp, otherwise you get what you are getting.
The question says that Snowflake transforms it to "53351-08-15 22:04:10.000" looks right, but it doesn't look right to me.
When I try the input number in Snowflake I get this:
select '1621447619899'::timestamp;
-- 2021-05-19T18:06:59.899Z
That makes a lot more sense.
You'll need to provide more code or context for further debugging - but if you tell Snowflake to transform that number to a timestamp, you'll get the correct timestamp out.
See the rules that Snowflake uses here:
https://docs.snowflake.com/en/sql-reference/functions/to_timestamp.html#usage-notes
The ::timestamp handles strings and numeric inputs differently. I.e. a string is added to 1970-01-01 as milliseconds (correct) whereas the numeric value is added in seconds which returns a date way in the future "53351-08-18 20:38:19.000".
SELECT TO_VARCHAR(1621447619899::timestamp) AS numeric_input
,'1621447619899'::timestamp AS string_input
numeric_input = 53351-08-18 20:38:19.000
string_input = 2021-05-19 18:06:59.899
Solutions are to convert to a string or divide by 1000:
SELECT TO_TIMESTAMP(time::string)
SELECT TO_TIMESTAMP(time/1000)

MySql, How to select data by comparing 2 Jsons

I have a json data like this
{"0":"6","1":"5","2":"10"}
And on the DB I have table which contains json datas like these
{"0":"6","1":"4"}
{"0":"5","1":"2","2":"7"}
{"0":"3","1":"10","2":"4"}
{"0":"6","1":"5","2":"10","3":"8"}
So, I would like know is it possible or does it make sense to select data by comparing the json datas?
I would like to get any json that may contain any key:value in my input json.
So, from my example they will be these
{"0":"6","1":"4"}
{"0":"6","1":"5","2":"10","3":"8"}
You can use JSON search functions. For example -
SELECT json_field FROM table1
WHERE
JSON_CONTAINS(json_field, '{"0":"6"}')
AND JSON_CONTAINS(json_field, '{"1":"5"}')
AND JSON_CONTAINS(json_field, '{"2":"10"}');

How to convert a string to date and extract values in Access query

I'm using Access DB 2007 - 2010; I've tried to import many CSV files but the timestamp column keeps failing to import correctly.
So I linked all of the CSV's to an Access DB and I'm trying to query all of the tables.
I'm trying to extract the year and day of the year from the time stamp (which is currently a string)
I'm trying to combine the Format with datepart functions and it keeps failing. (it just says error in the table)
The format function by itself works but I can't combine it with anything.
I'm basically trying to do this:
select datepart("y", Format(gmt, "dd-mmm-yyyy hh:nn:ss")) as DOY from Table1;
but it fails. I've also tried CDate and DateValue in different combinations but it all fails.
Does anyone know how to get this to work?
UPDATE
The format function isn't doing anything. The text remains the same no matter how I try to format it.
Here's a datetime sample: 05-Dec-2008 13:40:01.955
Access can't cope with the milliseconds in your date strings.
Use Left() to exclude them and feed the resulting substring to CDate().
SELECT CDate(Left(gmt, 20)) AS date_from_string
FROM Table1;
Once you have a valid Date/Time value, you can use Year(<Date/Time value>) or DatePart("yyyy", <Date/Time value>) to extract the year. And DatePart("y", <Date/Time value>) will give you the day of the year.
Just solve this issue, here is my code for your reference:
update tablename
set date=cdate(format(left(gmt,4)&"-"&right(gmt,2),"yyyy-mm"))

MySqlImport - Import a date field not in the proper format

I have a csv file that has a date field in a format like (among other fields):
17DEC2009
When I do a mysqlimport, the other fields are imported properly, but this field remains 0000-00-00 00:00:00
How can I import this date properly? Do I have to run a sed/awk command on the file first to put it into a proper format? If so, what would that be like? Does the fact that the month is spelled out instead of a number matter?
STR_TO_DATE() enables you to convert a string to a proper DATE within the query. It expects the date string, and a format string.
Check the examples in the manual entry to figure out the correct format.
I think it should be along the lines of %d%b%Y (However the %b is supposed to produce Strings like Dec instead of DEC so you will have to try out whether it works).
I had this issue in the past. What I had to do was to utilize LOAD DATA and set the appropriate expression here -
[SET col_name = expr,...]
http://dev.mysql.com/doc/refman/5.1/en/load-data.html
Here is the approach I took to solve similar problem. My use case was bit complex with so many columns, but making here simple to present the solution.
I have Persons table with (Id int autogen, name varchar(100),DOB date), and few million of data(name,DOB) needs to be populated from CSV file.
Created additional column in persons table with name like (varchar_DOB varchar(25)).
Imported data using mysqlimport utility into columns(name,varchar_DOB).
Executed update query that updated DOB column using str_to_date(varchar_DOB,'format') function.
Now, I have expected data populated DOB column.
The same logic could be applied in doing even other kind of data formatting like double,time_stamp etc.