【问题标题】:Why does selecting all columns change the order为什么选择所有列会改变顺序
【发布时间】:2022-10-01 09:36:44
【问题描述】:

我有 2 张桌子。使用select * 选择的顺序与不使用通配符的选择顺序不同。

此问题发生在生产环境中。

我试图复制这个问题,但没有成功。

什么可能导致生产表中出现此问题?

DROP TABLE IF EXISTS #table1
DROP TABLE IF EXISTS #table2

CREATE TABLE #table1 (id int, code varchar(10), carriercode varchar(10), maxvalue numeric(14,3))
CREATE TABLE #table2 (id int, carriercode varchar(10))

-- notice the maximum value is always 2000.000
INSERT INTO #table1 (id,code,carriercode, maxvalue) SELECT 1,\'a\',\'carrier_a\',2000.000
INSERT INTO #table1 (id,code,carriercode, maxvalue) SELECT 2,\'a\',\'carrier_b\',2000.000
INSERT INTO #table1 (id,code,carriercode, maxvalue) SELECT 3,\'c\',\'carrier_c\',2000.000
INSERT INTO #table2 (id,carriercode) SELECT 1,\'carrier_a\'
INSERT INTO #table2 (id,carriercode) SELECT 2,\'carrier_b\'

这是没有通配符的选择

SELECT t1.id,t1.code,t1.parentcode,t1.carriercode 
FROM #table1 t1
LEFT JOIN #table2 t2 on t1.carriercode=t2.carriercode
WHERE (t1.parentcode = \'a\')
AND (t1.maxvalue >= 830 OR t1.maxvalue is null)
ORDER BY t1.maxvalue DESC

结果

id  code    parentcode  carriercode
1   a1  a   carrier_a
2   a2  a   carrier_b

这里使用通配符选择

SELECT t1.id,t1.code,t1.parentcode,t1.carriercode,* 
FROM #table1 t1
LEFT JOIN #table2 t2 on t1.carriercode=t2.carriercode
WHERE (t1.parentcode = \'a\')
AND (t1.maxvalue >= 830 OR t1.maxvalue is null)
ORDER BY t1.maxvalue DESC

第二个结果

id  code    parentcode  carriercode id  code    parentcode  carriercode maxvalue    dt  id  carriercode
1   a1  a   carrier_a   1   a1  a   carrier_a   2000.000    2022-09-30 22:49:52.787 1   carrier_a
2   a2  a   carrier_b   2   a2  a   carrier_b   2000.000    2022-09-30 22:49:52.787 2   carrier_b

请注意,两个 select 语句的表 1 id 列的顺序是相同的。在生产表上,2 个 select 语句的顺序不同。

我试过的

  1. 舍入问题:CAST numeric to int -> 两个选择的顺序仍然相同
  2. 更改了初始插入的顺序 -> 两个选择的顺序仍然相同
  • 两行中的 maxvalue 值相同 (2000.000),因此它们的相对顺序未定义。这里的所有都是它的.确保任何特定排序的唯一方法是完全合格你的ORDER BY 子句(例如ORDER BY t1.MaxValue, id)。
  • 如果您要排序的列中每一行的值都相同,则 SQL Server 将按原样返回结果,但不能保证其他列之间的值。生产查询可能具有不同的执行计划,因此数据的读取方式会有所不同。
  • “完全符合您的订单”谢谢@Dai ...现在看起来很明显
  • 在您的第一个 SQL 语句中,是不是因为通配符(即 *)意味着 SQL 服务器在对 MaxValue 字段之外的任何内容进行排序时必须考虑 T1 和 T2 的所有其他列(您没有显示)?而在第二条 SQL 语句中,指定的 4 列意味着它不会影响 id 相对于 MaxValue 的顺序。我希望您也显示MaxValue 字段的值。

标签: sql sql-server


【解决方案1】:

因为基于您的 ORDER BY 绑定的行的顺序是未记录的,并且取决于执行计划的详细信息。

要修复顺序,请确保您的 ORDER BY 包含足够的列来对行进行唯一排序。例如

ORDER BY t1.maxvalue DESC, id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-18
    • 2018-06-13
    • 1970-01-01
    • 2013-07-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多