【问题标题】:Substring range break out SQL server 2008 R2子字符串范围突破 SQL server 2008 R2
【发布时间】:2015-04-26 10:26:56
【问题描述】:

所以我有一个如下所示的表格:

Order/item       Price
2001/1-10        $1000
2001/11-13       $ 500 
2002/1-20 + 22   $2500
2003             $2000

我想从订单/项目中获取数据并创建一个看起来像这样的范围:

Order/item
2001/1
2001/2
2001/3

等等...如您所见,可能有一个“+”号表示范围是 x-y 和 z...

我的变量和子字符串技能是有限的。我的宏观想法是在“/”符号后面取第一个数字,然后 +1,直到我得到第二个数字。但也有没有'/'号的记录,然后如何处理'+'号。 '/' 符号后的第一个数字的长度也可以是 1-4 位。对不起,如果这是基本的。我知道那里有类似的问题,但没有什么能真正帮助我理解。

编辑:

那么这个呢...不用担心 order/one_item 格式...可以说该字段将始终是 order/item-item 没有空格 +'s 等...我想拿第一个项目(所以所有数字在“/”之后但在“-”之前,然后将 1 添加到它,直到我达到第二个项目值。所以表格看起来像这样:

order/item    new_col
2001/1-10      1
2001/1-10      2
2001/1-10      3
2001/1-10      4
2001/1-10      5
2001/1-10      6
2001/1-10      7
2001/1-10      8
2001/1-10      9
2001/1-10      10

我认为这应该更容易做到。

【问题讨论】:

  • 这看起来太复杂了,无法在 SQL 中实现(容易且合理)。
  • 是的,它很复杂,如果有人想发布一个复杂的解决方案,这对我来说很好。
  • 我的意思是,用编程语言(如 C#)做起来要容易得多
  • 这应该通过一个包含每个项的条目的中间表来完成...范围就像那个气球变成可怕的噩梦,
  • @ Alex,我有一个表,其中包含我尝试使用 order/ONE_item 加入的每个项目的条目...要么就是这样,要么找到一种方法使其他表匹配这个。

标签: sql-server range substring charindex


【解决方案1】:

您可以创建一个函数来获取每一行的范围

CREATE FUNCTION dbo.GetRange (@range varchar(10))
RETURNS @RangeTable TABLE (RangeNumber int) AS BEGIN

    DECLARE @StartRange int, @EndRange int

    SELECT @StartRange = SUBSTRING(@range, CHARINDEX('/', @range, 0) + 1, CHARINDEX('-', @range, 0) - CHARINDEX('/', @range, 0) - 1),
        @EndRange = SUBSTRING(@range, CHARINDEX('-', @range, 0) + 1, LEN(@range))

    WHILE @StartRange <= @EndRange BEGIN
        INSERT INTO @RangeTable (RangeNumber) VALUES (@StartRange)
        SET @StartRange = @StartRange + 1
    END

    RETURN
END
GO

然后在您选择的原始表格中加入这个

SELECT * FROM OrderItemTable 
CROSS APPLY dbo.GetRange(OrderItem)

您可能可以修改 GetRange 函数来处理您的其他一些情况(+、无范围等)。

【讨论】:

    【解决方案2】:

    这应该适用于您的简化版本。 CTE 生成一个(大)范围的数字,然后将其连接回已拆分为其组成部分的字符串。

    DECLARE @OrderItem VARCHAR(100) = '2001/1-10'
    
    ;WITH Nums AS
    (
      SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
      FROM sys.all_objects 
    
    )
    SELECT  SUBSTRING(@OrderItem, 0, CHARINDEX('/', @OrderItem)),
            n
    FROM nums
    WHERE n BETWEEN CAST(SUBSTRING(SUBSTRING(@OrderItem, 6, 100), 0, CHARINDEX('-', SUBSTRING(@OrderItem, 6, 100))) AS INT)
    AND CAST(SUBSTRING(SUBSTRING(@OrderItem, 6, 100), CHARINDEX('-', SUBSTRING(@OrderItem, 6, 100))+1, 100) AS INT)
    

    因此,假设您有一个名为 Orders 的表,其中包含名为 OrderItemPrice 的列,那么您可以像这样将它们连接在一起:

    ;WITH Nums AS
    (
      SELECT n = ROW_NUMBER() OVER (ORDER BY [object_id]) 
      FROM sys.all_objects 
    
    )
    
    SELECT  SUBSTRING(Orders.OrderItem, 0, CHARINDEX('/', Orders.OrderItem)) AS [Order],
            n AS Item,
            Price
    FROM Orders
    CROSS APPLY nums
    WHERE n BETWEEN CAST(SUBSTRING(SUBSTRING(Orders.OrderItem, 6, 100), 0, CHARINDEX('-', SUBSTRING(Orders.OrderItem, 6, 100))) AS INT)
    AND CAST(SUBSTRING(SUBSTRING(Orders.OrderItem, 6, 100), CHARINDEX('-', SUBSTRING(Orders.OrderItem, 6, 100))+1, 100) AS INT)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-21
      相关资源
      最近更新 更多