0
votes

Comment interroger la colonne multi-valorise par clé dans SQL Server

Comment interroger une colonne Multivé pour une clé spécifique?

échantillons de données xxx

par exemple:

Sélectionnez ... où la touche du jour = '02'

attendu: xxx

notes

La table réelle a plus de 30 champs.

Joindre plusieurs croix Appliquer Split_string ressemblait à une solution fastidieuse


8 commentaires

Il existe une fonction appelée string_split pour la version 2016+ si c'est le vôtre.


@ Barbarosözhan je l'ai essayé. Vous auriez besoin de ré-construire le champ de la table source par champ, puis de vous joindre. La table réelle a plus de 30 champs ... j'espérais un moyen plus intelligent de faire cela


@CHARLESOKWUAGWU, la plus intelligente est de stocker des détails dans une table séparée. Si le refactoring de la DB n'est pas possible, utilisez [Delimitedsplit8k_lead] SP qui contrairement à string_split retourne les jetons numérotés, vous pouvez donc facilement correspondre à des jetons de deux (30) colonnes par le Numéro de jeton.


@Serg va essayer, merci


Idéalement, vous devez corriger votre conception, en la normalisant et ne pas stocker de multiples valeurs en une seule valeur.


Les solutions fastidieuses sont souvent le prix que vous payez pour une mauvaise conception de base de données.


Pas mon design ... Les données ont été chargées à partir d'une plate-forme MV, j'essaie simplement de déplacer certaines parties de SQL Server.


@Larnu Vous voyez l'extrait que j'ai inclus de l'ETL, nous héritons / dois gérer les systèmes existants, pas toujours jolie


4 Réponses :


2
votes

Voici une option qui pivotera de manière dynamique de vos données (sans utiliser de manière dynamique SQL), puis pivotez les résultats.

Vous devrez simplement répertorier les 30 colonnes dans le pour l'élément (.. .) portion

CROST Appliquer b convertira la ligne en xml

croix applicatif UNPIVOT LE XML

CROST Appliquer D PAR analysez / divisera la chaîne délimitée (avec une séquence) de C

Ensuite, il devient une petite affaire pour le pivot

Exemple xxx

retours xxx


0 commentaires


1
votes

Si vous pouvez créer une fonction supplémentaire dans votre base de données, vous pouvez utiliser ce script suivant pour obtenir votre sortie souhaitée.

Créer une fonction: strong> p>

DECLARE @S_String VARCHAR(20) = '05'
DECLARE @S_String_New VARCHAR(20) = ';'+@S_String+';'

SELECT 
REVERSE(
    SUBSTRING(
        REVERSE(
            SUBSTRING(
                ';'+Day+';',
                0, 
                (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String)) +1
            )
        ),
        0,
        CHARINDEX(
            ';',
            REVERSE(SUBSTRING(';'+Day+';',0, (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String)) +1)),
            0
        )
    )
),

REVERSE(
    SUBSTRING(
        REVERSE(
            SUBSTRING(
                ';'+PRICE+';',
                0,    
                (
                    dbo.FIND_CHARINDEX(
                        ';',
                        ';'+PRICE+';',
                        (
                            LEN(SUBSTRING(';'+Day+';',0, (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String)) +1)) 
                                - LEN(REPLACE(SUBSTRING(';'+Day+';',0,  (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String))  +1),';',''))+1
                        )
                    )
                )
            )
        ),
        0,
        CHARINDEX(
            ';',
            REVERSE(
                SUBSTRING(
                    ';'+PRICE+';',
                    0,    
                    (
                        dbo.FIND_CHARINDEX(
                            ';',
                            ';'+PRICE+';',   
                            (
                                LEN(SUBSTRING(';'+Day+';',0, (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String)) +1)) 
                                    - LEN(REPLACE(SUBSTRING(';'+Day+';',0,  (CHARINDEX(@S_String_New,';'+Day+';',0)+LEN(@S_String))  +1),';',''))+1
                            )
                        )
                    )
                )
            ),
            1
        )
    )
)
FROM your_table
WHERE ';'+Day+';' LIKE '%'+@S_String_New+'%'


0 commentaires

2
votes

Cette solution utilise CTE et j'espère que cela fonctionne pour vous:

with cte1 as
( 
select id, value daykey,
 row_number() over(order by (select null)) as rowid
from mvct
cross apply string_split(day, ";")
),
cte2 as
(
select id, value pricekey,
 row_number() over(order by (select null)) as rowid
from mvct
cross apply string_split(price, ";")
)
select cte1.id, cte1.daykey, cte2.pricekey
from cte1
inner join cte2 on cte1.id = cte2.id
and cte1.rowid = cte2.rowid
and cte1.daykey = "02"


1 commentaires

Merci, j'ai finalement utilisé une variante de ceci - c'était la solution la plus simple