【问题标题】:Numeric ordering on varchar based co-related subqueries基于 varchar 的相关子查询的数字排序
【发布时间】:2010-12-16 14:29:26
【问题描述】:

让我说我有一个包含一些通用数据持有者列的表(因此看起来原始代码的开发人员选择使用字符串类型)。这些列可以包含所有数字、字母数字或它们的混合。

让我说我有一个共同相关的子查询,例如;

SOME_CORELATED_QUERY=(SOME SELECT SQL)

假设我有一个 order by 子句;

order by ID,SOME_CORELATED_QUERY

现在因为这些字段都是基于 varchar 的,所以我无法默认对它们进行数字排序。

我可以为我的共同相关子查询试试这个;

SOME_CORELATED_QUERY=cast((SOME SELECT SQL) as int)

但是上面的问题是,并不是我所有的数据都是数字的,我会得到一个错误;

Conversion failed when converting the varchar value '304L' to data type int.

所以我找到了一个解决方案here,它基本上使用了对我的问题可行的空格,但问题是我不能将它应用于相关的子查询。

如果我尝试将它应用于我的表格列 ID,一切正常;

order by space(50-len(ID))+ID, SOME_CORELATED_QUERY

但这不能作为解决方案,因为我需要对我的 SOME_CORELATED_QUERY 进行数字排序。我试试看;

order by space(50-len(SOME_CORELATED_QUERY))+SOME_CORELATED_QUERY

但我收到一条错误消息,因为在某种程度上我的相关子查询无法被 SQL 函数(如空格、转换、转换等)识别:

Msg 207, Level 16, State 1, Line 48
Invalid column name 'SOME_CORELATED_QUERY'.
Msg 207, Level 16, State 1, Line 48
Invalid column name 'SOME_CORELATED_QUERY'.

所以基本上我需要在排序时间对我的相关子查询使用 SQL 函数空间、转换、转换。

注意:更改数据库布局,字段类型是不可能的,因为布局是在我使用的程序上硬编码的,我只是为用户创建基于 SQL 的报告。

  • 我也在研究 mssql2005。

更新:感谢 Brad,我更新了问题文本以使用“共同相关子查询”,因为它比虚拟列更好地描述。

Update2:这是要求的完整 sql;

select ID, S.STOCK_ID ,S.STOCK_CODE,S.STOK_SHORT_NAME,S.UNIT1_NAME UNIT_NAME,

  PROPERTY_VALUE_NAME1=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_1),
  PROPERTY_NAME1=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT, STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY1_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME2=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_2),
  PROPERTY_NAME2=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY2_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME3=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_3),
  PROPERTY_NAME3=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY3_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME4=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES  where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_4),
  PROPERTY_NAME4=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY4_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME5=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_5),
  PROPERTY_NAME5=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY5_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME6=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_6),
  PROPERTY_NAME6=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY6_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  PROPERTY_VALUE_NAME7=(Select PROPERTY_VALUE from STOCK_PROPERTY_VALUES where  PROPERTY_VALUE_ID=a.PROPERTY_VALUE_ID_7),
  PROPERTY_NAME7=(Select PROPERTY_NAME from STOCK_PROPERTY_DEFINITIONS SOT,STOCK_PROPERTY_TEMPLATES SOS where SOS.PROPERTY7_ID=SOT.PROPERTY_ID and SOS.ID=a.ID),

  isnull(SUM(case IN_OUT when 1 then UNIT1_VALUE else 0 end),0) IN_VALUE,
  isnull(SUM(case IN_OUT when 2 then UNIT1_VALUE else 0 end),0) OUT_VALUE

    from STOCK_PROPERTY_DETAILS a, STOCK b, STOCK_TRANSACTION_ROWS DHS, STOCK S, WAREHOUSE D 

    where a.STOCK_ID=b.STOCK_ID   and  b.STOCK_ID *= DHS.SHD_ID   and  DHS.SHD = 1 and ID>0 and B.UPPER_STOCK_ID=S.STOCK_ID and D.WAREHOUSE_ID*=DHS.WAREHOUSE_ID

    group by S.STOCK_ID ,S.STOCK_CODE,S.STOK_SHORT_NAME,S.UNIT1_NAME, PROPERTY_VALUE_ID_1,PROPERTY_VALUE_ID_2,PROPERTY_VALUE_ID_3,PROPERTY_VALUE_ID_4,PROPERTY_VALUE_ID_5,PROPERTY_VALUE_ID_6,PROPERTY_VALUE_ID_7,ID

    having 1=1 and ((isnull(SUM(case IN_OUT when 1 then UNIT1_VALUE else 0 end),0)-isnull(SUM(case IN_OUT when 2 then UNIT1_VALUE else 0 end),0)<>0 /*##ZERO#*/) or (not(1=1 /*##ZERO#*/)))

    order by   ID,PROPERTY_VALUE_NAME1,PROPERTY_VALUE_NAME2,PROPERTY_VALUE_NAME3,PROPERTY_VALUE_NAME4,PROPERTY_VALUE_NAME5,PROPERTY_VALUE_NAME6,PROPERTY_VALUE_NAME7

我想对 PROPERTY_VALUE_NAME1、PROPERTY_VALUE_NAME2 等进行排序..

【问题讨论】:

  • 仅供参考:我相信那些“虚拟列”被称为“相关子查询”
  • 如果您可以发布查询的实际样本,那将有很大帮助。 (人们经常将他们的对象重命名为“MyTable”和“Col1, Col2”等以匿名他们的工作。)
  • 这段代码有很多错误,我什至不知道从哪里开始。首先不要使用隐含的左连接(带有星号的连接)。它不会可靠地给出正确的结果,因为 SQL 服务器有时认为它是左连接,有时是交叉连接。早在 SQL Server 2000 中就是如此,并且不推荐使用这种语法。它不能正常工作,所以不要使用它。无论如何,您都不应该使用隐式连接。接下来,那些相关的子查询是性能杀手,应该用连接替换。它们逐行运行,几乎不是一个好主意。
  • 是的,我知道代码很容易出错,但正如我所说,这不是我开发的代码,而是由“程序”开发人员提供的。我只是在寻找一个快速解决问题的方法。我仍然会考虑您的建议,但我找不到数字排序的快速修复方法,我将进行完整的重新实现。

标签: sql sql-server sql-server-2005 sql-order-by


【解决方案1】:

我无法测试它,因为我手头没有实例,但如果它允许您在其上使用 case 语句,这样的事情可能会起作用

order by
   case 
      when isnumeric(columnname) then cast(columnname as int) 
      else -1 
   end,
   columnname

希望这会以两种方式进行,第一种按数字顺序对数值进行排序,然后将 alpha 内容集中在 -1 的组中,然后我们的第二部分将按 alpha 进行排序

【讨论】:

    【解决方案2】:

    对于字符数据的数字排序,请使用ORDER BY LEN(columnName), columnName

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-23
      • 2011-02-02
      • 2011-12-05
      • 2018-07-29
      • 2020-06-25
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      相关资源
      最近更新 更多