1
votes

SQL Server sélectionne les lignes qui ont 1 valeur dans TOUTES les colonnes

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)


3 commentaires

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 comme IN (list, of, hardcoded, values) - il n'y a pas de ALL (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 Sean


Je 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


5 Réponses :


2
votes

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...


4 commentaires

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



1
votes

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)


6 commentaires

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



0
votes

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.

Tout cela dit

.. 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' ,'') = ''


0 commentaires

0
votes

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 ...


0 commentaires

0
votes

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
   ...
;


0 commentaires