从表中获取最大数量添加一个并检查具体约定

时间:2016-03-20 15:37:20

标签: sql sql-server

我必须根据某些惯例制作artikel编号,此惯例如下

位数

{1 or 2 or 3}.{4 or 5}.{n}

示例产品编号:

7.1001.1
1.1453.1
3.5436.1
12.7839.1
12.3232.1
13.7676.1
3.34565.1
12.56433.1
247.23413.1

第一部分基于producent,每个产品都有自己的编号。让我们说Rebook - 12,Nike - 256和Umbro - 。

我必须传递这个号码并检查表格中是否有一些行包含它,例如我通过12然后我应该得到从12开始的所有内容。

现在应该有三个案例:

第一个案例:表格中没有行:

  

然后检索1001

第二种情况:如果有行

所以肯定已经有至少一个:

12.1001.1

以及更多,如果他们说:

12.1002.1
12.1003.1
...
12.4345.1
  

所以应该接下来的一个,所以:4346

如果此产品已有5位数字,那么让我们说:

12.1002.1
12.1003.1
...
12.9999.1
  

所以应该接下来的一个,所以:10001

第3个案例:实际上与第2个案件相同,但如果第二个部分为9999次:

12.1001.1
...
12.9999.1
  

然后返回应该是:10001

12.1002.1
12.1003.1
...
12.9999.1
12.10001.1
12.10002.1
  

所以应该接下来的一个,所以:10003

希望你知道我的意思

我已经开始做点什么了。这段代码是生产数字 - 查找以它开头的所有行,然后只是简单地在第二部分添加1,我不知道如何根据这三种情况更改它。

select
    parsename(max(nummer), 3) + '.'                    -- 3
    + ltrim(max(cast(parsename(nummer, 2) as int) +1)) -- 5436 -> 5437
    + '.1'                                          
from tbArtikel 
where Nummer LIKE '3.%'

指望你的帮助。如果不明确的事情让我知道。

其他问题:

Using cmd As New SqlCommand("SELECT CASE WHEN r.number Is NULL THEN 1001
                                                     WHEN r.number = 9999 THEN 10001
                                                     Else r.number + 1 End number
                                        FROM (VALUES(@producentNumber)) AS a(art)   -- this will search this number within inner query And make case..
                                        LEFT JOIN(
                                        -- Get producent (in Like) number And max number Of it (without Like it Get all producent numbers And their max number out Of all
                                        SELECT PARSENAME(Nummer, 3) art,
                                        MAX(CAST(PARSENAME(Nummer, 2) AS INT)) number
                                        FROM tbArtikel WHERE Nummer Like '@producentNumber' + '[.]%'
                                        GROUP BY PARSENAME(Nummer, 3)
                                        ) r
                                        On r.art = a.art", con)



                cmd.CommandType = CommandType.Text
                cmd.Parameters.AddWithValue("@producentNumber", producentNumber)

3 个答案:

答案 0 :(得分:0)

我不完全明白你的要求。我不确定这些例子......但如果我这样做,我会先尝试将场分成3个区域,然后再用它们做点什么。 sqlfiddle

SELECT nummer,LEFT(nummer,first-1) as field1,
       RIGHT(LEFT(nummer,second-1),second-first-1) as field2,
       RIGHT(nummer,LEN(nummer)-second) as field3
FROM
(SELECT nummer,
    CHARINDEX('.',nummer) as first,
    CHARINDEX('.',nummer,CHARINDEX('.',nummer)+1)as second
from tbArtikel)T

希望在3个字段分解后,现在将逻辑应用到它们会容易得多。

更新: 好的,我重读了你的问题,我知道你想要得到什么...... 如果用户搜索例如8不存在的值。 然后你想要1001返回 如果他们搜索其他任何有结果的东西,则返回max + 1 除非它是9999然后返回10001。 如果这是正确的,请检查此sqlfiddle2

DECLARE @search varchar(20)
SET @search = '8'
SELECT field1,max(nextvalue) as nextvalue FROM
  (SELECT field1,
       MAX(CASE (field2)
       WHEN 9999 THEN 10001
       ELSE field2+1
       END) as nextvalue
    FROM 
      (SELECT nummer,
        CAST(LEFT(nummer,first-1) as INTEGER) as field1,
        CAST(RIGHT(LEFT(nummer,second-1),second-first-1) as INTEGER) as field2,
        CAST(RIGHT(nummer,LEN(nummer)-second) as INTEGER) as field3
        FROM
        (SELECT nummer,
          CHARINDEX('.',nummer) as first,
          CHARINDEX('.',nummer,CHARINDEX('.',nummer)+1)as second
          FROM tbArtikel
        )T
      )T2
  GROUP BY field1
  UNION 
  SELECT CAST (@search as INTEGER)as field1 ,1001
  )T3
WHERE field1 = @search
GROUP BY field1

只需更改@search变量即可查看结果 我认为可能有一种更清洁的方法可以做到这一点,但现在还没有找到我:(

答案 1 :(得分:0)

如果你真的不能添加2个新字段(可能不是最简单和最快的解决方案),并且可能无法添加功能索引,则必须提取第二部分编号并获得最大值,增量,然后连接条件第一部分编号和最后的“.1”:

SELECT :par1 || '.' || (Max(To_Number(SubStr(nummer, dot1 + 1, dot2 - dot1 -1 ))) + 1) || '.1' NEW_number
--SELECT SubStr(nummer, 1, dot1 - 1) N1st, SubStr(nummer, dot1 + 1, dot2 - dot1 -1 ) N2nd,  SubStr(nummer, dot2 + 1) N1th
FROM (
SELECT nummer, InStr(nummer, '.') dot1, InStr(nummer, '.', 1, 2) dot2 
FROM tbArtikel
WHERE nummer LIKE :par1 || '.%')
;      
--GROUP BY SubStr(nummer, 1, dot1 – 1)

是oracle sql,我没有sql-serwer来测试,但可能这是最简单的答案:

select @par1 + '.' + (select max(cast(SUBSTRING(nummer, CHARINDEX( '.', nummer, 1 ) +1, CHARINDEX( '.', nummer, CHARINDEX( '.', nummer, 1 ) +1 ) - CHARINDEX( '.', nummer, 1 ) -1) as int)) + 1 from tbArtikel where nummer LIKE @par1 || '.%') + '.1'

如果parsename(nummer,2)是你定义的函数,那么得到第二个数字:

select @parm + '.' + (max(cast(parsename(nummer, 2) as int)) + 1) + '.1'
from tbArtikel 
where Nummer LIKE @parm + '.%'

答案 2 :(得分:0)

一种相当直接的方法是(ab)使用PARSENAME来分割字符串以便能够提取当前最大值。然后外部查询可以只实现缺失值/ 9999 / other的规则。

将值(此处为12)插入表值构造函数中,以便能够使用LEFT JOIN检测缺失值。

SELECT CASE WHEN r.number IS NULL THEN 1001
            WHEN r.number = 9999 THEN 10001
            ELSE r.number + 1 END number
FROM ( VALUES(12) ) AS a(category)
LEFT JOIN (
  SELECT PARSENAME(prodno, 3) category,
         MAX(CAST(PARSENAME(prodno, 2) AS INT)) number
  FROM products
  GROUP BY PARSENAME(prodno, 3)
) r
ON r.category = a.category;

An SQLfiddle to test with

作为进一步优化,您可以在内部查询中添加WHERE prodno LIKE '12[.]%',以便不解析不必要的行。