PDA

View Full Version : دادن 2 عدد به 2 فیلد رکورد جدید که تا به حال به هیچ رکورد جدول داده نشده



intel_amd
دوشنبه 28 مهر 1393, 10:31 صبح
مسئله پیچیده اما ساده نما !
چطور در هنگام ثبت نام یوزر جدید می توان 2 عدد رندوم بین 0-200 به 2 فیلد رکورد جدید داد که این 2 عدد تا به حال به هیچ رکورد دیگری داده نشده باشد

اول پیش خودم گفتم 2 عدد رندوم انتخاب می کنم و در جدول سلکت میکنم اگر رکوردی که این 2 فیلدش این 2 عدد نیست پس این 2 عدد جدید هستند و به رکورد جدید میدم به همین سادگی اما بعد دیدم یکم که جدول جلو بره و رکوردها زیاد شن هر عدد رندومی که انتخاب کنم قبلا انتخاب شده ! و هزاران بار باید عدد جدید انتخاب کرد تا شانسی عدد انتخاب نشده پیدا شه که خیلی طول میکشه !

مثال :
انتخاب 2 عدد بین 0-200 شامل 200*200 حالت می شود یعنی 40 هزار جفت عدد
حال اگر ما 2 عدد رندوم اول انتخاب کنیم بعد بخاهیم ببینیم قبلا رکوردی با این دو عدد بوده یا نه برای شروع خوب است اما زمانی که مثلا 30 هزار رکورد پر شده هر عددی انتخاب کنیم احتمال زیاد میافته داخل همون 30 هزارتائی که قبلا انتخاب کردیم و احتمال اینکه عدد جدید داخل اون 10 هزارتای باقی مونده بیافته خیلی خیلی کمه و شاید تا ابد نیافته و قطعی نیست

bagherok
دوشنبه 28 مهر 1393, 11:57 صبح
مسئله پیچیده اما ساده نما !
چطور در هنگام ثبت نام یوزر جدید می توان 2 عدد رندوم بین 0-200 به 2 فیلد رکورد جدید داد که این 2 عدد تا به حال به هیچ رکورد دیگری داده نشده باشد

اول پیش خودم گفتم 2 عدد رندوم انتخاب می کنم و در جدول سلکت میکنم اگر رکوردی که این 2 فیلدش این 2 عدد نیست پس این 2 عدد جدید هستند و به رکورد جدید میدم به همین سادگی اما بعد دیدم یکم که جدول جلو بره و رکوردها زیاد شن هر عدد رندومی که انتخاب کنم قبلا انتخاب شده ! و هزاران بار باید عدد جدید انتخاب کرد تا شانسی عدد انتخاب نشده پیدا شه که خیلی طول میکشه !

مثال :
انتخاب 2 عدد بین 0-200 شامل 200*200 حالت می شود یعنی 40 هزار جفت عدد
حال اگر ما 2 عدد رندوم اول انتخاب کنیم بعد بخاهیم ببینیم قبلا رکوردی با این دو عدد بوده یا نه برای شروع خوب است اما زمانی که مثلا 30 هزار رکورد پر شده هر عددی انتخاب کنیم احتمال زیاد میافته داخل همون 30 هزارتائی که قبلا انتخاب کردیم و احتمال اینکه عدد جدید داخل اون 10 هزارتای باقی مونده بیافته خیلی خیلی کمه و شاید تا ابد نیافته و قطعی نیست
چرا رندوم
و چرا AUTO INCREMENT نه

اگه اصرار دارید
میتونید چندهزار تا عدد رندوم یا هرچند تا عدد رو درون یه جدول به اسم temp قرار بدید و
حالا هر بار یه سطر ازاین جدول رو سلکت کنید و بعد حذفش کنید

intel_amd
دوشنبه 28 مهر 1393, 12:33 عصر
دقیقا منهم به همین نتیجه رسیده بودم اما مشکل اینجاست که تعداد خیلی بالاست ! چون اعداد انتخابی بین 0-1000 هست که یعنی 1 میلیون جفت عدد وجود دارد که باید جدولی با 1 میلیون رکورد ایجاد کنم که سلکتاش سنگین میشه یک طرف , طرف دیگه قضیه اینه که for گذاشتم که 1 میلیون رکورد را در جدول اینسرت کنم اما چون در یک ترد این عمل انجام میشه منجر به هنگ و قطع ادامه پردازش میشه و فقط 200 رکورد اول درج میشه و بعدش قطع میشه
حالا اومدم اینکار کردم که یک جدول با فقط هزار رکورد 0-1000 ایجاد کردم و این جدول با خودش join کردم و کل اون 1 میلیون رکورد جفت عدد متمایز بهم داد

تا join که نوشتم به شکل زیره :
select * from fr JOIN fr as jd

الان جدول fr اعداد 0-1000 فقط داخلشه که با خودش join کردم که 1 میلیون جفت عدد مد نظرمو داده , یعنی کل جفت اعداد چه اونائی که برای هر یوزر انتخاب شده چه اونائی که هنوز انتخاب نشدن

حالا فقط این قسمت مونده که از جدول یوزرها که جفت اعداد انتخاب شده داخلشه و نتیجه این join سلکتی کنم که این فیلدهاشون برابر نیستو بهم بده و از نتیجش دیگه هر رکوردی انتخاب کنم جفت عدد انتخاب نشده است

سلکت هم میدونم به شکل زیره اما نمیتونم این سلکتو از نتیجه سلکت قبلی کنم
select * from natije joine ghabli,user where user.a!=atije join.a AND user.b!=natije join.b

hamedarian2009
دوشنبه 28 مهر 1393, 12:53 عصر
میتونید اینکارم بکنید بیاید قبل اینسرت اول تمام عددهای رندوم ذخیره شده داخل دیتابیس رو تویک آرایه فچ کنی و بعدش بیای از آرایه مرجعت که مثلا (40000-1)range هست با دستور array_diff مقادیر غیر تکراری رو دربیاری و از داخل این مقادیر یک عدد رندوم انتخاب کنی

intel_amd
دوشنبه 28 مهر 1393, 12:59 عصر
اعداد خیلی زیادن و آوردن و بردن تو آرایه و اینها خیلی سنگینه فقط اگر جواب پست قبله منو یکی بده همه چیز تمومه

bagherok
دوشنبه 28 مهر 1393, 13:05 عصر
وقتی باخودش join کردی سطرهای تکراری به وجود نیومد!!!
قسمت آخرشو متوجه نشدم.

میتونی دو تا جدول
یک فیلدی
اعددی رندوم بین 1 تا 1000 پرکنی
و هربارسطر اول هردوجدول رو سلکت و به هم متصلش کنی و بعد اون سطرها رو حذف کنی ازجدول
مثلا جدول یک
سطر اولش عدد 50
جدول دو
سطر اولش عدد1000

که میشه 501000

حالا این 50 و 1000 روحذف میکنی از جدول.
همین.

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

intel_amd
دوشنبه 28 مهر 1393, 13:21 عصر
چرا join جفت های برعکس هم که میده الان تست کردم

intel_amd
دوشنبه 28 مهر 1393, 13:38 عصر
دوستان فعلا من فقط نیاز به گرفتن کوئری زیر دارم


SELECT * FROM fr1,fr2 as er;
SELECT * FROM er,USER WHERE er.a!=USER.a AND er.a1!=USER.b;

intel_amd
دوشنبه 28 مهر 1393, 14:40 عصر
به شکل زیر هم این سلکتو خواستم انجام بدم بازم نشد



SELECT a,b FROM fr1,fr2 as ef where NOT EXISTS(select a,b from user);

bagherok
دوشنبه 28 مهر 1393, 18:05 عصر
پیشنهادم اینه که...
فایل sql ای که ضمیمه کردم رو دانلود کن
که یه جدول به اسم user_id میسازه
که یه فیلد بیشتر نداره به اسم id
که بصورت رندوم بین 1 تا 39900 شماره گذاری شده

هربار یه سلکت میزنی به اینصورت

select * from `user_id` limit 1
بعد id بدست اومده رو از جدول حذف میکنی

delete from `user_id` where id=$id







124762




برای ساخت اعداد رندوم هم از دو جدول باید بزنی CROSS JOIN
ضرب دکارتی



SELECT CONCAT(`t1`.id ,`t2`.id) as id FROM `t1` CROSS JOIN `t2`

intel_amd
دوشنبه 28 مهر 1393, 18:21 عصر
دوست عزیز کلیه جفت اعداد بین 0-1000 باید به صورت رندوم به یوزرها داده شوند و هیچ جفت عددی جا نیافته این جدولی که شما دادین به این منظور فایده ندارد
الان من فقط سر یک چیز کوچیک موندم اگر اینو بگین دیگه تموم میشه
ببینید من الان توسط کد زیر کلیه جفت اعداد موجود را بدست می آورم
select * from fr1,fr2
داخل fr1 فقط 1 فیلد با اعداد بین 0-1000 هست و داخل fr2 هم همینطور

پس الان کلیه جفت اعداد را داریم , از قبیل 1و2 2و1 1و1 و .......

حالا کافیست جفت اعداد انتخاب شدرو از کلیه جفت اعداد موجود برداریم تا هر سری جفت اعداد انتخاب نشده برامون بمونن تا از بینشون یکی برداریم بدیم به کاربر جدید
برای این کار باید جفت اعداد کلیه کاربر هارو که قبلا انتخاب شده اند را از نتیجه سلکت بالا فقط برداریم تا تهش جفت اعداد انتخاب نشده بمونه

الان فقط تو انجام این سلکت موندم که هرطور میزنم جواب نمیده
به عنوان مثال سلکت زیر جواب نمیده
SELECT a,b FROM fr1,fr2 as ef where NOT EXISTS(select a,b from user);

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

bagherok
دوشنبه 28 مهر 1393, 18:39 عصر
جوری دیگه هم میشد.(
نیازی نیست که چک کنید یوزر درون جفت عددهای join شده وحود داره یا نه.
هربار یکی ازاین سطرهای join رو بدید به یوزر و حذفش کنید)
این join از 11 شروع میکنه تا انتها
که با
limit
تنها سطر اول رو برمیگردونه.


SELECT `fr1`.id,`fr2`.id FROM `fr1`,`fr2` order by `fr1`.id ,`fr2`.id ASC limit 1


حالا این id بدست اومده رو بدید به کاربر
وبعد حذفش کنید.



اما هرجور که راحتترید
اینو تست کنید

SELECT `fr1`.a ,`fr2`.b FROM `fr1`,`fr2`
WHERE NOT EXISTS (
SELECT NULL FROM `user`
WHERE `user`.a = `fr1`.a AND `user`.b = `fr2`.b)

intel_amd
دوشنبه 28 مهر 1393, 21:21 عصر
الان 2 تا جدول که join میکنیم جدولش ایجاد نمیشه که بخوام سطریشو که به یوزری میدم حذف کنم , اگر هم بشه جدولشو به طور دائم روی هارد ایجاد کرد معقول هست یک جدول به این بزرگی به طور دائم ذخیره کنم؟ می خواستم فقط توی کوئری گرفتن ها 1 جدول فقط هزار سطری با خودش join کنم یا نهایتا 2 تا جدول هزار سطری باهم


SELECT `fr1`.a ,`fr2`.b FROM `fr1`,`fr2`
WHERE NOT EXISTS (
SELECT NULL FROM `user`
WHERE `user`.a = `fr1`.a AND `user`.b = `fr2`.b)


این کد الان تست کردم کار نمیکنه متاسفانه و من هم مشکلم دقیقا همینجاست که سر این گیر کردم که این کار نمیکنه

intel_amd
دوشنبه 28 مهر 1393, 21:23 عصر
اوه کوتیشن های کدتونو برداشتم کار کرد ! چه جالب من اونجا null نمیذاشتم خراب میشده دفعات قبلی
تشکر آقا مرسییییییییی