字符串比较的意外结果

时间:2018-07-27 12:52:36

标签: sql sql-server string tsql

我无法理解以下行为:

WITH tests(min, val, max) AS (
    SELECT 'a', 'x', 'z' UNION ALL
    SELECT '',  'x', 'z' UNION ALL
    SELECT 'a', 'x', '~'
)
SELECT min, val, max, CASE WHEN val BETWEEN min AND max THEN 'PASS' ELSE 'FAIL' END AS result
FROM tests

结果:

| min | val | max | result |
|-----|-----|-----|--------|
| a   | x   | z   | PASS   |
|     | x   | z   | PASS   |
| a   | x   | ~   | FAIL   |

x~的字符代码分别为120和126。在每种编程语言中,我都知道'x' < '~' is true。那么SQL是什么?

我在不同的RDBMS上得到相同的结果。在SQL Server上,使用以下排序规则:

  

Latin1常规,不区分大小写,区分重音,   不区分假名类型,不区分宽度

3 个答案:

答案 0 :(得分:4)

在您的问题下方的评论中,我问您使用的是collation。您说“假定默认”,但没有“默认”。 “默认”取决于数据库和服务器的设置方式。我在SQL Server上进行了实验,碰巧获得了与您相同的结果,但这只是一个巧合。

我进行实验的SQL Server和数据库使用的是SQL_Latin1_General_CP1_CI_AS归类。基于这个事实,这是字符的顺序:

http://collation-charts.org/mssql/mssql.0409.1252.Latin1_General_CI_AS.html

请注意,Tilde ~在明显包含x的字母字符之前。

答案 1 :(得分:0)

您需要应用BINARY排序规则,否则SQL Server将根据表或数据库所使用的排序规则使用(可能是非二进制)顺序。

这是一个有效的示例。您需要确定哪种确切的二进制排序规则。

outputs, _ = model.get_outputs()

loss_weights = tf.placeholder(tf.float32, [batch_size, None, 1])

nce_weights = tf.Variable(tf.truncated_normal([len(lexicon_dict), w2v_dim], stddev=1.0 / math.sqrt(w2v_dim)))
nce_biases = tf.Variable(tf.zeros([len(lexicon_dict)]))

loss = tf.reduce_mean(
     loss_weights * 
     tf.nn.nce_loss(weights=nce_weights, biases=nce_biases, 
         labels=model.target_idx, inputs=outputs[0], 
         num_sampled=128, num_classes=len(lexicon_dict), 
         num_true=N)
)

logits = tf.matmul(outputs[0], tf.transpose(nce_weights)) + nce_biases

输出:

GT Labels : for months each side had been building forward rifle pits and defensive positions , which resulted in many skirmishes . artillery fire aiming to gain superiority over the enemy guns . : 450
-- 462 september saw the final assault . on 5 september , another french bombardment -LRB- the sixth -RRB- was followed by an assault by the french army on 8 september resulting in the capture of the malakoff by the french , and following their failure to retake it , the collapse of the russian defences . meanwhile , the british captured the great redan , just south of the city of sevastopol . the russians retreated to the north , blowing up their magazines and the city fell on 9 september 1855 after a 337 day long siege . : 106 ;; who took control of the great redan ?? the british <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD> <PAD>

Out Labels : odger odger odger odger hastelloy hastelloy hastelloy hastelloy hastelloy hastelloy hastelloy odger odger hastelloy hastelloy hastelloy hastelloy hastelloy odger hastelloy odger odger odger hastelloy odger odger odger hastelloy odger odger hastelloy odger odger hastelloy odger odger odger hastelloy odger odger hastelloy hastelloy odger odger hastelloy odger odger odger hastelloy hastelloy odger hastelloy hastelloy odger hastelloy hastelloy odger hastelloy hastelloy odger odger hastelloy odger odger odger hastelloy hastelloy odger hastelloy hastelloy odger hastelloy hastelloy odger hastelloy hastelloy odger hastelloy odger hastelloy odger hastelloy hastelloy hastelloy odger hastelloy hastelloy odger odger hastelloy odger hastelloy hastelloy odger odger hastelloy odger odger hastelloy odger odger hastelloy hastelloy hastelloy hastelloy odger hastelloy hastelloy odger odger hastelloy hastelloy odger hastelloy odger odger hastelloy odger hastelloy hastelloy hastelloy odger hastelloy odger odger odger hastelloy hastelloy odger odger odger odger hastelloy odger odger hastelloy hastelloy odger odger hastelloy hastelloy odger odger hastelloy hastelloy hastelloy odger odger odger odger odger odger odger odger odger odger odgerodger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger odger

答案 2 :(得分:0)

您的行为取决于您使用的排序规则。

我已经尝试过了:

ChromeOptions options = new ChromeOptions();
options.addExtensions(new File(path));  

并且Sql Server返回ko(使用我的默认排序规则chrome://extension

如果我想按如下所述:

select
case
    when 'x' < '~' then 'ok'
    else 'ko'
end

它与ASC代码兼容