J'ai une table qui ressemble à ceci: pour chaque identifiant, je voudrais récupérer une valeur. Idéalement, la valeur devrait venir de la ligne avec type Z01. Cependant, si Z01 n'est pas disponible, je choisirai la Z09 à la place. Si rien n'est disponible, je voudrais ne rien sélectionner. P> Le résultat ressemblerait à ceci: p> Comment puis-je accomplir cela avec T-SQL? p> p>
6 Réponses :
Cela devrait vous donner ce que vous voulez: une alternative, avec une approche plus courante, c'est (réécrire le cas code> expression code>): p> Une approche évidente et quand je dis index, je parle d'un index non clusterné sur la colonne code> code>. p> p> Sargable code> (qui permettra à votre requête d'utiliser l'index approprié sur votre table, si elle existe) serait: p> < Pré> xxx pré>
C'est un moyen compliqué d'aborder le problème. Une expression de cas n'appartient pas à un où code> clause. Utilisez et code>, ou code> et entre parenthèses à la place.
@Thorstenkettner pourrait être, mais je suppose qu'ils sont les mêmes identiques. Et pourquoi l'expression code> code> appartient-elle dans un où la clause CODE>? Je suis curieux si vous en avez des exemples pour cela.
C'est aussi un non sargable Query et aura une très mauvaise performance.
@Erikphilipips basé sur quelles règles ma requête devient-elle non sargable? Malheureusement (pour moi), je ne vois pas pourquoi c'est. Est-ce à cause du ou code>?
Bonjour, comme vous l'avez montré avec votre deuxième requête, vous pouvez écrire n'importe quelle expression booléenne dans où code> et c'est plus simple. Il n'y a pas besoin d'une construction qui vous permet de créer une valeur d'une expression booléenne dans où code>. Case Code> est effectué pour le Sélectionnez CODE> et Commandez par CODE> Les clauses permettent d'évaluer une expression booléenne là-bas.
@RADUGHEORGHIU Votre message original avec seulement la requête utilisée par la déclaration de cas nécessite une analyse de cas pour chaque ligne, ce qui signifie qu'il est non sargable.
@Erikphilips Même donc, il n'ya presque aucun moyen de garantir un indice de recherche sans en savoir plus sur la structure de la table. Mais, en termes d'utilisation de l'indice, s'il existe un indice sur la colonne code> code>, une approche utilisera définitivement (même s'il s'avère être une analyse d'index).
Vous pouvez utiliser une requête comme celle-ci
;WITH cte
AS (SELECT
*, ROW_NUMBER() OVER (PARTITION BY id ORDER BY type) AS rn
FROM yourtable
WHERE type IN ('Z01', 'Z09'))
SELECT
id, type, value
FROM cte
WHERE rn = 1
Je voudrais utiliser les fonctions de fenêtre:
select t.*
from (select t.*,
row_number() over (partition by id order by type) as seqnum
from t
where type in ('Z01', 'Z09')
) t
where seqnum = 1;
Essayez ensuite cette
Select distinct a.id,
coalesce(t1.type, t9.type) type,
case when t1.type is not null
then t1.value else t9.value end value
From table a
left join table t1
on t1.id = a.id
and t1.type = 'Z01'
left join table t9
on t9.id = a.id
and t9.type = 'Z09'
Where a.type in ('Z01', 'Z09') -- < -- this last to eliminate row E
quelque chose comme ceci:
select distinct
base.Id,
Coalesce(z01.Type, any.Type) Type,
Coalesce(z01.Value, any.Value)
from (select distinct id from [table]) base
left outer join [table] z01
on z01.id = base.id
and z01.Type = 'Z01'
left outer join [table] any
on any.id = base.id
and any.type != 'Z01'
Démarrer avec un où code> clause. Sélectionnez uniquement les entrées avec Z01 et Z09. Ensuite, utilisez row_number code> pour classer vos lignes et garder le meilleur. select id, type, value
from
(
select
id, type, value,
row_number()
over (partition by id order by case when type = 'Z01' then 1 else 2 end) as rn
from mytable
where type in ('Z01','Z09')
) ranked
where rn = 1;
Désolé, cela était censé être dans la table d'origine. Corrigé-le maintenant.