Eu tenho uma tabela que contém mais de 80 colunas esparsas junto com uma coluna de conjunto de colunas, este é um breve exemplo:
DROP TABLE IF EXISTS #ColumnSet
GO
CREATE TABLE #ColumnSet
(
Id INT NOT NULL
, Value1 VARCHAR(100) SPARSE NULL
, Value2 VARCHAR(100) SPARSE NULL
, Value3 VARCHAR(100) SPARSE NULL
, Value4 VARCHAR(100) SPARSE NULL
, AllValues XML COLUMN_SET FOR ALL_SPARSE_COLUMNS
)
GO
INSERT INTO #ColumnSet
(Id, Value1, Value2, Value3, Value4)
VALUES
(1, 'POSITIVE', NULL, NULL, NULL),
(2, 'NEGATIVE', NULL, 'NEGATIVE', NULL),
(3, NULL, NULL, 'NEGATIVE', 'POSITIVE'),
(4, 'NEGATIVE', NULL, 'THIS IS NOT A POSITIVE RESULT', NULL)
GO
Eu quero consultar o conjunto de colunas para identificar as linhas em que qualquer uma das colunas tem um valor POSITIVO.
Usar o value
método no conjunto de colunas concatenará todos os valores em uma string e eu poderia usar LIKE
, mas não quero resultados em que o valor esteja dentro de outra string.
SELECT
*
FROM
#ColumnSet
WHERE
AllValues.value('/', 'nvarchar(4000)') LIKE '%POSITIVE%'
Existem métodos alternativos de consultar um conjunto de colunas para alcançar o acima? Usar APPLY
junto com o nodes
método fornece a mesma saída de string concatenada, embora minha sintaxe possa estar incorreta.
A saída necessária:
id
1
3
Especificar o
text()
nó antes do predicado será mais eficiente do que tertext()
no predicado.Plano de consulta com texto no predicado
AllValues.exist('*[text() = "POSITIVE"]') = 1
Aqui está uma solução XPath, embora eu não saiba o quão eficiente ela será.
Aqui está outra solução xquery:
Como você alterou seus dados de amostra, o procedimento acima não funcionará.
Você poderia fazer isso em vez disso:
Mas não tenho certeza de como isso competirá com a resposta de Mikael em escala.