2016-03-20 6 views
0

に確認してください、私はいくつかの規則に基づいてartikel番号を生成する必要があり、そしてこの大会はテーブルから最大数を取得1を追加し、特定の規則

{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 

最初の部分はプロデュースに基づいており、すべてのプロデュースは独自の番号を持っています。 Rebook - 12、Nike - 256、Umbro - 3としましょう。

私はこの番号を渡してテーブルをチェックしなければなりません。たとえば、12を渡すと12から始まるすべてを取得する必要があります。

、今何をすべきか3例があるはずです。その後、1001

を取得

第一CASE:表の行なし

第二のケースは:行があるかどうかわから用ので

は、すでに少なくとも一つがあります:

12.1001.1 

とより多くの彼らはのは、言わせている場合:

12.1002.1 
12.1003.1 
... 
12.4345.1 

したがって、次のように収集されるべきです:4346

と5桁が、この製品のためにすでに存在する場合それでは言わせて:10001

第三の場合:

12.1002.1 
12.1003.1 
... 
12.9999.1 

はとてもので、次の1 retreivedしなければならないとして、実際には同じ第二が、第2の部分のためにそれrached 9999の場合:

12.1001.1 
... 
12.9999.1 

は、その後でなければなりません返されました:10001

または

12.1002.1 
12.1003.1 
... 
12.9999.1 
12.10001.1 
12.10002.1 

のでので、次のいずれかをretreivedする必要があります:10003

あなたは私が

何を意味するか知っているホープすでに何かを始めた。このコードは、それから始まるすべての行を探し、2番目の部分に1を追加するだけで、私はそれらの3つのケースに応じてどのように変更するべきかわかりません。

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) 
+0

固定幅:000.000000.00000で番号を保存すると、書式がずっと簡単になります。あなたはこれを考えましたか? –

+0

3つの異なるフィールドに3つの部分を格納し、ビュー内の計算フィールドとしてのみ番号を作成する方法はありますか? –

+0

これは顧客が私が必要とするコンベンションです;それに影響を与えることはありません。私はメインポストのように正しいアサイメントだけを実装する必要があります。 –

答えて

0

かなり単純な方法は、(AB)にある現在の最大値を抽出することができるように、文字列を分割するPARSENAMEを使用します。外部クエリは、値が見つからない/ 9999 /その他のルールを実装するだけです。

値(ここでは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[.]%'を追加することができます。

+0

クエリが動作していて、最も短いものです。とにかく他の人のおかげで!あなたの解決策の中に隠された問題がないことを願ってください:) –

+1

クールな解決策私はこれから何かを学んだと思います。 –

+0

@Joachim Isaksson私はあなたがその質問にパラメータを渡そうとしていて、何か間違ったことをやって1001を得るように心配していなければ、私は追加の質問があります - あなたはメインのポストを見て、 –

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つの分野で、それは今彼らに論理を適用する方がはるかに簡単です。

更新: 私はあなたの質問を再読し、私は一種のあなたがで取得しようとしているかを知るよし.. 次に、あなたは1001 を返さ例8 のために存在しない値のためのユーザーの検索をしたい場合彼らは結果が、その後、最大+ 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変数を変更チェック 私はそれを行うためのクリーンな方法があるかもしれないと思うsのそれは:(今の私には

0

を来ていないあなたが本当に2つの新しいフィールド(is'tおそらく最も簡単かつ最速のソリューション)を追加することはできません、おそらく機能的なインデックスを追加することができない場合は、第二を抽出する必要があります部品番号と、このの最大を取得し、増分、そして最後に、あなたの条件の第一の部品番号と」0.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)が関数を定義するならば次いで、第2の数:

select @parm + '.' + (max(cast(parsename(nummer, 2) as int)) + 1) + '.1' 
from tbArtikel 
where Nummer LIKE @parm + '.%' 
関連する問題