PDA

View Full Version : جستجو در پایگاه داده بر اساس تاریخ



rashidi_sm
شنبه 08 تیر 1392, 21:38 عصر
سلام
من یک برنامه انبار داری نوشتم که ورود و خروج کالا را با تاریخ درج می کنم
حالا می خوام وقتی کاربر یک محدوده تاریخ مشخص می کند در پایگاه داده جستجو کنم و تمام کالاهایی که در آن فاصله زمانی وارد یا خارج شدند را پیدا کنم، می شود راهنمایی کنید چطوری باید این کار را انجام بدم؟
سپاس

eshaghrahimy
شنبه 08 تیر 1392, 21:41 عصر
select * from mytable where date beetwen date 1 and date2

gholami146
شنبه 08 تیر 1392, 21:43 عصر
از دستورات اسکیوال استفاده کنید

Select * From tblKala Where (Dateout >= date And Dateout <=Date)

gholami146
شنبه 08 تیر 1392, 21:45 عصر
البته روش بهتر روش دوست خوبم هست که با استفاده از پارامتر beetwenمی باشد ولی در عمل هر دو دستور یکی هست

samad1987
یک شنبه 09 تیر 1392, 00:28 صبح
اصلا به تعداد انسانها میتونی کد بزنی که کار کنه


select * from (select *from table where date > date1) where data < date2


جوابای دوستای عزیزم هم کاملا درسته
ولی این سرعتش بیشتره
چرا که از بین جدولی کوچیکتر سرچ میزنه
and که کلا خیلی کار رو کند میکنه

veniz2008
یک شنبه 09 تیر 1392, 02:58 صبح
اصلا به تعداد انسانها میتونی کد بزنی که کار کنه


select * from (select *from table where date > date1) where data < date2


جوابای دوستای عزیزم هم کاملا درسته
ولی این سرعتش بیشتره
چرا که از بین جدولی کوچیکتر سرچ میزنه
and که کلا خیلی کار رو کند میکنه
سلام.
این حرف در این مثال اشتباه هست.
ما زمانی این کار رو انجام میدیم که بخوایم از روی یه نتیجه برگشتی دوباره جواب بگیریم. در اینصورت ابتدا اون جواب برگشتی اولیه رو ریز میکنیم (همون select داخلی) و بعدش از روی اون جواب کوچیک شده، دنبال نتیجه دلخواه میگردیم. ولی در این مثال شما یک select رو تبدیل به دو select کردی که کار بهینه ای نیست.
برای اینکه در عمل نتیجه کار رو ببینید یه جدول با چند هزار رکورد رو در نظر بگیرید. با کد زیر زمان اجرای کوئری ها رو می سنجیم :
کد شما :

DECLARE @start_time DATETIME

SET @start_time = GETDATE()

-- my query
select * from (select * from Table_1 where '1391/10/01' > date1)a1 where '1391/04/01' < date2

-- calculate runtime query
SELECT RTRIM(CAST(DATEDIFF(MS, @start_time, GETDATE()) AS CHAR(10))) AS 'RunTime'

کد دوستانی که در پست های 1 و 2 جواب دادن :

DECLARE @start_time DATETIME

SET @start_time = GETDATE()

-- my query
--select * from Table_1 where '1391/10/01' > date1 and '1391/04/01' < date2

-- calculate runtime query
SELECT RTRIM(CAST(DATEDIFF(MS, @start_time, GETDATE()) AS CHAR(10))) AS 'RunTime'
موفق باشید.

rashidi_sm
دوشنبه 10 تیر 1392, 09:40 صبح
تشکر از پاسختون
مطابق با گفته شما من این کد را به صورت زیر نوشتم
string str1 = "SELECT * from Anbar inner join Object on Anbar.ObjectCode=Object.ObjectCode WHERE state='خروج ازانبار' and Anbar.date>=@date1 and Anbar.date<=@date2";

SqlCommand cmd = new SqlCommand(str1, Con);

// cmd.Parameters.AddWithValue("@a", ObjCode1.Text);

cmd.Parameters.AddWithValue("@date1", Sdate.Text);
cmd.Parameters.AddWithValue("@date2", Edate.Text);

DataSet ds = new DataSet();
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
Con.Open();
da.Fill(ds, "Anbar");
Con.Close();
dataGridView1.DataBindings.Add(new Binding("datasource", ds, "Anbar"));

ولی تمام تاریخ ها در این بازه رو نشون نمی ده!! بعضی ها را جا می ندازه، چی کار باید بکنم؟

veniz2008
دوشنبه 10 تیر 1392, 11:09 صبح
شما وقتی join میزنید (منظور همون inner join هست)، فقط رکوردهای مشترک بین دو جدول (objectcode یکسان ) با هم ادغام میشن. و بعد شرط شما بر روی این کوئری اعمال میشه. شما فقط دارید به بازه زمانی نگاه میکنید و فکر میکنید که خروجی صحیح نیست. در صورتیکه این join هست که اول داده ها رو فیلتر میکنه.
برای رفع این مشکل و با توجه به کوئری که نوشتید میتونید از Left Join استفاده کنید. در کوئری که شما نوشتید، جدول انبار شما که تاریخ رو از اون میخونید در سمت چپ قرار داره (جدول Object در سمت راست قرار داره). کار Left Join اینه که تمام رکوردهای جدول سمت چپ رو برمیگردونه حتی اگر نظیرش در جدول سمت راست نباشه. یعنی اگر ObjectCode ای در جدول Anbar باشه ولی همون ObjectCode در جدول Object نباشه، باز هم همه رکوردهای جدول Anbar (که شامل تاریخ هست) رو میاره و به جای فیلدهای جدول Object مقدار Null رو برمیگردونه.حالا زمانیکه شرط تاریخ بر این نتیجه برگشتی اعمال میشه، جواب مورد نظرتون رو مشاهده خواهید کرد.
مطلب بسیار ساده است، کافیه یه بار تست کنید تا متوجه این چند خط توضیحات بشید.
فقط به جای کلمه Join بنویسید Left Join .
موفق باشید.

hamid_hr
دوشنبه 10 تیر 1392, 11:30 صبح
يه چيز ديگه هم هس
اين تاريخ تو ديتابيس به صورت رشته هس يا datetime
اگه رشته باشه بايد حتما به صورت hh/mm/ss باشه يعني مثل اين 1392/04/09
اگه به صورت 1392/4/9 باشه جواب كلا اشتباه ميده

rashidi_sm
دوشنبه 10 تیر 1392, 12:51 عصر
يه چيز ديگه هم هس
اين تاريخ تو ديتابيس به صورت رشته هس يا datetime
اگه رشته باشه بايد حتما به صورت hh/mm/ss باشه يعني مثل اين 1392/04/09
اگه به صورت 1392/4/9 باشه جواب كلا اشتباه ميده

تاریخ به صورت رشته است، تاریخ رو از رو سیستم می خواند و به صورت 1392/4/9 ذخیره می کند، چرا اشتباه هست؟
چی کار باید بکنم؟

amir200h
دوشنبه 10 تیر 1392, 14:20 عصر
به آدرس زیر یه سر بزن
http://barnamenevis.org/showthread.php?406294-%D8%B1%D9%81%D8%B9-%D9%85%D8%B4%DA%A9%D9%84-%D8%AC%D8%B3%D8%AA%D8%AC%D9%88-%D8%A7%D8%B2-%D8%B7%D8%B1%DB%8C%D9%82-%D8%AA%D8%A7%D8%B1%DB%8C%D8%AE-%D8%B4%D9%85%D8%B3%DB%8C-%D8%A8%D8%B1%D8%A7%DB%8C-%D9%87%D9%85%DB%8C%D8%B4%D9%87&p=1807612#post1807612

veniz2008
دوشنبه 10 تیر 1392, 14:48 عصر
تاریخ به صورت رشته است، تاریخ رو از رو سیستم می خواند و به صورت 1392/4/9 ذخیره می کند، چرا اشتباه هست؟
چی کار باید بکنم؟
همونطور که دوستمون هم گفتن تاریخ رو نباید به این صورت ذخیره کنید. و باید همه تاریخ ها به یک شکل واحد ذخیره بشن. یعنی باید طول تمام تاریخ ها رو 10 کاراکتری وارد کنید.
دلیل این کار به این خاطر هست که مقایسه رشته ها، بصورت کاراکتر به کاراکتر هست. یعنی رشته '4' از رشته '11' بزرگتر هست. در صورتیکه شما قصد این رو دارید که به sql بفهمونید که ماه 11 بزرگتر از ماه 4 هست. ولی چون 4 رشته ای ( '4') از 11 رشته ای ( '11' ) بزرگتر هست این اتفاق در جستجوها رخ نمیده و نتیجه مد نظر بدست نمیاد. ولی اگر '4' رو بصورت '04' ذخیره کنید در اینصورت '11' از '04' بزرگتر خواهد بود. (اولین کاراکتر 11 برابر با 1 هست که با اولین کاراکتر 04 که 0 هست مقایسه میشه و 11 به عنوان رشته بزرگتر شناخته میشه). پس همه تاریخ ها رو بصورت 10 کاراکتری مثلا 1392/04/09 ذخیره کنید.
برای اینکه تاریخ سیستم رو بصورت 10 کاراکتری ذخیره کنید میتونید از کد زیر استفاده کنید :

DateTime today = DateTime.Today;

PersianCalendar pc = new PersianCalendar();

string date = pc.GetYear(today).ToString("0000") + pc.GetMonth(today).ToString("/00") + pc.GetDayOfMonth(today).ToString("/00");

MessageBox.Show(date);

با این توضیح من فکر میکنم دیگه نیازی به Left Join نیست. چون من اینطور تصور کرده بودم که شما همه تاریخ ها رو 10 کاراکتری ثبت کردید.
موفق باشید.

bazikadeh
دوشنبه 10 تیر 1392, 16:06 عصر
یه مثال با linq میزنید ؟