Quero dizer desde já que sei que isso é loucura.
Eu herdei um aplicativo que preciso manter de alguém que desnormalizou 6 conjuntos de colunas em uma única linha (por exemplo, algumas colunas principais, como ID , 00_c1, 00_c2, 00_c3, 01_c1, 01_c2, 01_c3, 02_c1, 02_c2, 02_c3, etc.).
Então ele quis normalizar novamente esse conjunto de colunas com a finalidade de criar objetos JSON a partir da linha.
Na implementação original, ele escreveu uma visão de renormalização que usava 6 UNION ALLs
por exemplo
SELECT ID, '0' as X, 00_c1 as c1, 00_c2 as c2, 00_c3 as c3
FROM table WHERE 00_c1 is not null
UNION ALL
SELECT ID, '1' as X, 01_c1 as c1, 01_c2 as c2, 01_c3 as c3
FROM table WHERE 01_c1 is not null
UNION ALL
SELECT ID, '2' as X, 02_c1 as c1, 02_c2 as c2, 02_c3 as c3
FROM table WHERE 02_c1 is not null
UNION ALL
...
Sua consulta jsonizada procura a linha em ID e então se junta à exibição em ID com FOR JSON PATH.
É extremamente ineficiente, então eu estava tentando substituir a normalização por CROSS APPLY (VALUES ())
Funcionou e é muito mais eficiente, mas estou obtendo um artefato estranho com a implementação de VALUES, onde todas as colunas em um conjunto são nulas e estou obtendo um objeto json vazio para isso.
Em outras palavras, nem todas as linhas têm todos os 6 conjuntos de colunas. Algumas podem ter 3, algumas 4, etc. e as colunas (05_c1, 05_c2, 05_c3) serão todas nulas. O json resultante para essa linha simplesmente sai {}
Existe alguma maneira (com FOR JSON ou VALUES) de ignorar uma linha onde todos os valores são nulos?
Ou a única solução real é reimplementar tudo com uma normalização adequada?
Eu encontrei meu caminho. É um pouco estranho, mas mantenho a subconsulta com as uniões, mas a consulta externa estabelece o contexto da linha. Parece complicado, mas funciona: