I receive data in JSON files and for one particular type of data I am having problems getting it into a sensible SQL format. The data consists of an ID and a JSON array of bank accounts belonging to that ID. For the data below, I want one row for ID 4710592 with the data where field "pri" is Bert and another row where it is Bob (note: this field isn't necessarily populated in the actual data).
CREATE TABLE #temptable ( [id] nvarchar(4000), [entry] nvarchar(4000) )
INSERT INTO #temptable ([id], [entry])
VALUES
( N'4710592', N'[
{"pri":"Bert"}
,{"is_pens_pay":""}
,{"acc_nr":"12345678"}
,{"curry_id":55}
,{"limit":""}
,{"acc_name":"Mr. J. Smith"}
,{"acc_nick_name":"J. Smith--GBP"}
,{"init_deposit_amt":""}
,{"is_main":"true"}
,{"is_third_party":""}
,{"bank_name":"NATIONAL WESTMINSTER BANK PLC"}
,{"bank_addr":"NATIONAL WESTMINSTER BANK PLC Leicester"}
,{"sort_code_nr":"123456"}
,{"pri":"Bob"}
,{"is_pens_pay":"True"}
,{"acc_nr":"98765432"}
,{"curry_id":56}
,{"limit":"20000.00"}
,{"acc_name":"Mr. J. Smith No. 2 account"}
,{"acc_nick_name":"J. Smith--USD"}
,{"init_deposit_amt":"1204.53"}
,{"is_main":"False"}
,{"is_third_party":""}
,{"bank_name":"SANTANDER"}
,{"bank_addr":"SANTANDER Moorgate"}
,{"sort_code_nr":"654321"}
]'
)
When I run the query below, I get as many rows per ID value as there are columns and only one column is populated on each row. I've tried using PIVOT, but that only gives me a single row per ID with the MAX (or MIN or whatever other aggregate function I use) per column. I'm sure there must be a relatively easy way to do this, but I'm stumped. Any assistance would be gratefully received.
SELECT *
FROM #temptable t
CROSS APPLY OPENJSON(t.entry)
WITH (
pri NVARCHAR(4000),
is_pens_pay NVARCHAR(4000),
acc_nr NVARCHAR(4000),
curry_id NVARCHAR(4000),
limit NVARCHAR(4000),
acc_name NVARCHAR(4000),
acc_nick_name NVARCHAR(4000),
init_deposit_amt NVARCHAR(4000),
is_main NVARCHAR(4000),
is_third_party NVARCHAR(4000),
bank_name NVARCHAR(4000),
bank_addr NVARCHAR(4000),
sort_code_nr NVARCHAR(4000)
) oj
PS: The only unique identifier for the entries in the array would be a combination of columns - for the sample data the sort_code_nr and acc_nr combination is unique.
Maybe this?
WITH CTE AS (
SELECT t.id,
j2.[key] AS field,
j2.value AS val,
row_number() over(partition by j2.[key] order by cast(j.[key] as int)) as rn
FROM #temptable t
CROSS APPLY OPENJSON(t.entry) j
CROSS APPLY OPENJSON(j.value) j2
)
SELECT id,
MAX(CASE WHEN field='pri' THEN val END) AS pri,
MAX(CASE WHEN field='is_pens_pay' THEN val END) AS is_pens_pay,
MAX(CASE WHEN field='acc_nr' THEN val END) AS acc_nr,
MAX(CASE WHEN field='curry_id' THEN val END) AS curry_id,
MAX(CASE WHEN field='limit' THEN val END) AS limit,
MAX(CASE WHEN field='acc_name' THEN val END) AS acc_name,
MAX(CASE WHEN field='acc_nick_name' THEN val END) AS acc_nick_name,
MAX(CASE WHEN field='init_deposit_amt' THEN val END) AS init_deposit_amt,
MAX(CASE WHEN field='is_main' THEN val END) AS is_main,
MAX(CASE WHEN field='is_third_party' THEN val END) AS is_third_party,
MAX(CASE WHEN field='bank_name' THEN val END) AS bank_name,
MAX(CASE WHEN field='bank_addr' THEN val END) AS bank_addr,
MAX(CASE WHEN field='sort_code_nr' THEN val END) AS sort_code_nr
FROM CTE
GROUP BY id,rn
ORDER BY id,rn;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537July 1, 2022 at 11:21 am
Thanks. That works perfectly.
July 4, 2022 at 7:48 am
In case anyone else comes across this as the solution to a similar problem, I had to add ral.id to the partition in order to get it to work with my full data set (ie. the original sample data didn't cover all scenarios).
Viewing 4 posts - 1 through 3 (of 3 total)
You must be logged in to reply to this topic. Login to reply