এসকিউএল সার্ভারে নেতৃস্থানীয় শূন্যগুলি ছাঁটাই করার জন্য আরও ভাল কৌশল?


161

আমি ব্যবহার করছি এই কিছু সময়ের জন্য:

SUBSTRING(str_col, PATINDEX('%[^0]%', str_col), LEN(str_col))

তবে সম্প্রতি, আমি '00000000' এর মতো সমস্ত "0" অক্ষর সহ কলামগুলিতে একটি সমস্যা পেয়েছি কারণ এটি কখনও মেলানোর জন্য একটি অ-"0" অক্ষর খুঁজে পায় না।

একটি বিকল্প কৌশল যা আমি দেখেছি তা হ'ল TRIM:

REPLACE(LTRIM(REPLACE(str_col, '0', ' ')), ' ', '0')

এম্বেড থাকা স্পেস থাকলে এটির একটি সমস্যা রয়েছে, কারণ স্পেসগুলি "0" এর মধ্যে ফিরে এলে সেগুলি "0" এর মধ্যে পরিণত হবে।

আমি একটি স্কেলার ইউডিএফ এড়ানোর চেষ্টা করছি। আমি এসকিউএল সার্ভার 2005 সালে ইউডিএফগুলির সাথে প্রচুর পারফরম্যান্স সমস্যা পেয়েছি।


স্ট্রিংয়ের বাকী অংশগুলি সর্বদা কেবল 'সংখ্যাসূচক' অক্ষর রাখে, বা আপনারও আলফা থাকতে পারে? যদি এটি কেবল সংখ্যার ডেটা হয় তবে কোসনোইয়ের পূর্ণসংখ্যা এবং পিছনে কাস্ট করার পরামর্শটি বেশ ভাল বলে মনে হচ্ছে।
রোবসফট

এটি একটি সাধারণ কৌশল। এগুলি সাধারণত অ্যাকাউন্ট নম্বরগুলি যা কোনও অপ্রতিনিধিত ক্ষেত্রের দিকে আসছে এবং আমার এটি নিশ্চিত করা দরকার যে তারা তাদের ইটিএলে ডেটা গুদাম ব্যবহার করে এমন কনফর্মেশন নিয়মের সাথে মিলছে (যা অবশ্যই আরও অনেক বেশি বৈশিষ্ট্যযুক্ত এসআইএসআইএস পরিবেশে রয়েছে, আমি ধরে নিই যে তারা ব্যবহার করে। TrimStart)।
ক্যাড রক্স

উত্তর:


282
SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col))

2
চতুর, ইচ্ছে করে আমি এটা ভাবতাম।
ক্যাড রক্স

4
কিছু মনে করবেন না, আমি বুঝতে পেরেছি যে ''। স্ট্রিংগুলিতে নেই কারণ এটি কেবলমাত্র প্যাটার্নটি সন্ধান করতে ব্যবহৃত - এটি আমার ধারণা থেকে আরও চালাক।
কেড রক্স

2
এটি একটি ফাংশনে আবদ্ধ করার ফলে আমার প্রশ্নগুলি ধীর করে দেয়। আমি কেন পুরোপুরি নিশ্চিত নই তবে আমি মনে করি এটি রূপান্তরকরণের সাথে সম্পর্কিত। সাবস্ক্রিং ইনলাইন ব্যবহার করা খুব দ্রুত ছিল।
রনি ওভারবি

1
প্রশ্নটি এর সাথে সমস্যাটি উল্লেখ করে যখন আপনি একটি শূন্য ('0') পার্স করেন, আপনি একটি ফাঁকা পান। আপনাকে একটি '0' মান এবং একটি ফাঁকা মানের মধ্যে পার্থক্য বলতে সক্ষম হতে হবে। : দয়া করে একটি সম্পূর্ণ সমাধান জন্য আমার পোস্ট দেখতে stackoverflow.com/a/21805081/555798
MikeTeeVee

1
@ আরভো বাহ ... এক মিনিটের জন্য আমি বিভ্রান্ত হয়ে পড়েছিলাম এবং ভেবেছিলাম যে এই প্রশ্নের উত্তরটি আমাকে সাহায্য করতে চলেছে answered Arvoএসও-তে প্রথমবারের মতো আমি অন্য কাউকে দেখেছি !
আরভো বোয়েন

41

আপনি কেন কেবল তার মানটি INTEGERআবার কাস্ট করবেন না VARCHAR?

SELECT  CAST(CAST('000000000' AS INTEGER) AS VARCHAR)

--------
       0

11
এটি একটি স্ট্রিং কলাম, তাই আমি অনুমান করব যে তারা সময়ে সময়ে অ-সংখ্যাসূচক ডেটা আশা করে। একটি MRN সংখ্যা যেখানে ডেটা শুধুমাত্র মতো কিছু বেশিরভাগই সাংখ্যিক।
জোয়েল কোহোর্ন 14

1
দুর্ভাগ্যক্রমে, কেবলমাত্র সংখ্যার ডেটা জন্য কাজ করে এবং কখনও কখনও স্ট্রিংগুলি পূর্ণসংখ্যার জন্যও সীমা অতিক্রম করে, সুতরাং আপনাকে বিগিন্ট ব্যবহার করতে হবে।
ক্যাড রক্স

3
SELECT CASE ISNUMERIC(str_col) WHEN 1 THEN CAST(CAST(str_col AS BIGINT) AS VARCHAR(255)) ELSE str_col END
ইউরি রোজোভেসটস্কি

এমনকি BIGINT, কিছু ধরণের স্ট্রিং এখনও এই রূপান্তরকে ব্যর্থ করবে। 0001E123উদাহরণস্বরূপ বিবেচনা করুন ।
রোয়াইমা

1
আমার পরীক্ষা থেকে (এবং অভিজ্ঞতা) এটি গ্রহণযোগ্য উত্তরের তুলনায় তুলনামূলকভাবে ব্যয়বহুল অপারেশন। পারফরম্যান্সের কারণে, ডেটা প্রকার পরিবর্তন করা বা বিভিন্ন ধরণের ডেটার তুলনা করা এড়ানো ভাল, যদি এটি করার ক্ষমতা আপনার মধ্যে থাকে।
রিডস্টোনফুড

14

আপনার কাছে অল-শূন্যের (বা এমনকি একটি একক শূন্য) থাকলে তা বিবেচনায় নেওয়ার জন্য অন্যান্য উত্তরগুলি এখানে নেই।
কিছু সর্বদা একটি শূন্য স্ট্রিং শূন্যকে ডিফল্ট করে দেয়, যা যখন ফাঁকা থাকার কথা মনে হয় ভুল হয়।
মূল প্রশ্নটি পুনরায় পড়ুন। এটি প্রশ্নকর্তা যা চান তার উত্তর দেয়।

সমাধান # 1:

--This example uses both Leading and Trailing zero's.
--Avoid losing those Trailing zero's and converting embedded spaces into more zeros.
--I added a non-whitespace character ("_") to retain trailing zero's after calling Replace().
--Simply remove the RTrim() function call if you want to preserve trailing spaces.
--If you treat zero's and empty-strings as the same thing for your application,
--  then you may skip the Case-Statement entirely and just use CN.CleanNumber .
DECLARE @WackadooNumber VarChar(50) = ' 0 0123ABC D0 '--'000'--
SELECT WN.WackadooNumber, CN.CleanNumber,
       (CASE WHEN WN.WackadooNumber LIKE '%0%' AND CN.CleanNumber = '' THEN '0' ELSE CN.CleanNumber END)[AllowZero]
 FROM (SELECT @WackadooNumber[WackadooNumber]) AS WN
 OUTER APPLY (SELECT RTRIM(RIGHT(WN.WackadooNumber, LEN(LTRIM(REPLACE(WN.WackadooNumber + '_', '0', ' '))) - 1))[CleanNumber]) AS CN
--Result: "123ABC D0"

সমাধান # 2 (নমুনা ডেটা সহ):

SELECT O.Type, O.Value, Parsed.Value[WrongValue],
       (CASE WHEN CHARINDEX('0', T.Value)  > 0--If there's at least one zero.
              AND LEN(Parsed.Value) = 0--And the trimmed length is zero.
             THEN '0' ELSE Parsed.Value END)[FinalValue],
       (CASE WHEN CHARINDEX('0', T.Value)  > 0--If there's at least one zero.
              AND LEN(Parsed.TrimmedValue) = 0--And the trimmed length is zero.
             THEN '0' ELSE LTRIM(RTRIM(Parsed.TrimmedValue)) END)[FinalTrimmedValue]
  FROM 
  (
    VALUES ('Null', NULL), ('EmptyString', ''),
           ('Zero', '0'), ('Zero', '0000'), ('Zero', '000.000'),
           ('Spaces', '    0   A B C '), ('Number', '000123'),
           ('AlphaNum', '000ABC123'), ('NoZero', 'NoZerosHere')
  ) AS O(Type, Value)--O is for Original.
  CROSS APPLY
  ( --This Step is Optional.  Use if you also want to remove leading spaces.
    SELECT LTRIM(RTRIM(O.Value))[Value]
  ) AS T--T is for Trimmed.
  CROSS APPLY
  ( --From @CadeRoux's Post.
    SELECT SUBSTRING(O.Value, PATINDEX('%[^0]%', O.Value + '.'), LEN(O.Value))[Value],
           SUBSTRING(T.Value, PATINDEX('%[^0]%', T.Value + '.'), LEN(T.Value))[TrimmedValue]
  ) AS Parsed

ফলাফল:

MikeTeeVee_SQL_Server_Remove_Leading_Zeros

সারসংক্ষেপ:

শীর্ষস্থানীয় শূন্যের এক-অফ অপসারণের জন্য আমার উপরের জিনিসগুলি আপনি ব্যবহার করতে পারেন।
যদি আপনি এটির পুনঃব্যবহারের পরিকল্পনা করেন তবে এটি একটি ইনলাইন-টেবিল-মূল্যবান-ফাংশন (আইটিভিএফ) এ রাখুন।
ইউডিএফ এর সাথে পারফরম্যান্স সমস্যা সম্পর্কে আপনার উদ্বেগ বোধগম্য।
যাইহোক, এই সমস্যাটি কেবলমাত্র সমস্ত স্কেলার-ফাংশন এবং বহু-বিবৃতি-সারণী-ফাংশনগুলিতে প্রযোজ্য।
আইটিভিএফ ব্যবহার করা পুরোপুরি ঠিক আছে।

আমাদের তৃতীয় পক্ষের ডেটাবেস নিয়ে আমার একই সমস্যা।
আলফা-নিউমেরিক ক্ষেত্রের সাহায্যে অনেকগুলি নেতৃস্থানীয় স্থান ছাড়াই প্রবেশ করে, ডাং মানব!
এটি অনুপস্থিত নেতৃস্থানীয়-জেরোগুলি পরিষ্কার না করে যোগ দেওয়াটিকে অসম্ভব করে তোলে।

উপসংহার:

শীর্ষস্থানীয়-জিরোগুলি সরিয়ে দেওয়ার পরিবর্তে, আপনি যখন যোগ দেবেন তখন আপনি নিজের ছাঁটাই-মানগুলি শীর্ষস্থানীয়-জিরোগুলির সাথে প্যাডিং বিবেচনা করতে পারেন।
আরও ভাল, নেতৃস্থানীয় শূন্যগুলি যোগ করে, তারপরে আপনার সূচীগুলি পুনর্নির্মাণ করে টেবিলে আপনার ডেটা পরিষ্কার করুন।
আমি মনে করি এটি দ্রুত এবং কম জটিল হবে।

SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF(' 0A10  ', ''))), 10)--0000000A10
SELECT RIGHT('0000000000' + LTRIM(RTRIM(NULLIF('', ''))), 10)--NULL --When Blank.

4
@ ডিগো কুইয়েরোজ উত্তরটি যদি ভুল হয় তবে দয়া করে ডাউনরঙ্ক করে ব্যাখ্যা করুন কেন এটি কার্যকর হয় না। যদি উত্তরটি কাজ করে তবে আপনার পক্ষে খুব বিস্তৃত, তবে দয়া করে আমাকে বা এই সাইটে অন্য সদস্যদের ক্ষতিগ্রস্থ করবেন না। মন্তব্য করার জন্য আপনাকে ধন্যবাদ. এটি শুনতে ভাল প্রতিক্রিয়া - আমি আন্তরিকভাবে এটি বলছি।
মাইকটিভি 21

5

কোনও স্থানের পরিবর্তে 0 এর স্থানটিকে একটি 'বিরল' সাদা স্থানের অক্ষর দিয়ে প্রতিস্থাপন করুন যা কলামের পাঠ্যে সাধারণত হওয়া উচিত নয়। একটি লাইনের ফিড সম্ভবত এই জাতীয় কলামের জন্য যথেষ্ট ভাল। তারপরে আপনি সাধারণত LTrim করতে পারেন এবং আবার 0 এর সাথে বিশেষ চরিত্রটি প্রতিস্থাপন করতে পারেন।


3

নিম্নলিখিত স্ট্রিংটি সম্পূর্ণ শূন্য ধারণ করে '0' ফিরিয়ে দেবে:

CASE WHEN SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col)) = '' THEN '0' ELSE SUBSTRING(str_col, PATINDEX('%[^0]%', str_col+'.'), LEN(str_col)) END AS str_col

মানটিতে শূন্য না থাকলে এটি শূন্যও ফিরে আসবে (ফাঁকা থাকে)।
মাইকটিভি

সেখানে কেন str_col + 'রয়েছে।' এবং না শুধুমাত্র str_col? বিন্দু কি করে?
মুফ্লিক্স

2

এটি একটি সুন্দর ফাংশন করে ....

DROP FUNCTION [dbo].[FN_StripLeading]
GO
CREATE FUNCTION [dbo].[FN_StripLeading] (@string VarChar(128), @stripChar VarChar(1))
RETURNS VarChar(128)
AS
BEGIN
-- http://stackoverflow.com/questions/662383/better-techniques-for-trimming-leading-zeros-in-sql-server
    DECLARE @retVal VarChar(128),
            @pattern varChar(10)
    SELECT @pattern = '%[^'+@stripChar+']%'
    SELECT @retVal = CASE WHEN SUBSTRING(@string, PATINDEX(@pattern, @string+'.'), LEN(@string)) = '' THEN @stripChar ELSE SUBSTRING(@string, PATINDEX(@pattern, @string+'.'), LEN(@string)) END
    RETURN (@retVal)
END
GO
GRANT EXECUTE ON [dbo].[FN_StripLeading] TO PUBLIC

মানটিতে শূন্য না থাকলে এটি শূন্যও ফিরে আসবে (ফাঁকা থাকে)। এই উত্তরটি একটি মাল্টি-স্টেটমেন্ট-স্কেলার-ফাংশনও ব্যবহার করে, যখন উপরের প্রশ্নটি নির্দিষ্ট করে ইউডিএফ ব্যবহার করা এড়াতে বলে।
মাইকটিভি

2

কাস্ট (মান হিসাবে মান) সর্বদা কাজ করবে যদি স্ট্রিং সংখ্যা হয়


এটি প্রশ্নের উত্তর সরবরাহ করে না। কোনও লেখকের কাছ থেকে সমালোচনা বা স্পষ্টতার জন্য অনুরোধ জানাতে, তাদের পোস্টের নীচে একটি মন্তব্য দিন। - পর্যালোচনা থেকে
জোসিপ আইভিক

1
বাস্তবে এটি একটি উত্তর কারণ এটি কাজ করে? উত্তরগুলি দীর্ঘ হতে হবে না
টিচরা

আপনি সঠিক বলেছেন যে উত্তরগুলি দীর্ঘতর হওয়ার দরকার নেই, তবে সম্ভব হলে সেগুলি সম্পূর্ণ হওয়া উচিত, এবং আপনার উত্তরটি তা নয়; এটি ফলাফলের ডেটা ধরণের পরিবর্তন করে। আমি বিশ্বাস করি এটির একটি ভাল প্রতিক্রিয়া হতে পারে: নির্বাচন কাস্ট (CAST (মূল্য হিসাবে IN) AS VARCHAR)। আপনার এটিও উল্লেখ করা উচিত যে যদি সংখ্যার মানটি 2.1x10 ^ 9 (আট ডিজিটের সীমা) অতিক্রম করে তবে আপনি ইন্টের সাথে একটি ত্রুটি পাবেন। বিগআইএন্ট ব্যবহার করে আপনি ত্রুটি পাবেন যদি মানটি প্রায় 19 টি সংখ্যার (9.2x10 ^ 18) অতিক্রম করে।
জে ক্রিস কমপটন

2

এর আমার সংস্করণটি আরভোর কাজের একটি অভিযোজন, যা আরও দুটি ক্ষেত্রে নিশ্চিত করার জন্য আরও কিছু যুক্ত করা হয়েছে।

1) আমাদের সমস্ত 0 গুলি থাকলে আমাদের 0 নম্বরটি ফিরিয়ে দেওয়া উচিত।

2) আমাদের যদি একটি ফাঁকা থাকে, আমাদের এখনও একটি ফাঁকা অক্ষর ফিরিয়ে আনা উচিত।

CASE 
    WHEN PATINDEX('%[^0]%', str_col + '.') > LEN(str_col) THEN RIGHT(str_col, 1) 
    ELSE SUBSTRING(str_col, PATINDEX('%[^0]%', str_col + '.'), LEN(str_col))
 END

1
replace(ltrim(replace(Fieldname.TableName, '0', '')), '', '0')

টমাস জি এর পরামর্শ আমাদের প্রয়োজনের জন্য কাজ করেছে।

আমাদের ক্ষেত্রে ক্ষেত্রটি ইতিমধ্যে স্ট্রিং ছিল এবং কেবলমাত্র শীর্ষস্থানীয় শূন্যগুলি ছাঁটাই করা দরকার। বেশিরভাগ ক্ষেত্রে এটি সমস্ত সংখ্যাসূচক তবে মাঝে মাঝে চিঠিগুলি থাকে তাই পূর্ববর্তী INT রূপান্তরটি ক্র্যাশ হয়ে যায়।



1
SELECT CAST(CAST('000000000' AS INTEGER) AS VARCHAR)

স্ট্রিংয়ের দৈর্ঘ্যের এটির একটি সীমা রয়েছে যা কোনও INT এ রূপান্তরিত হতে পারে


আপনি নিজের উত্তরে আরও কিছুটা ব্যাখ্যা করতে পারেন কেন আপনি ভাবেন যে এটি কাজ করবে? अग्रणी শূন্যগুলির একগুচ্ছ যদি এটি একটি শূন্য নম্বরের হয় তবে কী হবে?
তাইগোস্ট

যদি আপনার সংখ্যা 18 ডিজিট বা তার চেয়ে কম হয় (এবং সর্বাধিক 19 সংখ্যার সংখ্যা কাজ করে কারণ সীমাটি 9.2x10 ^ 18 হয়) তবে শীর্ষস্থানীয় শূন্যগুলি থেকে মুক্তি পেতে আপনি SELECT CAST (@Feld_Name AS BigInt AS AS) ব্যবহার করতে পারেন। দ্রষ্টব্য: যদি আপনার ত্রুটিযুক্ত অ-সংখ্যাযুক্ত অক্ষর (ড্যাশ, চিঠি, সময়কাল, ইত্যাদি) থাকে তবে এটি ব্যর্থ হবে 8114 "ডেটা টাইপ বারচরকে বিগিন্টে রূপান্তর করার সময় ত্রুটি" "
জে ক্রিস কমপটন

1

আপনি যদি স্নোফ্লেক এসকিউএল ব্যবহার করেন তবে এটি ব্যবহার করতে পারে:

ltrim(str_col,'0')

Ltrim ফাংশন বাম দিক থেকে অক্ষরগুলির নির্ধারিত সেটগুলির সমস্ত উদাহরণ সরিয়ে দেয়।

সুতরাং ltrim (str_col, '0') '00000008A' এ '8A' ফেরত আসবে

এবং rtrim (str_col, '0।') '' 125.00 'এ ফিরে আসবে' return 125 '


1
  SUBSTRING(str_col, IIF(LEN(str_col) > 0, PATINDEX('%[^0]%', LEFT(str_col, LEN(str_col) - 1) + '.'), 0), LEN(str_col))

এমনকি '0', '00' ইত্যাদির সাথেও দুর্দান্ত কাজ করে।



0

আপনি যদি ইন্টিতে রূপান্তর করতে না চান তবে আমি নীচের যুক্তিটিকে পছন্দ করি কারণ এটি নালগুলি IFNULL (ক্ষেত্র, LTRIM (ক্ষেত্র, '0')) পরিচালনা করতে পারে


0

মাইএসকিউএল এ আপনি এটি করতে পারেন ...

Trim(Leading '0' from your_column)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.