Showing posts with label SQL. Show all posts
Showing posts with label SQL. Show all posts

Tuesday, February 20, 2024

SQL - Defined vs Dynamic table column values into JSON

 Convert Defined vs Dynamic table column values into JSON using SQL Syntax, using SQL Pivot and Subquery execution achieved to construct JSON,


IF OBJECT_ID('tempdb..#tempDefinedTable1') IS NOT NULL

       DROP TABLE #tempDefinedTable1

IF OBJECT_ID('tempdb..#tempDefinedTable2') IS NOT NULL

       DROP TABLE #tempDefinedTable2

IF OBJECT_ID('tempdb..#tempAllColumns') IS NOT NULL

       drop table #tempAllColumns

IF OBJECT_ID('tempdb..#tempMatchedColumns') IS NOT NULL

       drop table #tempMatchedColumns

IF OBJECT_ID('tempdb..#tempUnMatchedColumns') IS NOT NULL

       drop table #tempUnMatchedColumns

 


--create some defined column names as values

 create table #tempDefinedTable1 (

 definedcolnames varchar(max)

)

insert into #tempDefinedTable1

values ('col1'),('col2')

 

select * from #tempDefinedTable1

 

-- create table with defined columns + dynamic columns

create table #tempDefinedTable2 (

id int,

col1 varchar(max),

col2 varchar(max),

dynamicCol1 varchar(max),

dynamicCol2 varchar(max)

)

 

insert into #tempDefinedTable2

values (1, 'a1', 'b1', 'c1', 'd1'),(2, 'a2', 'b2', 'c2', 'd2')

 

select * from #tempDefinedTable2

  

--From the defined+dynamic column list, consolidate columns as values

Select C.* into #tempAllColumns

 From #tempDefinedTable2 A

 Cross Apply ( values (cast((Select A.* for XML RAW) as xml))) B(XMLData)

 Cross Apply (

                Select ColumnName  = a.value('local-name(.)','varchar(100)')

                      ,ColumnValue = a.value('.','varchar(max)')

                                     ,Id

                 From  B.XMLData.nodes('/row')  as C1(n)

                 Cross Apply C1.n.nodes('./@*') as C2(a)

                 Where a.value('local-name(.)','varchar(100)') not in ('ID','ExcludeOtherCol')

             ) C

 

select Id, ColumnName, ColumnValue from #tempAllColumns

 

--now preparing sql sub query to list defined columns in root level, dynamic columns as nested object

DECLARE @Columns as VARCHAR(MAX)

 

SELECT @Columns = COALESCE(@Columns + ', ','') + QUOTENAME([ColumnName])

FROM

    (SELECT DISTINCT ColumnName FROM #tempAllColumns st

       JOIN #tempDefinedTable1 tt on tt.definedcolnames = st.ColumnName

       WHERE tt.definedcolnames is not null) AS B

ORDER BY B.ColumnName

 

select @Columns as DefinedColumns

 

 

DECLARE @DynamicColumns as VARCHAR(MAX)

SELECT @DynamicColumns = COALESCE(@DynamicColumns + ', ','') + QUOTENAME([ColumnName])

FROM

    (SELECT DISTINCT ColumnName FROM #tempAllColumns st

       LEFT JOIN #tempDefinedTable1 tt on tt.definedcolnames = st.ColumnName

       WHERE tt.definedcolnames is null) AS B

ORDER BY B.ColumnName

select @DynamicColumns  as UndefinedColumns

 

DECLARE @SQL as VARCHAR(MAX)

SET @SQL = 'SELECT Id,' + @Columns + ',

       (SELECT PR1.Id,' + @DynamicColumns + ' FROM (select st1.Id, st1.[ColumnName], st1.ColumnValue from #tempAllColumns st1

        LEFT JOIN #tempDefinedTable1 tt1 on tt1.definedcolnames = st1.ColumnName

        WHERE tt1.definedcolnames is null) as PD2

        PIVOT (

          max(ColumnValue)

          FOR [ColumnName] IN (' + @DynamicColumns + ')

       ) AS PR1

       WHERE PR1.Id = PR.Id

       ORDER BY Id

       FOR JSON PATH, INCLUDE_NULL_VALUES) as ExtraFields

FROM

(

 select Id,[ColumnName],ColumnValue from #tempAllColumns st

 JOIN #tempDefinedTable1 tt on tt.definedcolnames = st.ColumnName

 WHERE tt.definedcolnames is not null

) as PD

PIVOT

(

   max(ColumnValue)

   FOR [ColumnName] IN (' + @Columns + ')

) AS PR

ORDER BY Id

FOR JSON PATH, INCLUDE_NULL_VALUES'

 

EXEC(@SQL);

 

Columns:


Output:





Monday, August 24, 2020

SQL - Modify Array of JSON

 How to copy one array of JSON object into another array of JSON in SQL. Take this below sample copy array of empIds from one JSON into another JSON


DECLARE  @pArrayOfIntEmps nvarchar(max)='{ "empIds": [' + '1,2'+'] }'

--JSON_Query will return array value from json whereas JSON_VALUE return object value from json

--select JSON_QUERY(@pArrayOfIntEmps,'$.empIds') 

 

DECLARE @info NVARCHAR(max)='{"id":1,"abc":false,"empIds":[3,4] }'

SET @info=  JSON_MODIFY(ISNULL(@info,'{}'),'$.empIds,JSON_QUERY(@pArrayOfIntEmps,'$.empIds'))

select @info

 

--Output {"id":1,"abc":false,"empIds":[1,2] }, this empIds will be replaced by array of int

Tuesday, August 7, 2018

SQL - Split different column names display with separator

In some situation, we need to show separator for firstname and middlename. This can be comma if there some values.

Lets take sample of employees data as below


With EmployeeCTE AS (
    SELECT * FROM (VALUES (1, 'Balaji', NULL),
    (2, 'Siva', NULL),
    (3,'Balaji', 'Prasad'),
    (4,NULL,'Raj'),
    (5,NULL,NULL),
    (6,'Karthi','m')) as E(Sno,FirstName,MiddleName) )


Now query this to get comma separate names out of this
      
SELECT    
p.sno,p.firstname,p.middlename,
IsNull(p.FirstName, '')
+ CASE
 WHEN p.MiddleName = ''
 THEN ''
 WHEN (IsNull(p.FirstName, '') <> '' and IsNull(p.MiddleName, '') <> '')
 THEN IsNull(', ' + p.MiddleName, '')
 ELSE IsNull(p.MiddleName, '') END As Name
FROM  EmployeeCTE AS p


Now the output will come as comma separated if there values present in firstname or lastname

sno
firstname
middlename
Name
1
Balaji
NULL
Balaji
2
Siva
NULL
Siva
3
Balaji
Prasad
Balaji, Prasad
4
NULL
Raj
Raj
5
NULL
NULL

6
Karthi
m
Karthi, m