-1

大家好,感谢您花时间研究我的问题,

背景

我正在使用 ROW_NUMER() 函数和 PARTITION BY..ORDER BY 语句来为我的一个表中的每个值设置一个 varchar 值,并在其末尾增加一个 int 值。

SELECT  component_module_id as component_module_id,
        component_property_id,
        'cf' + CAST(ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_module_id) as VARCHAR) AS cf
FROM component_property

这里的“cf”值来自每个 component_module_id 的 cf1-cfX

示例查询输出

我的问题

每当我尝试在其他地方使用这些 cf 值时,例如保存在临时表中,其他 Ordering 和 Grouping 语句都会更改这些值。这就像生成“cf”值的语句被保存,而不是“cf”值本身。

将上面的查询插入到临时表中后#t -

SELECT * FROM #t ORDER BY cf

我收到从 cf1 开始并跳转到 cf10 然后 cf100 的“cf”值,cf 值范围从 cf1 到 cf900...我应该只接收从 c1 到 cf29 的值。

我的问题是 - 为什么此列中的值与任何其他正常值不同?为什么将 ROW_NUMBER() OVER (PARTITION BY....)) 计算传递给后续的查询?(如果这实际上是正在发生的事情)。最后,我如何将这些“cf”值视为正常的 VARCHAR 值,并且在我尝试按它们进行分组或排序时不让它们改变。

谢谢你的帮助!

更新

我接受了拉努的建议,

“似乎你最好只存储 int 值,并使用(PERSISTED)计算列来连接你的前缀和 ROW_NUMBER 值。”

并且我的“cf”值在排序后现在可以正确显示。感谢大家标记为已解决。

4

4 回答 4

0

如果你这样做,它会起作用

SELECT * FROM #t ORDER BY component_module_id, cast(replace(cf, 'cf', '') as int)
于 2020-02-10T16:43:57.350 回答
0

尝试这个

SELECT  component_module_id,
        component_property_id,
        'cf' + CAST(cf) AS VARCHAR(10)
FROM    (
            SELECT  component_module_id,
                    component_property_id,
                    ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_module_id) AS cf
            FROM    component_property
        ) a
ORDER BY component_module_id

您遇到的行为是因为VARCHAR按字母顺序排列数字

您需要使用 an 进行排序INT,然后在最后进行连接(通过将原始查询包装在子查询中

但是,评论中建议了一个更好的解决方案,即仅将数字存储为INT并使用计算列(或在查询级别)添加前缀

于 2020-02-10T16:42:26.430 回答
0

问题是您既按 分区按排序component_module_id。在每个分区内,排序键具有相同的值。

为什么这很重要?SQL 中的排序不稳定。这意味着关系可以通过任何一种方式解决。再次运行查询,您可能会得到不同的排序(在关系中)。

简单的解决方案是将排序更改为稳定,您只需使用列即可component_property_id。我还建议您使用CONCAT(),这样您就不需要任何类型转换:

SELECT component_module_id as component_module_id,
       component_property_id,
       CONCAT('cf',
              ROW_NUMBER() OVER (PARTITION BY component_module_id ORDER BY component_property_id)
             0 AS cf
FROM component_property

我还应该注意,您的代码使用VARCHAR没有长度。这在 SQL Server 中是一个非常糟糕的主意。默认长度因上下文而异,对于某些值可能不够大(尽管在这种情况下您没有这个问题)。

于 2020-02-10T17:58:10.910 回答
0

更新

我接受了拉努的建议,

“似乎你最好只存储 int 值,并使用(PERSISTED)计算列来连接你的前缀和 ROW_NUMBER 值。”

并且我的“cf”值在排序后现在可以正确显示。感谢大家标记为已解决。

于 2020-02-10T20:54:13.247 回答