J'ai une table pour laquelle je veux savoir si certaines colonnes contiennent toutes le mot «Compliant»
les colonnes sont toutes varchar.
cette requête sélectionne n'importe quelle ligne qui a Compliant dans l'une des colonnes.
Msg 156, Level 15, State 1, Line 20 Incorrect syntax near the keyword 'all'.
mais j'ai besoin qu'ils contiennent tous Compliant
J'ai essayé de remplacer tout par in mais j'ai eu cette erreur p>
SELECT curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check FROM table
where 'Compliant' in(ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check)
5 Réponses :
Vous devez être explicite ici.
WHERE ramp_running_slope_counter_slope_check = 'Compliant'
AND curb_defective_check = 'Compliant'
AND sidewalk_defective_check = 'Compliant'
AND ponding_check = 'Compliant'
etc...
Eh bien, vous n'avez pas à l'être; beaucoup de façons mignonnes de vérifier que toutes les colonnes contiennent "Conforme" mais c'est la voie que je ferais :)
@CaiusJard est sûr qu'il existe des moyens bizarres de gérer cela, mais ...
ahh ok c'est la façon la plus normale de s'y prendre - je pensais qu'il y aurait un raccourci en utilisant un mot-clé ou quelque chose. en tout cas merci
@ziggy Il y a (probablement); voir la dernière suggestion dans ma première réponse
Voici une approche "bizarre" juste pour le plaisir
Where concat(
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check
) = replicate('Compliant',18)
Avec une note de bas de page bien sûr que l'appel d'une fonction sur chaque ligne d'une table est généralement quelque chose à éviter; tue les performances pour toutes sortes de raisons
@CaiusJard La réplique est résolue une fois. 18 ANDs vs 1 concat ... Je soupçonne un impact nominal.
Quelle que soit la manière dont vous le coupez, l'appel de fonctions sur les colonnes empêche généralement l'utilisation d'index. En termes généraux, il devrait être évité dans une clause where
@CaiusJard Vous supposez que ces 18 colonnes sont indexées? Je ne suis pas.
@CaiusJard Pour être clair, personnellement, j'opterais pour les 18 AND ... ce n'était qu'une alternative.
Non, je ne suppose pas que quoi que ce soit est indexé dans ce cas particulier, mais comme j'ai mentionné le mot GENERAL dans chacun des commentaires que j'ai faits, nous devrions GÉNÉRALEMENT < / b> cherche à éviter d'appeler une fonction sur chaque ligne. Considérez que si même l'une de ces colonnes était indexée, l'approche AND utilisera l'index, l'approche concat ne sera pas
Voici une méthode que je ne recommanderais pas (mais voyez la fin de la réponse pour celle que je ferais):
SELECT curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check FROM table
where 'NonCompliant' NOT IN (ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check)
Vos colonnes devraient être 'conformes' ou autre chose (comme «non conforme»). Si la non-conformité est indiquée par un blanc, elle échouera
Vous pouvez également:
SELECT curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check FROM table
where CONCAT(ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check)
= 'CompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliantCompliant'
Je recommanderais toujours l'itinéraire de Sean de préférence à l'un ou l'autre; appeler des fonctions sur chaque ligne d'une table n'est pas cool.
.. si vous avez une valeur de «NonCompliant» ou similaire, vous pouvez inverser la logique: p>
SELECT curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check FROM table
where REPLACE(CONCAT(ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check), 'Compliant' ,'') = ''
En tant qu'autre curiosité, vous pouvez UNPIVOT et rechercher des lignes dont le nombre de conformité est de 18:
WITH unpiv as
SELECT SOME_ID_COLUMN, CheckType, Compliancy
FROM
(
SELECT
SOME_ID_COLUMN,
curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check
FROM table
) p
UNPIVOT
(Compliancy FOR CheckType IN
(
curb_reveal_check,
ramp_running_slope_counter_slope_check,
curb_defective_check,
sidewalk_defective_check,
ponding_check,
crosswalk_location_check,
gutter_slope_check,
flare_slope_check,
ramp_cross_slope_check,
ramp_width_check,
obstacles_check,
dws_check,
ramp_running_slope_check,
apex_turning_space_check,
cut_through_check,
landing_length_check,
landing_width_check,
landing_slope_check,
landing_check
)
)AS unpvt
SELECT SOME_ID_COLUMN
FROM unpiv
WHERE compliancy = 'Compliant'
GROUP BY SOME_ID_COLUMN
HAVING COUNT(*) = 18
Je suppose qu'il existe une autre colonne qui fonctionnerait comme un identifiant, pour le rendent réellement utile ...
Pour une variation mineure de la réponse de Sean, vous pouvez utiliser une sous-requête pour rendre la chaîne de recherche littérale (paramètre) un peu moins répétée:
SELECT t.stuff FROM theTable AS t INNER JOIN (SELECT ? AS searchString) AS s ON t.field1 = s.searchString AND t.field2 = s.searchString AND t.field3 = s.searchString AND t.field4 = s.searchString ... ;
Version paramétrée:
SELECT t.stuff FROM theTable AS t INNER JOIN (SELECT 'Complaint' AS searchString) AS s ON t.field1 = s.searchString AND t.field2 = s.searchString AND t.field3 = s.searchString AND t.field4 = s.searchString ... ;
TOUT ne fonctionne pas comme ça; il faut que l'élément à l'intérieur des crochets renvoie une seule colonne de plusieurs lignes et bien qu'il y ait un IN () qui fonctionne de la même manière, à savoir
WHERE some_id IN (SELECT other_id FROM othertable)que IN est peut-être mieux pensé comme IN différent de celui qui fonctionne commeIN (list, of, hardcoded, values)- il n'y a pas deALL (hardcoded, list, of, values), vous devrez faire quelques astuces pour faire pivoter votre ligne dans une colonne ... cela ne vaut pas vraiment la peine. Suivez simplement l'itinéraire mentionné par SeanJe ne vois aucun mot clé dans la requête ci-dessus.
@Rishi il a dit
J'ai essayé de remplacer ALL par IN== prendre la requête, trouver l'opérateur IN, remplacer par ALL