How to build a Snowflake query to get these results - mysql

The below table (TMP_RN_TC) in query is a temp table which would be used to load the data into the final table. This table has to get the data from stage-table and the output of temp-table data needs to be stored in final table. Stage table will get data for 15-days in every run.
But the fact/final table should store all the data for the first run and then after only one day of data which would be changing (rest 14-days data would remain same). Since stage-table will hold even the duplicate data, temp-table should be able to remove those duplicates and load only data for the day from second run. Distinct didn't help. Below is the data and query:
For example, in the first run for 15-days, we get 30 records but in the second run, stage is getting 30-more records that is 60-records in stage now after 2nd run, but temp table should pick only 2-records since that would only have changed in the second run and rest 14-days(28-rows) data would be same.
This is the query I want to build:
1-row Data looks like:
{
"location": "xyz",
"metrics": [
{
"name": "traffic_in",
"data": [
{
"group": {
"start": "2020-07-05",
"type": "date"
},
"index": 0,
"next_level": [
{"index": 0,
"validity": "complete",
"value": 1,
"group": {
"finish": "00:15",
"start": "00:00",
"type": "time"
}
}
]
}
],
}
],
}
Below is the snowflake-query:
create or replace TABLE TMP_RN_TC as
(select * from(
select distinct
replace(D_NEXT : location , '"' , '')as rn_loc_id,
mtr.value:name::VARCHAR as metrics_name,
dta.value:group.start::DATE as metrics_event_date,
dta.value:index::numeric as metrics_date_index,
nxt.value:validity::VARCHAR as metrics_data_validity,
nxt.value:value::numeric as metrics_data_value,
nxt.value:group.start::time as metrics_data_start_tms,
nxt.value:index::numeric as metrics_time_index
from STG_RN_TC stg,
lateral flatten(input => stg.D_NEXT:metrics) mtr,
lateral flatten(input => mtr.value:data) dta,
lateral flatten(input => dta.value:next_level)nxt)
) ;
Note: from second run, I want only one day data to be coming in tmp-table which would be loaded in final table eventually.

Related

PostgreSQL jsonb_set function

using postgresql db for persistence. one of my table's column's data type is json and stored data format is like
{
"Terms": [
{
"no": 1,
"name": "Vivek",
"salary": 123
},
{
"no": 2,
"name": "Arjun",
"salary": 123
},
{
"no":3,
"name": "Ashok",
"salary": 123
}
]
}
I need to update any of no or name or salary of 1st Term object only.
Used native queried to load and for better performance, I should use native query only for UPDATE. I tried postgresql jsonb_set function for the update, but unable to update.
I tried:
UPDATE table_name
SET terms = jsonb_set(terms->'Terms','{0,name}','"VVVV"',FALSE)
WHERE some condition
and response message in pgAdmin tool is
Query returned successfully: 0 rows affected, x msec execution time.
Can any one help me with this one?

Accessing an Array Inside JSON with a Postgres Query

I have a table with a data_type of json that I need to query one of the properties inside of it.
This is what the data in the column looks like:
{
"id": 7008,
"access_links": [
{
"product_code": "PRODUCT-1",
"link": "https://some.url"
},
{
"product_code": "PRODUCT-2",
"link": "https://someOther.url"
}
],
"library_id": "2d1203db-75b3-43a5-947c-8555b48371db"
}
I need to be able to pull out and filter by the product_code nested inside of the access_links.
I can get one layer deep by using this query:
SELECT
courses.course_metadata -> 'access_links' as access_links
FROM
courses
This seems to get me into the column, but I can't query any further.
The output I receive from the query looks like:
[{"product_code":"PRODUCT-1","link":"https://some.url"},{"product_code":"PRODUCT-2","link":"https://someOther.url"}]
I've tried using the ->> and #>> operators, but they both complain about the array not starting with a {. Also worth noting that the column is a data type of JSON not JSONB, so the #> operator doesn't work.
What am I missing here?
Does this help?
select
json_array_elements (x->'access_links')->'product_code' as product_code
from
(select '{
"id": 7008,
"access_links": [
{
"product_code": "PRODUCT-1",
"link": "https://some.url"
},
{
"product_code": "PRODUCT-2",
"link": "https://someOther.url"
}
],
"library_id": "2d1203db-75b3-43a5-947c-8555b48371db"
}'::json x
) as v
;
product_code
"PRODUCT-1"
"PRODUCT-2"

Postgres - updating an array element in a json column

I have a json column in a postgres table.
The column contains the following json data:
{
"data": {
"id": "1234",
"sites": [
{
"site": {
"code": "1",
"display": "Site1"
}
},
{
"site": {
"code": "2",
"display": "Site2"
},
"externalSite": true
},
{
"site": {
"code": "3",
"display": "Site3"
}
}
]
}
}
I need to create an update query that adds another attribute ('newAttribute' in the sample below) to all array items that have '"externalSite": true', so, after running the update query the second array element will be:
{
"site": {
"code": "2",
"display": "Site2"
},
"externalSite": true,
"newAttribute": true
}
The following query returns the array elements that need to be updated:
select * from myTable, jsonb_array_elements(data -> 'sites') sites
where sites ->'externalSite' = 'true'
What is the syntax of the update query?
Thanks
Kobi
Assuming your table is called test and your column is called data, you can update it like so:
UPDATE test SET data =
(select jsonb_set(data::jsonb, '{"data","sites"}', sites)
FROM test
CROSS JOIN LATERAL (
SELECT jsonb_agg(CASE WHEN site ? 'externalSite' THEN site || '{"newAttribute":"true"}'::jsonb
ELSE site
END) AS sites
FROM jsonb_array_elements( (data#>'{"data","sites"}')::jsonb ) as ja(site)
) as sub
);
Note that I cast the data to jsonb data as there are more functions and operators available for manipulating jsonb than plain json.
You can run the SELECT statement alone to see what it is doing, but the basic idea is to re-create the sites object by expanding it with jsonb_array_elements and adding the newAttribute attribute if externalSite exists.
This array is then aggregated with jsonb_agg and, finally, in the outer select, the sites object is replaced entirely with this newly computed version.

how to overwrite a one to many records in odoo through default API

how to overwrite a one to many records in odoo through odoo API ?
This is my create json, what change I want to make in this json to overwrite(Replace) the existing? lead_product_ids., now it is appending the records. Now i am getting multiple when update the records in this code instead of 0,0 what is the value,
Please help.
{
"jsonrpc": "2.0",
"params": {
"model": "crm.lead",
"method": "create",
"args": [
{
"type": "opportunity",
"name": "Fgtrdhjkkmmmmmmmm1290",
"pro_info": "Fggggggg hhhhhh jkkkkkkknjj hjkll",
"tag_ids": [
6,
0,
[
43,42
]
],
"purposes_id": 3,
"lead_product_ids": [
***0,
0,***
{
"product_uom": 21,
"product_id": 148,
"description": "",
"qty": 1,
"price_unit": 2448,
"expected_price": 2448,
"discount": 0,
"tax_id": [
6,
0,
[
22
]
],
"price_subtotal": 2741.760009765625
}
],
"partner_id": 1592,
"religion": 2,
"age_bucket": "40_45",
"phone": "5695324877",
"mobile": "5695324878",
"locations_id": 157,
"district_id": 157,
"state_id": 593
}
]
}
}
The answer is found in the docstring of the Model.write():
"""
...
This format is a list of triplets executed sequentially, where each
triplet is a command to execute on the set of records. Not all
commands apply in all situations. Possible commands are:
``(0, _, values)``
adds a new record created from the provided ``value`` dict.
``(1, id, values)``
updates an existing record of id ``id`` with the values in
``values``. Can not be used in :meth:`~.create`.
``(2, id, _)``
removes the record of id ``id`` from the set, then deletes it
(from the database). Can not be used in :meth:`~.create`.
``(3, id, _)``
removes the record of id ``id`` from the set, but does not
delete it. Can not be used on
:class:`~odoo.fields.One2many`. Can not be used in
:meth:`~.create`.
``(4, id, _)``
adds an existing record of id ``id`` to the set. Can not be
used on :class:`~odoo.fields.One2many`.
``(5, _, _)``
removes all records from the set, equivalent to using the
command ``3`` on every record explicitly. Can not be used on
:class:`~odoo.fields.One2many`. Can not be used in
:meth:`~.create`.
``(6, _, ids)``
replaces all existing records in the set by the ``ids`` list,
equivalent to using the command ``5`` followed by a command
``4`` for each ``id`` in ``ids``.
.. note:: Values marked as ``_`` in the list above are ignored and
can be anything, generally ``0`` or ``False``.
"""
It's (1, id, {'field_1': value_1,'field_2': value_2,}). But you should use write instead of create because in create it doesn't make any sense to change non-existing records of a x2many field.

Simple SQL query to Couchbase

I have the following document:
{
"postId": "Message_2D73B43390041E868694A85A65E47A09D50F019C180E93BAACC454488F67A411_1375457942227",
"userId": "User_2D73B43390041E868694A85A65E47A09D50F019C180E93BAACC454488F67A411",
"post_message": "test",
"attachments": {
"images": [
],
"audio": [
],
"videos": [
]
},
"timestamp": 1375457942227,
"followers": [
],
"follow": 0,
"reporters": [
],
"report": 0,
"rerayz": 0,
"mtype": "post"
}
I would like do the following query:
SELECT * FROM posts WHERE users in ("User_1", "User_2", "User_3") ORDER_BY timestamp LIMIT 20
I did the following and I pass multiple ?keys=["User_1", "User_2", etc] . But how can I get the results sorted by timestamp in order to get only the 20 first?
function (doc, meta) {
if(doc.mtype == "post") {
emit(doc.userId, doc.post_message);
}
}
Any suggestions?
Thanks.
I see two choices here (there are likely more):
Emit the time stamp instead of the user id. loop through the results and filter out the users you want by using code instead of asking couchbase to do it for you. Loop until you have 20 matching records.
You could emit the user id followed by the timestamp. Then search for each user in turn and grab their last 20 posts (each). Put these in some sort of array or structure and sort them (using code) by the timestap. Grab the first 20 entries in your array (which contains 60 items if you have 3 users) and you have what you need.