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 4 (of 4 total)
You must be logged in to reply to this topic. Login to reply
This website stores cookies on your computer.
These cookies are used to improve your website experience and provide more personalized services to you, both on this website and through other media.
To find out more about the cookies we use, see our Privacy Policy