PDA

View Full Version : مشکل در مرتب کردن بر حسب اعدادی که به صورت رشته ای ذخیره شده اند



icmaster
پنج شنبه 16 فروردین 1386, 01:35 صبح
سلام
من در یک جدول یک فیلد به نام serial از نوع رشته دارم که کلید جدولم هم هست.
وقتی که میخوام بترتیب اعداد از کوچکتر به بزرگتر از این جدول select بگیرم درست کار نمیکنه به اینصورت که در مرتب کردن اعداد به طول اعداد توجهی نمیکنه مثلا بجای اینکه عدد 1425 قبل از 11256 بیاد بعد از اون میاد چون رقم دوم عدد 1425 از رقم دوم عدد 11256 بزرگتره!
انشاله که منظورمو فهمیدین.
به نظر شما دلیلش چیه و چیکار باید بکنم که درست بشه؟

با سپاس بسیار.

iman_22a
پنج شنبه 16 فروردین 1386, 01:56 صبح
یک دلیلش اینه که نوع ستون رو رشته گذاشتید و توی مقایسه رشته ها وقتی به مقایسه 1425 با 11256 می رسه مقایسه رو از سمت چپ به راست شروع می کنه چون اینها در واقع رشته هستند و برای مقایسه رشته ها از چپ براست مثایسه انجام می شه . پس 1425 بعد از 11256 میاد .

ghabil
پنج شنبه 16 فروردین 1386, 02:13 صبح
دلیلش اینه که نوع فیلد رو String گذاشتی راه حلش هم اینه که خب بکنیش Int اما اگر نمیخوای بکنی اینطوری سورت کن Select .... order by cast(Field as int)

icmaster
پنج شنبه 16 فروردین 1386, 11:23 صبح
با تشکر
به این دلیل رشته گذاشتم که در این فیلد ممکنه که سریالهایی که ترکیبی از حرف و عدد هستند هم وجود داشته باشند .
اون راهی که جناب کوشا فرمودند با حروف هم درست کار میکنه؟

icmaster
پنج شنبه 16 فروردین 1386, 14:28 عصر
دوستان به نظر شما میشه براش یه الگوریتم با استفاده از توابع موجود نوشت که این کار را انجام بده؟
اون راه جناب کوشا هم امتحان کردم برای حروف جواب نمیده .
من هر چی تلاش کردم نشد، اگه راهی به نظرتون میرسه لطف کنید و در اینجا بنویسید.

ممنون

ghabil
پنج شنبه 16 فروردین 1386, 23:05 عصر
من منظورت رو از حروف نمیفهمم ؟! یعنی مثلا انتظار داری مثلا 134 با 3ب1 مقایسه بشه ؟ اونم نه به شکل حرفی بلکه به شکل عددی؟!!
تنها حالتی که ممکنه کارت رو راه بندازه اینه که همه رشته ها رو با گذاشتن صفر در آخرشون هم طول بکنی .(نه لزما توی دیتا بلکه مثلا یک تابع بنویسی که این کار رو بکنه و بعد زمان Order کردن مثلا جای همون Cast ازش استفاده کنی)

reza_rad
پنج شنبه 16 فروردین 1386, 23:47 عصر
یک راهی که می تونه مشکل شما رو حل کنه:

فرض کنیم شما تاریخ رو به شکل 23/1/1386 توی این فیلد داری...
حالا می خوای این فیلد رو بر این اساس مرتب کنی که به ترتیب تاریخ باشه
یک راه اینه که از داخل این رشته علامت های اضافی مثل / در اینجا رو حذف کنی و به این فرمت ذخیره کنی مثلا اینجا میشه اینجوری : 13860123 و بعد مرتب کنی به راحتی.

راه دیگه اینه که توی order by استرینگ کانورت شده رو مرتب کنی مثلا بگی


order by convert(int,substring(field1,0,4))

AminSobati
جمعه 17 فروردین 1386, 00:06 صبح
create table #t1(
c1 varchar(10)
)
go

insert #t1 select '5'
insert #t1 select '1'
insert #t1 select '123'
go

select * from #t1 order by c1
select * from #t1 order by cast(c1 as int)

icmaster
جمعه 17 فروردین 1386, 00:38 صبح
من منظورت رو از حروف نمیفهمم ؟! یعنی مثلا انتظار داری مثلا 134 با 3ب1 مقایسه بشه ؟ اونم نه به شکل حرفی بلکه به شکل عددی؟!!
تنها حالتی که ممکنه کارت رو راه بندازه اینه که همه رشته ها رو با گذاشتن صفر در آخرشون هم طول بکنی .(نه لزما توی دیتا بلکه مثلا یک تابع بنویسی که این کار رو بکنه و بعد زمان Order کردن مثلا جای همون Cast ازش استفاده کنی)

حالا اون حرفو ول کن، شما یه الگوریتمی بگو که اعداد رشته ای رو بر حسب اندازه اعداد مرتب کنه نه مثل دیکشنری( و بدون دستکاری سریالها و استاندارد کردن اونها)


یک راهی که می تونه مشکل شما رو حل کنه:

فرض کنیم شما تاریخ رو به شکل 23/1/1386 توی این فیلد داری...
حالا می خوای این فیلد رو بر این اساس مرتب کنی که به ترتیب تاریخ باشه
یک راه اینه که از داخل این رشته علامت های اضافی مثل / در اینجا رو حذف کنی و به این فرمت ذخیره کنی مثلا اینجا میشه اینجوری : 13860123 و بعد مرتب کنی به راحتی.

راه دیگه اینه که توی order by استرینگ کانورت شده رو مرتب کنی مثلا بگی


order by convert(int,substring(field1,0,4))


آقا رضا فیلدم تاریخ نیست، یک فیلد از نوع رشته هست که اعداد رو بصورت رشته ای توش ذخیره میکنم.




create table #t1(
c1 varchar(10)
)
go

insert #t1 select '5'
insert #t1 select '1'
insert #t1 select '123'
go

select * from #t1 order by c1
select * from #t1 order by cast(c1 as int)


میشه یه کمی توضیح بدین؟؟

icmaster
جمعه 17 فروردین 1386, 00:41 صبح
آیا sql server تابعی داره که یک عدد کاراکتری رو بگیره و معادل عددیشو بده(مثلا '9' رو بگیره و 9 رو برگردونه)؟

ghabil
جمعه 17 فروردین 1386, 01:28 صبح
شما یه الگوریتمی بگو که اعداد رشته ای رو بر حسب اندازه اعداد مرتب کنه نه مثل دیکشنری( و بدون دستکاری سریالها و استاندارد کردن اونها)


گفتم دیگه یک تابع بنویس که پشت رشته هات رو به اندازه طول ماکسیمم فیلد منهای طول رشته صفر بزاره ، این تابع اطلاعات رو عوض نمیکنه فقط مثلا اگه اسمش هست SameLength اینطوری ازش استفاده میکنی


Select ..... order by SameLength(fieldName)


این موجب میشه که زمان سورت هم اندازه بشند و فقط درست سورت بشند.


آیا sql server تابعی داره که یک عدد کاراکتری رو بگیره و معادل عددیشو بده(مثلا '9' رو بگیره و 9 رو برگردونه)؟

همون Cast که اول برات نوشتم دیگه

reza_rad
جمعه 17 فروردین 1386, 10:30 صبح
آقا رضا فیلدم تاریخ نیست، یک فیلد از نوع رشته هست که اعداد رو بصورت رشته ای توش ذخیره میکنم.

من مثال زدم تاریخ... در کل روش کار یکیه

بیشتر توضیح بده که می خوای چی کار کنی؟

icmaster
جمعه 17 فروردین 1386, 11:00 صبح
سلام


گفتم دیگه یک تابع بنویس که پشت رشته هات رو به اندازه طول ماکسیمم فیلد منهای طول رشته صفر بزاره ، این تابع اطلاعات رو عوض نمیکنه فقط مثلا اگه اسمش هست SameLength اینطوری ازش استفاده میکنی


Select ..... order by SameLength(fieldName)


این موجب میشه که زمان سورت هم اندازه بشند و فقط درست سورت بشند.



همون Cast که اول برات نوشتم دیگه

ممنون.
اون تابع رو میشه با SQL SERVER نوشت؟
اخه من هر چی گشتم تابعی مثلا برای برگردوندن طول رشته پیدا نکردم؟


من مثال زدم تاریخ... در کل روش کار یکیه

بیشتر توضیح بده که می خوای چی کار کنی؟

من یک فیلد در دیتابیسم دارم بنام serial و از نوع رشته که توش مثلا شماره سریال یه سری دستگاه رو ذخیره میکنم و از اونجا که در شماره سریال بعضی از دستگاهها حروف انگلیسی هم وجود داره به ناچار اون فیلد رو رشته انتخاب کردم.
حالا میخوام که اطلاعاتم بصورت مرتب شده بر حسب اندازه عددی شماره سریالها مرتب بشه.
اون تابعی که آقای کوشا فرمودند فکر کنم درست باشه ولی تابعشو در sql server نمیدونم چطوری بنویسم.

ghabil
جمعه 17 فروردین 1386, 13:14 عصر
اخه من هر چی گشتم تابعی مثلا برای برگردوندن طول رشته پیدا نکردم؟


تابع LEN طول رشته رو بر میگردونه .
اینم یک کد که برای تست تو QueryAnalyzer نوشتم خوت تابش کن دیگه :



declare @aw varchar(20);
set @aw = 'alie';
while len(@aw) < 20
set @aw = '0' + @aw
select @aw

AminSobati
جمعه 17 فروردین 1386, 16:54 عصر
آیا sql server تابعی داره که یک عدد کاراکتری رو بگیره و معادل عددیشو بده(مثلا '9' رو بگیره و 9 رو برگردونه)؟
مثالی که نوشتم رو دقت کردین؟ چون دقیقا همین کار رو انجام میده!