简体   繁体   中英

Collation issue in SQL query

I have been reading about collation in SQL, but I am still confused. Why is it that this code works fine:

...case WHEN _AccountID not in ('00000000P','0000000P9','899') THEN 'blah'

but the following does not work and produces an error message

"Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CS_AS" and "SQL_Latin1_General_CP1_CI_AS" in the equal to operation"

...case WHEN _AccountID not in (select _AccountID from tMyTable) THEN 'blah'

especially when the rest of the query is exactly the same!

Actually, I can write other queries where even the latter syntax works fine (so I wouldn't think it's because of actual column values, right?), but my above examples are both from the otherwise exact same query. I can't understand what to look for enough in my data to differentiate the queries in which it works from the queries where it doesn't work.

Collations are used to determine things like sort order and handling for case sensitivity. Collations can be set at the server, database, table and column level. So two columns in the one table could potentially have different collations. In your error message, one collation is case insensitive ( CI ) and one is case sensitive ( CS ). What we don't know yet from the information you've posted, is the server/database/tables the two columns called _AccountID are stored. Nevertheless they have different collations. CI and CS are addressed in BOL thusly:

Distinguishes between uppercase and lowercase letters. If selected, lowercase letters sort ahead of their uppercase versions. If this option is not selected, the collation is case-insensitive. That is, SQL Server considers the uppercase and lowercase versions of letters to be identical for sorting purposes. You can explicitly select case insensitivity by specifying _CI.

One workaround assuming the first _AccountID has a different collation to the database's default collation (and the second one uses the database default), might be:

...case WHEN _AccountID collate database_default not in (select _AccountID from tMyTable) THEN 'blah'

As an aside, assuming you're using SQL Server, you might want to consider using

WHERE NOT EXISTS (SELECT * FROM from tMyTable tbl WHERE tbl._AccountID = <the_other>._AccountID)

...which will perform better than WHERE NOT IN (SELECT...)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM