MySQL JSON column add new array as element - mysql

I have a table with JSON type column, I want to update a column with new array element in existing JSON.
What needs to be done: add an array in JSON column when employee punch_in and add another array in JSON column when employee punch_out.
{"emp_sheet":[{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"},{"rulecode":"PUNCH_OUT","result":1,"applytime":"2018-04-12 13:01:39"}]}
What I did, for employee punch_in:
UPDATE table
SET rule_codes = JSON_SET(COALESCE(rule_codes, '{}'), '$.emp_sheet', '{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}')
WHERE emp_id = 1
Result in rule_codes column =
{"emp_sheet": "{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}"}
Please help me to write update query for employee punch_out.

This would be easiest if you made $.emp_sheet a JSON array on punch in:
UPDATE table3
SET rule_codes = JSON_SET(COALESCE(rule_codes, JSON_OBJECT('emp_sheet', JSON_ARRAY())),
'$.emp_sheet[0]',
'{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}')
WHERE emp_id = 1
Then on punch out, you can add another element to the array:
UPDATE table3
SET rule_codes = JSON_SET(COALESCE(rule_codes, JSON_OBJECT('emp_sheet', JSON_ARRAY())),
'$.emp_sheet[1]',
'{"rulecode":"PUNCH_OUT","result":1,"applytime":"2018-04-12 13:01:39"}')
WHERE emp_id = 1;
SELECT rule_codes FROM table3 WHERE emp_id = 1
Output:
{"emp_sheet": [
"{\"rulecode\":\"PUNCH_IN\",\"result\":1,\"applytime\":\"2018-04-12 04:50:39\"}",
"{\"rulecode\":\"PUNCH_OUT\",\"result\":1,\"applytime\":\"2018-04-12 13:01:39\"}"
]}
Note that when you do the SET, the input JSON ('{"rulecode ... }') gets treated as a string, hence the escaped " in the output above. You can remove those with JSON_UNQUOTE when you extract i.e.
SELECT JSON_UNQUOTE(JSON_EXTRACT(rule_codes, '$.emp_sheet[0]')) FROM `table3`
or using the short-cut notation
SELECT rule_codes->>'$.emp_sheet[0]' FROM `table3`
Output:
{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}

Try to use JSON_ARRAY_APPEND instead of JSON_SET.
Manual - https://dev.mysql.com/doc/refman/8.0/en/json-modification-functions.html
I think it could be like this
rule_codes = JSON_ARRAY_APPEND(COALESCE(rule_codes, '{"emp_sheet":[]}'), '$.emp_sheet', '{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}')
or
rule_codes = IF(rule_codes IS NULL,'
'{"emp_sheet":[{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}]}',
JSON_ARRAY_APPEND(rule_codes, '$.emp_sheet', '{"rulecode":"PUNCH_IN","result":1,"applytime":"2018-04-12 04:50:39"}')
)

Related

Query SQL database with JSON Value

Here is my JSON:
[{"Key":"schedulerItemType","Value":"schedule"},{"Key":"scheduleId","Value":"82"},{"Key":"scheduleEventId","Value":"-1"},{"Key":"scheduleTypeId","Value":"2"},{"Key":"scheduleName","Value":"Fixed Schedule"},{"Key":"moduleId","Value":"5"}]
I want to query the database by FileMetadata column
I've tried this:
SELECT * FROM FileSystemItems WHERE JSON_VALUE(FileMetadata, '$.Key') = 'scheduleId' and JSON_VALUE(FileMetadata, '$.Value') = '82'
but it doesn't work!
I had it working with just a dictionary key/value pair, but I needed to return the data differently, so I am adding it with key and value into the json now.
What am I doing wrong?
With the sample data given you'd have to supply an array index to query the 1th element (0-based array indexes), e.g.:
select *
from dbo.FileSystemItems
where json_value(FileMetadata, '$[1].Key') = 'scheduleId'
and json_value(FileMetadata, '$[1].Value') = '82'
If the scheduleId key can appear at arbitrary positions in the array then you can restructure the query to use OPENJSON instead, e.g.:
select *
from dbo.FileSystemItems
cross apply openjson(FileMetadata) with (
[Key] nvarchar(50) N'$.Key',
Value nvarchar(50) N'$.Value'
) j
where j.[Key] = N'scheduleId'
and j.Value = N'82'

mysql update json attribute and another column in one query

I need to update a json value in a column as well as update another column in the same query.
Something like this:
UPDATE fixtures
SET jsonResults = '{}',
JSON_SET(jsonFixture, '$.time_status', '0')
WHERE intRefID = 88961323;
How can I accomplish this?
JSON_SET() returns a JSON document value, but an UPDATE statement needs a series of assignment expressions:
UPDATE fixtures
SET jsonResults = '{}',
jsonFixture = JSON_SET(jsonFixture, '$.time_status', '0')
WHERE intRefID = 88961323;
This replaces jsonFixture with the result of JSON_SET(), after setting a field within that document.
Compare with an UPDATE like this:
UPDATE mytable
SET i = i + 1
WHERE ...
It takes the value of i, adds 1, and then uses the result of that addition expression to replace i.

How to retrieve a value in a json object in sqlite when the key is an empty string?

I am processing an sqlite table which contains json objects. These json objects have keys that are empty strings. How can I retrieve the value? For example:
select json_extract('{"foo": "bar", "":"empty"}', '$.foo') as data;
-result: "bar"
How can I retrieve "empty"?
Using your example:
sqlite> SELECT value FROM json_each('{"foo":"bar","":"empty"}') WHERE key = '';
value
----------
empty
As part of a larger query from a table:
SELECT (SELECT j.value FROM json_each(t.your_json_column) AS j WHERE j.key = '') AS data
FROM your_table AS t;

Update SQL records with values from another record

I'm spinning in circles trying to figure out what is likely a very simple SQL structure. My task seems simple - within the same table I need to update 3 related records with data from one master record. The master coordinates are in the record with a class of 'T', and I want to insert that record's coordinates into the rx_latitude/longitude columns of the related records with class code 'R'
The table structure is: callsign, class, tx_latitude, tx_longitude, rx_latitude, rx_longitude. Sample data looks like this:
J877, T, 40.01, -75.01, 0, 0
J877, R, 39.51, -75.21, 0, 0
J877, R, 40.25, -75.41, 0, 0
J877, R, 39.77, -75.61, 0, 0
Within that same table, I want to populate all of the rx_latitude and rx_longitude fields where the class is 'R' with the tx_latitude and tx_longitude coordinates where the class is 'T' and the callsign matches.
I've tried several insert and update statements, but I can only seem to operate on the master record, not the related records. I would appreciate any guidance that you might offer.
You can use UPDATE...FROM statement:
UPDATE theTable
SET
tx_latitude = masterRecord.tx_latitude,
tx_longitude = masterRecord.tx_longitude
FROM
(SELECT tx_latitude,tx_longitude,callsign FROM theTable WHERE class='T') masterRecord
WHERE
class='R' AND callsign = masterRecord.callsign
Updated
Try :
update yourTable t1, yourTable t2 set
t1.tx_latitude = t2.tx_latitude,
t1.tx_longitude = t2.tx_longitude
where t1.class = 'R' and t2.class = 'T' and t1.callsign = t2.callsign
Example
You can use MySQL's update ... join syntax.
It would go something like this:
update yourtable toUpdate
left join yourtable masterRecordTable
on toUpdate.callsign = masterRecordTable.callsign and masterRecordTable.class = 'T'
set toUpdate.rx_latitude = masterRecordTable.tx_latitude,
toUpdate.rx_longitude = masterRecordTable.tx_longitude
where toUpdate.callsign = 'J877' and toUpdate.class = 'R'
See this fiddle for a working example

Merge not inserting. No error

Can someone tell me why this insert is failing but not giving me an error either? How do I fix this?
merge table1 as T1
using(select p.1,p.2,p.3,p.4,p.5 from #parameters p
inner join table1 t2
on p.1 = t2.1
and p.2 = t2.2
and p.3 = t2.3
and p.4 = t2.4) as SRC on SRC.2 = T1.2
when not matched then insert (p.1,p.2,p.3,p.4,p.5)
values (SRC.1,SRC.2,SRC.3,SRC.4,SRC.5)
when matched then update set t1.5 = SRC.5;
The T1 table is currently empty so nothing can match. The parameters table does have data in it. I simply need to modify this merge so that it checks all 4 fields before deciding what to do.
You can't select from a variable: from #parameters
See the following post: Using a variable for table name in 'From' clause in SQL Server 2008
Actually, you can use a variable table. Check it out:
MERGE Target_table AS [Target]
USING #parameters AS [Source]
ON (
[Target].col1 = [Source].col1
AND [Target].col2 = [Source].col2
AND [Target].col3 = [Source].col3
AND [Target].col4 = [Source].col4
)
WHEN NOT MATCHED BY TARGET
THEN INSERT (col1,col2,col3,col4,col5)
VALUES (
[Source].col1
,[Source].col2
,[Source].col3
,[Source].col4
,[Source].col5
)
WHEN MATCHED
THEN UPDATE SET [Target].col5 = [Source].col5;