Il s'agit du code SQL Server.WHERE Colonne NOT LIKE ne fonctionne pas correctement avec le code récursif
Disons que vous avez une table avec trois colonnes. La colonne 1 s'appelle Monster, la colonne 2 s'appelle Level et la colonne 3 BodyType. Le niveau indique à quel point le monstre est puissant et BodyType indique le type de corps qu'il possède.
Mon schéma:
CREATE TABLE YourTable
([Monster] nvarchar(max), [Level] int, [BodyType] nvarchar(max))
;
INSERT INTO YourTable
([Monster], [Level], [BodyType])
VALUES
('Small Beast', 300, 'Scaly'),
('Large Beast', 700, 'Slimy'),
('Small Dragon', 350, 'Fiery'),
('Large Dragon', 800, 'Slimy')
;
J'ai une commande SQL pour trouver toutes les combinaisons possibles des monstres. Il utilise une cte récursive parce que le nombre de monstres dans la table peut fluctuer (donc je peux ajouter plus de monstres plus tard). La commande récupère également la valeur totale du niveau des monstres qui sont combinés. La commande ne sort également que les combinaisons de monstres qui tombent sous une certaine somme totale. Dans cet exemple, la somme totale est 1500. Tout fonctionne comme il se doit.
Ma commande sql:
;WITH cte AS (
SELECT Monster,
[Level],
BodyType,
1 as l
FROM YourTable
UNION ALL
SELECT c1.Monster+','+c2.Monster,
c1.[Level]+c2.[Level],
c1.BodyType+','+c2.BodyType,
c1.l+1
FROM cte c1
CROSS JOIN YourTable c2
WHERE c1.Monster NOT LIKE '%'+c2.Monster+'%'
)
SELECT *
FROM cte
WHERE cte.Level < 1500
ORDER BY l
OPTION (MAXRECURSION 0)
Et la sortie correcte:
1 Small Beast 300 Scaly 1
2 Large Beast 700 Slimy 1
3 Small Dragon 350 Fiery 1
4 Large Dragon 800 Slimy 1
5 Large Dragon,Small Beast 1100 Slimy,Scaly 2
6 Large Dragon,Small Dragon 1150 Slimy,Fiery 2
7 Small Dragon,Small Beast 650 Fiery,Scaly 2
8 Small Dragon,Large Beast 1050 Fiery,Slimy 2
9 Small Dragon,Large Dragon 1150 Fiery,Slimy 2
10 Large Beast,Small Beast 1000 Slimy,Scaly 2
11 Large Beast,Small Dragon 1050 Slimy,Fiery 2
12 Small Beast,Large Beast 1000 Scaly,Slimy 2
13 Small Beast,Small Dragon 650 Scaly,Fiery 2
14 Small Beast,Large Dragon 1100 Scaly,Slimy 2
15 Small Beast,Large Dragon,Small Dragon 1450 Scaly,Slimy,Fiery 3
16 Small Beast,Small Dragon,Large Beast 1350 Scaly,Fiery,Slimy 3
17 Small Beast,Small Dragon,Large Dragon 1450 Scaly,Fiery,Slimy 3
18 Small Beast,Large Beast,Small Dragon 1350 Scaly,Slimy,Fiery 3
19 Large Beast,Small Dragon,Small Beast 1350 Slimy,Fiery,Scaly 3
20 Large Beast,Small Beast,Small Dragon 1350 Slimy,Scaly,Fiery 3
21 Small Dragon,Large Dragon,Small Beast 1450 Fiery,Slimy,Scaly 3
22 Small Dragon,Large Beast,Small Beast 1350 Fiery,Slimy,Scaly 3
23 Small Dragon,Small Beast,Large Beast 1350 Fiery,Scaly,Slimy 3
24 Small Dragon,Small Beast,Large Dragon 1450 Fiery,Scaly,Slimy 3
25 Large Dragon,Small Dragon,Small Beast 1450 Slimy,Fiery,Scaly 3
26 Large Dragon,Small Beast,Small Dragon 1450 Slimy,Scaly,Fiery 3
Le problème que je rencontrais est quand j'ajoute une clause Where pour faire que de retour des monstres qui ne sont pas d'un certain type de corps (colonne BodyType). Cette partie du code de ci-dessus lorsqu'il est modifié pour y arriver est:
;WITH cte AS (
SELECT Monster,
[Level],
BodyType,
1 as l
FROM YourTable
WHERE BodyType NOT LIKE 'Fiery' AND BodyType NOT LIKE 'Slimy'
UNION ALL
La sortie est reformulé comme suit ce qui est incorrect, car il comprend encore les types de corps de gluant et Ardent:
Monster Level BodyType l
1 Small Beast 300 Scaly 1
2 Small Beast,Large Beast 1000 Scaly,Slimy 2
3 Small Beast,Small Dragon 650 Scaly,Fiery 2
4 Small Beast,Large Dragon 1100 Scaly,Slimy 2
5 Small Beast,Large Dragon,Small Dragon 1450 Scaly,Slimy,Fiery 3
6 Small Beast,Small Dragon,Large Beast 1350 Scaly,Fiery,Slimy 3
7 Small Beast,Small Dragon,Large Dragon 1450 Scaly,Fiery,Slimy 3
8 Small Beast,Large Beast,Small Dragon 1350 Scaly,Slimy,Fiery 3
La sortie semble fonctionner partiellement puisque Large Beast est Slimy et il l'a ignoré la première fois mais je soupçonne qu'il ignore la clause NOT LIKE en passant par les niveaux de BodyType et c'est pourquoi il n'ignore pas Large Beast lors des découvertes suivantes.
NOT LIKE « Slimy'' ou NOT LIKE '% Visqueux%''? Ils sont différents. – TriV
@ TriV Hi TriV, qui ne le résout toujours pas. J'ai peut-être trouvé une solution, juste besoin de confirmation c'est le code propre :) – Kian
Vous pouvez essayer ma réponse ... – TriV