L'image suivante fait partie des vues système de Microsoft SQL Server 2008 R2. L'image montre que la relation entre sys.partitions
et sys.allocation_units
dépend de la valeur de sys.allocation_units.type
. Donc, pour les réunir, j'écrirais quelque chose de similaire à ceci:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3)
THEN a.container_id = p.hobt_id
WHEN a.type IN (2)
THEN a.container_id = p.partition_id
END
Mais le code supérieur donne une erreur de syntaxe. Je suppose que cela est dû à la déclaration CASE
. Quelqu'un peut-il aider à expliquer un peu?
Ajouter un message d'erreur:
Msg 102, niveau 15, état 1, ligne 6 Syntaxe incorrecte près de '='.
Une expression CASE
renvoie une valeur à partir de la partie THEN
de la clause. Vous pourriez l'utiliser ainsi:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3) AND a.container_id = p.hobt_id THEN 1
WHEN a.type IN (2) AND a.container_id = p.partition_id THEN 1
ELSE 0
END = 1
Notez que vous devez faire quelque chose avec la valeur renvoyée, par exemple. comparez-le à 1. Votre instruction a tenté de renvoyer la valeur d'une affectation ou d'un test d'égalité, ce qui n'a aucun sens dans le contexte d'une clause CASE
/THEN
. (Si BOOLEAN
était un type de données, le test d'égalité aurait alors du sens.)
Au lieu de cela, vous vous adressez simplement aux deux tables et dans votre clause SELECT, vous retournez les données de celle qui correspond:
Je vous suggère de passer par ce lien Jointures conditionnelles dans SQL Server et Instruction de cas T-SQL dans une clause JOIN ON
par exemple.
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON a.container_id =
CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
END
Edit: Selon les commentaires.
Vous ne pouvez pas spécifier la condition de jointure comme vous le faites .. Vérifiez la requête ci-dessus qui ne contient aucune erreur. J'ai sortir la colonne commune et la valeur de la colonne de droite sera évaluée à condition.
Essaye ça:
...JOIN sys.allocation_units a ON
(a.type=2 AND a.container_id = p.partition_id)
OR (a.type IN (1, 3) AND a.container_id = p.hobt_id)
Je pense que vous avez besoin de deux déclarations de cas:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON
-- left side of join on statement
CASE
WHEN a.type IN (1, 3)
THEN a.container_id
WHEN a.type IN (2)
THEN a.container_id
END
=
-- right side of join on statement
CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
END
Ceci est dû au fait:
Cela semble bien
https://bytes.com/topic/sql-server/answers/881862-joining-different-tables-based-condition
FROM YourMainTable
LEFT JOIN AirportCity DepCity ON @TravelType = 'A' and DepFrom = DepCity.Code
LEFT JOIN AirportCity DepCity ON @TravelType = 'B' and SomeOtherColumn = SomeOtherColumnFromSomeOtherTable
J'ai pris votre exemple et l'ai édité:
SELECT *
FROM sys.indexes i
JOIN sys.partitions p
ON i.index_id = p.index_id
JOIN sys.allocation_units a
ON CASE
WHEN a.type IN (1, 3)
THEN p.hobt_id
WHEN a.type IN (2)
THEN p.partition_id
ELSE NULL
END = a.container_id
Ici, j'ai comparé la différence entre deux ensembles de résultats différents. J'espère que cela pourrait être utile.
SELECT main.ColumnName, compare.Value PreviousValue, main.Value CurrentValue
FROM
(
SELECT 'Name' AS ColumnName, 'John' as Value UNION ALL
SELECT 'UserName' AS ColumnName, 'jh001' as Value UNION ALL
SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
SELECT 'Phone' AS ColumnName, NULL as Value UNION ALL
SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
SELECT 'IsActive' AS ColumnName, '1' as Value
) main
INNER JOIN
(
SELECT 'Name' AS ColumnName, 'Rahul' as Value UNION ALL
SELECT 'UserName' AS ColumnName, 'rh001' as Value UNION ALL
SELECT 'Department' AS ColumnName, 'HR' as Value UNION ALL
SELECT 'Phone' AS ColumnName, '01722112233' as Value UNION ALL
SELECT 'DOB' AS ColumnName, '1993-01-01' as Value UNION ALL
SELECT 'CreateDate' AS ColumnName, '2017-01-01' as Value UNION ALL
SELECT 'IsActive' AS ColumnName, '1' as Value
) compare
ON main.ColumnName = compare.ColumnName AND
CASE
WHEN main.Value IS NULL AND compare.Value IS NULL THEN 0
WHEN main.Value IS NULL AND compare.Value IS NOT NULL THEN 1
WHEN main.Value IS NOT NULL AND compare.Value IS NULL THEN 1
WHEN main.Value <> compare.Value THEN 1
END = 1
Pris l'exemple de DonkeyKong.
Le problème est que je devais utiliser une variable déclarée. Cela permet d'indiquer à gauche et à droite ce que vous devez comparer. Cela permet de prendre en charge un rapport SSRS dans lequel différents champs doivent être liés en fonction de la sélection effectuée par l'utilisateur.
Le cas initial définit le choix du champ en fonction de la sélection, puis je peux définir le champ sur lequel je dois faire correspondre la jointure.
Une deuxième instruction de casse peut être ajoutée pour le côté droit si la variable est nécessaire pour choisir parmi différents champs
LEFT OUTER JOIN Dashboard_Group_Level_Matching ON
case
when @Level = 'lvl1' then cw.Lvl1
when @Level = 'lvl2' then cw.Lvl2
when @Level = 'lvl3' then cw.Lvl3
end
= Dashboard_Group_Level_Matching.Dashboard_Level_Name