web-dev-qa-db-fra.com

Utilisation d'une vérification d'égalité entre les colonnes dans une clause SELECT

J'utilise Microsoft SQL Server 2012 et je voudrais exécuter cette requête apparemment simple:

SELECT 
    FirstEvent.id AS firstEventID, 
    SecondEvent.id AS secondEventID, 
    DATEDIFF(second, FirstEvent.WndFGEnd, SecondEvent.WndFGStart) AS gap, 
    FirstEvent.TitleID = SecondEvent.TitleID AS titlesSameCheck
FROM VibeFGEvents AS FirstEvent
RIGHT OUTER JOIN VibeFGEvents AS SecondEvent
ON 
    FirstEvent.intervalMode = SecondEvent.intervalMode 
    AND FirstEvent.id = SecondEvent.id - 1 
    AND FirstEvent.logID = SecondEvent.logID

Cependant FirstEvent.TitleID = SecondEvent.TitleID AS titlesSameCheck dans la clause SELECT est une syntaxe incorrecte. Mais la documentation SELECT Clause (Transact-SQL) inclut cette syntaxe:

SELECT [ ALL | DISTINCT ]
[ TOP ( expression ) [ PERCENT ] [ WITH TIES ] ] 
<select_list> 
<select_list> ::= 
    { 
        * 
        | { table_name | view_name | table_alias }.* 
        | {
            [ { table_name | view_name | table_alias }. ]
                { column_name | $IDENTITY | $ROWGUID } 
            | udt_column_name [ { . | :: } { { property_name | field_name } 
            | method_name ( argument [ ,...n] ) } ]
            | expression
            [ [ AS ] column_alias ] 
            }
        | column_alias = expression 
    } [ ,...n ]

Je pense que cela signifie qu'une expression est valide dans la clause select et en effet les exemples donnés incluent des choses comme 1 + 2. En regardant la documentation des expressions :

{ constant | scalar_function | [ table_name. ] column | variable 
    | ( expression ) | ( scalar_subquery ) 
    | { unary_operator } expression 
    | expression { binary_operator } expression 
    | ranking_windowed_function | aggregate_windowed_function
}

les vérifications d'égalité booléennes sont des expressions valides et en effet l'exemple d'exemple donné dans la documentation = (Equals) (Transact-SQL) en inclut une:

SELECT DepartmentID, Name
FROM HumanResources.Department
WHERE GroupName = 'Manufacturing'

bien que dans la clause WHERE pas dans la clause SELECT. Il semble que je ne puisse pas utiliser = l'opérateur d'égalité pour comparer les expressions dans ma clause SELECT car elles sont interprétées à tort comme une affectation.

Comment puis-je inclure une comparaison de colonnes d'égalité booléenne équivalente à FirstEvent.TitleID = SecondEvent.TitleID AS titlesSameCheck dans ma clause SELECT?

26
dumbledad

Comme ça:

case when FirstEvent.TitleID = SecondEvent.TitleID then 1 else 0 end as titlesSameCheck 
30
Dumitrescu Bogdan

Vous ne pouvez pas utiliser le type booléen directement, sauf dans les instructions conditionnelles (cas, où, avoir, etc.)

La meilleure façon de résoudre votre problème est de faire quelque chose comme

select case when x = y then 'true' else 'false' end

Le type bit est probablement le plus proche de booléen.

select CAST(case when x = y then 1 else 0 end as bit)

Bien sûr, utilisez les deux valeurs qui représentent le mieux ce que vous recherchez.

14
pyrospade

Comme l'indiquent les deux réponses existantes, les valeurs booléennes ne peuvent pas être renvoyées en tant que valeur de colonne. Ceci est documenté dans la section Opérateurs de comparaison :

Contrairement à d'autres types de données SQL Server, un type de données booléen ne peut pas être spécifié comme type de données d'une colonne ou d'une variable de table et ne peut pas être renvoyé dans un jeu de résultats.

Étant donné cette restriction, utiliser CASE pour transformer la valeur en quelque chose qui peut être affiché est votre meilleure alternative.

1
Allan