ورود

View Full Version : مشکل در select کردن افراد بین دو تاریخ



mahdi_armed
یک شنبه 26 تیر 1401, 18:32 عصر
سلام اساتید گرامی
من به یه مشکل خوردم که خودم نتونستم برطرفش کنم که از روی عکس توضیح میدم کامل.
همونطور که میبینید من یک سری کارمند دارم که توی روز های هفته مرخصی میزنن
کارمند اول یک روز
کارمند دوم و سوم، ۲ روز
کارمند چهارم ۵ روز

و نقطه مشترک اینها، توی روز پنجم هست که همگی مرخصی رفتن

153912

حالا من چطور میتونم یک query داشته باشم که تعداد کارمند هایی که روز پنجم نیستن رو بدست بیارم ؟

کدهای خودم هم میزارم. اما جوابی که میخواستم رو نتونستم بگیرم ازشون


SELECT * FROM dbo.leave
WHERE
dateFrom BETWEEN '1401/01/05' AND '1401/01/05'
OR
dateTo BETWEEN '1401/01/05' AND '1401/01/05'
OR dateTo >= '1401/01/05' AND dateFrom <= '1401/01/05'

ORDER BY createdDate



با این کدها، نفر چهارم که که قبل از تاریخ پنجم مرخصی رفته و چند روز بعد از پنجم اومده رو نمیتونم داشته باشم توی نتیجه

mazoolagh
سه شنبه 28 تیر 1401, 23:38 عصر
سلام و روز خوش
شرط where درست نیست!
SELECT * FROM dbo.leave
WHERE dateFrom <= 14010105 AND dateTo >= 14010105
ORDER BY createdDate

و این که تاریخ حتما باید int ذخیره بشه و نه string !

Apache66
پنج شنبه 13 مرداد 1401, 11:51 صبح
تاریخ شمسی میتونه string هم ذخیره بشه و مشکلی نیست

mazoolagh
جمعه 14 مرداد 1401, 18:49 عصر
تاریخ شمسی میتونه string هم ذخیره بشه و مشکلی نیست

تفاوت هست بین اینکه کاری شدنی باشه و اینکه کاری درست باشه -
مثل این که آب استخر رو با استکان هم میشه خالی کرد!

اینکه تاریخ فارسی رو بجای int بصورت string نگهداری کنیم چون از نظر فنی نادرست هست پس مشکل دار هم هست.

mmbguide
جمعه 28 مرداد 1401, 22:11 عصر
سلام

یه سوال تقریبا حاشیه ای. برنامه شما از کجا میدونه که کارمند کدام روزها حضور و غیاب براش انجام شده؟ احتمالا اگر در تاریخ مورد نظر مقدار null باشه و یا مثلا دستور Count مقدار 0 برگردونه و شاید هم با Exist بخواهید بررسی کنید، نبود مقدار را ملاک عدم حضور در نظر میگیرید؟ سوال اصلیم اینه که اگر کارمند از تارخ 6ام استخدام شده باشه و شما تاریخ 5ام رو برای این کارمند چطور بررسی میکنید؟

Apache66
یک شنبه 01 آبان 1401, 20:23 عصر
تفاوت هست بین اینکه کاری شدنی باشه و اینکه کاری درست باشه -
مثل این که آب استخر رو با استکان هم میشه خالی کرد!

اینکه تاریخ فارسی رو بجای int بصورت string نگهداری کنیم چون از نظر فنی نادرست هست پس مشکل دار هم هست.

از لحاظ فنی چه مشکی داره ؟!!!
من الان با یک نرم افزار بزرگ 20 هزار کاربره دارم 12 سال اینطوری تاریخ ذخیره میکنم
یک مورد مشکل نداشتم

ROSTAM2
دوشنبه 02 آبان 1401, 18:28 عصر
بنظرم تاریخ شمسی از طریق SQL قابل شناسایی بعنوان Date نیست. و باید به تاریخ میلادی تبدیل بشه.
sql - Converting GETDATE() to Hijri date to yyyymmdd - Stack Overflow (https://stackoverflow.com/questions/42786255/converting-getdate-to-hijri-date-to-yyyymmdd)

masoode
چهارشنبه 04 آبان 1401, 09:49 صبح
خود MSSQL برای ما تبدیل میلادی به شمسی گذاشته
select format(GETDATE(),'yyyy/MMMM/dddd','fa')
select format(GETDATE(),'yyyy/MMM/dd','fa')
select format(GETDATE(),'yy/MM/dd','fa')
select format(GETDATE(),'yyyy/MM/dd','fa')

ROSTAM2
چهارشنبه 04 آبان 1401, 11:15 صبح
سلام اساتید گرامی
من به یه مشکل خوردم که خودم نتونستم برطرفش کنم که از روی عکس توضیح میدم کامل.
همونطور که میبینید من یک سری کارمند دارم که توی روز های هفته مرخصی میزنن
کارمند اول یک روز
کارمند دوم و سوم، ۲ روز
کارمند چهارم ۵ روز

و نقطه مشترک اینها، توی روز پنجم هست که همگی مرخصی رفتن

153912

حالا من چطور میتونم یک query داشته باشم که تعداد کارمند هایی که روز پنجم نیستن رو بدست بیارم ؟

کدهای خودم هم میزارم. اما جوابی که میخواستم رو نتونستم بگیرم ازشون


SELECT * FROM dbo.leave
WHERE
dateFrom BETWEEN '1401/01/05' AND '1401/01/05'
OR
dateTo BETWEEN '1401/01/05' AND '1401/01/05'
OR dateTo >= '1401/01/05' AND dateFrom <= '1401/01/05'

ORDER BY createdDate



با این کدها، نفر چهارم که که قبل از تاریخ پنجم مرخصی رفته و چند روز بعد از پنجم اومده رو نمیتونم داشته باشم توی نتیجه

سلام.
یک سوال برای هر سال یک دیتابیس جداگونه استفاده می شه یا اطلاعات تمام سالهای فعالیت اون اداره یا شرکت توی همون یک دیتابیس ذخیره می شه؟!
من که ساختار جدول رو متوجه نشدم چطوریه -
با این حال استفاده از کلمه کلیدی BETWEEN بین یک تاریخ منطقی نیست!
و همچنین بنظر میاد ساختار جدول باید تغییر کنه.

همچنین می شه تاریخ آغاز و پایان را باهم با یک کاراکتر جداکننده در یک فیلد ذخیره کرد و در زمان فراخوانی تاریخ ها رو با تابع STRING_SPLIT (Transact-SQL) (https://learn.microsoft.com/en-us/sql/t-sql/functions/string-split-transact-sql?view=sql-server-2016)جدا کرد.

mazoolagh
پنج شنبه 05 آبان 1401, 13:37 عصر
از لحاظ فنی چه مشکی داره ؟!!!
من الان با یک نرم افزار بزرگ 20 هزار کاربره دارم 12 سال اینطوری تاریخ ذخیره میکنم
یک مورد مشکل نداشتم

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

این که چرا چیزی مثل تاریخ فارسی نباید string ذخیره بشه جزو بدیهیات هست، هم از نظر منطقی و هم از نظر کاربردی؛

از نظر منطقی دلیلش این هست که تاریخ بطور کلی یک کمیت شمردنی هست و هر مقدار تاریخ عملا نسبت به یک مبدا شمرده میشه - حالا این شمارش میتونه برمبنای هزارم ثانیه باشه یا روز یا ...
همچنین تمام عملیات روی تاریخ از نوع شمردنی هست: افزودن یا کم کردن روز/ماه/سال .... ، محاسبه اختلاف بین 2 تاریخ ، ...

از نظر کاربردی دلیلش این هست که عملیات روی شماره ها بسیار سریعتر از عملیات روی stringها هست:
در سطح ماشین مقایسه دو مقدار عددی فقط یک دستور نیاز داره ولی مقایسه دو string بصورت کارآکتر به کارآکتر انجام میشه و در عملیات با حجم زیاد زمانگیر هست.
محاسبات روی بخش های مختلف یک کمیت شمارشی هم بسیار سریع انجام میشه (مثلا بیرون کشیدن مقدار سال) ولی در کمیت string این دست عملیات بمراتب وقت گیر تر هست.
دست آخر این که عملا برای هر نوع محاسبه روی بخش های مختلف تاریخ از نوع string در نهایت باز باید به شماره تبدیل بشن.

البته اگر مقدار تاریخ واقعا literal هست و قرار نیست هیچ نوع عملیاتی روی اون بشه اهمیتی نداره که چجوری ذخیره بشه.

mazoolagh
پنج شنبه 05 آبان 1401, 14:54 عصر
خود MSSQL برای ما تبدیل میلادی به شمسی گذاشته
select format(GETDATE(),'yyyy/MMMM/dddd','fa')
select format(GETDATE(),'yyyy/MMM/dd','fa')
select format(GETDATE(),'yy/MM/dd','fa')
select format(GETDATE(),'yyyy/MM/dd','fa')

بسیار عالی
ولی مشکل ذخیره سازی مستقیم تاریخ فارسی رو حل نمیکنه.
تاریخ sql فقط گرگورین هست (تا جایی که میدونم) و هنوز نمیشه تاریخ فارسی براش تعریف کرد.
میشه تاریخ رو در front-end به گرگورین تبدیل و در sql ذخیره و عملیات datediff/dateadd رو هم در همون front-end با persian-calendar انجام داد.

همچنین میشه تاریخ فارسی رو مستقیما بصورت int در sql ذخیره کرد ولی در front-end با اجزای اون یک تاریخ ساخت و عملیات رو در persian-calendar انجام داد.

masoode
شنبه 07 آبان 1401, 17:04 عصر
بسیار عالی
ولی مشکل ذخیره سازی مستقیم تاریخ فارسی رو حل نمیکنه.
تاریخ sql فقط گرگورین هست (تا جایی که میدونم) و هنوز نمیشه تاریخ فارسی براش تعریف کرد.
میشه تاریخ رو در front-end به گرگورین تبدیل و در sql ذخیره و عملیات datediff/dateadd رو هم در همون front-end با persian-calendar انجام داد.

همچنین میشه تاریخ فارسی رو مستقیما بصورت int در sql ذخیره کرد ولی در front-end با اجزای اون یک تاریخ ساخت و عملیات رو در persian-calendar انجام داد.

من همیشه تاریخ را با فرمت DateTime در دیتابیس ذخیره میکنم و موقع نمایش به شمسی تبدیل میکنم. که قبلا با یک فانکشن که در SQL داشتم این کار را انجام می دادم اما مدتی است که از همین روش بالا استفاده می کنم

mazoolagh
دوشنبه 09 آبان 1401, 09:04 صبح
من همیشه تاریخ را با فرمت DateTime در دیتابیس ذخیره میکنم و موقع نمایش به شمسی تبدیل میکنم. که قبلا با یک فانکشن که در SQL داشتم این کار را انجام می دادم اما مدتی است که از همین روش بالا استفاده می کنم
درسته و کار بسیار خوبی هم هست، اما اگر روی تاریخ یک سری عملیات خاص نیاز داشته باشین هنوز مجبور به کد نویسی در سمت fe هستین.
به هر روی کاربر تاریخ رو به فرمت ایرانی وارد میکنه و یک بار در سمت برنامه شما اون رو به گرگورین تبدیل و در sql ذخیره میکنین.
حالا اگر فرضا 50 روز بعد از یک تاریخ خاص رو بخواین خب مشکلی نیست و مستقیما در sql شدنی هست.

اما اگر 3 ماه بعد از یک تاریخ معین مد نظر باشه، دیگه توابع سمت sql جوابگو نیستن باید اول در برنامه با persian calendar معادل گرگورین اون تاریخ رو پیدا و بعد اون رو در کوئری استفاده کنین.
از طرفی اگر فقط نمایش تاریخ هدف هست دیگه چه نیازی هست تاریخی رو که کاربر به فرمت ایرانی در برنامه وارد کرده اول به گرگورین تبدیل و در sql ذخیره کنیم و دوباره برای نمایش اون رو برگردونیم.

منظور من همین بود که چون sql (هنوز) مستقیما تاریخ ایرانی رو قبول نمیکنه (چه ذخیره سازی چه عملیات روی اون) این روش در حالت کلی بتنهایی کافی نیست،
وگرنه در سودمندی و درستی گفته شما ایرادی نیست.

masoode
دوشنبه 09 آبان 1401, 10:45 صبح
درسته و کار بسیار خوبی هم هست، اما اگر روی تاریخ یک سری عملیات خاص نیاز داشته باشین هنوز مجبور به کد نویسی در سمت fe هستین.
به هر روی کاربر تاریخ رو به فرمت ایرانی وارد میکنه و یک بار در سمت برنامه شما اون رو به گرگورین تبدیل و در sql ذخیره میکنین.
حالا اگر فرضا 50 روز بعد از یک تاریخ خاص رو بخواین خب مشکلی نیست و مستقیما در sql شدنی هست.

اما اگر 3 ماه بعد از یک تاریخ معین مد نظر باشه، دیگه توابع سمت sql جوابگو نیستن باید اول در برنامه با persian calendar معادل گرگورین اون تاریخ رو پیدا و بعد اون رو در کوئری استفاده کنین.
از طرفی اگر فقط نمایش تاریخ هدف هست دیگه چه نیازی هست تاریخی رو که کاربر به فرمت ایرانی در برنامه وارد کرده اول به گرگورین تبدیل و در sql ذخیره کنیم و دوباره برای نمایش اون رو برگردونیم.

منظور من همین بود که چون sql (هنوز) مستقیما تاریخ ایرانی رو قبول نمیکنه (چه ذخیره سازی چه عملیات روی اون) این روش در حالت کلی بتنهایی کافی نیست،
وگرنه در سودمندی و درستی گفته شما ایرادی نیست.

:تشویق::تشویق: