PDA

View Full Version : مشکل در دستور sql



رضا قربانی
چهارشنبه 15 تیر 1390, 04:41 صبح
سلام خدمت تمامی دوستان گل اتحاد

یه مشکل کوچیک دارم که هر کاری کردم نتونستم درستش کنم

ببینید این کد های منه :



$sql1 = 'SELECT count(*) as m,`ticket_user`,MAX(ticket_pdate) as `ticket_pdate` ,view '
. ' FROM `tbl_all_ticket` '
. ' group by `ticket_user` '
. ' ORDER BY `tid` DESC,`view` desc LIMIT '.$start.', '.$end.'';



من با هیچ جاش مشکل ندارم ، مشکل من فقط با نمایش فیلد view هست .

فیلد view من یا 0 هست یا 1 . حالا من می خوام آخرین رکوردی که در گروه درج شد view هم آخرین رو بزنه.


مثلا الان آخرین رکورد شماره 42 هست که view برابر با 1 هست ولی میره رکورد 30 رو می خونه که view برابر با 0 هست.

حالا دلیلش رو بگم چرا می ره رکورد 30 رو می خونه : چون با وارد کردن اطلاعات در اون حجم اون رکورد بالاتر از همه هست . مشکلم اینجاست که نمی خوام اینطوری باشه.
می خوام مثل بچه ی آدم بر اساس آخرین ارسال view هم آخرین رو بزنه که 1 هست نه رکورد 30 که 0 هست .


ممنون می شم کمکم کنید و امیدوارم واضح توضیح داده باشم .

MMSHFE
چهارشنبه 15 تیر 1390, 09:08 صبح
با سلام، مشكل از نحوه مرتب سازي ركوردهاي شماست. دقيقاً بگين ميخواين چطور ركوردها مرتب بشن تا راهنمايي كنم. دقت كنيد كه چون بر اساس tid و view و اون هم بصورت نزولي دارين مرتب ميكنيد، طبيعتاً viewهاي 0 ميان آخر. مرتب سازي رو اصلاح كنيد (مثلاً بر اساس id صعودي) تا آخرين ركورد به شكل درست انتخاب بشه.
موفق باشيد.

رضا قربانی
چهارشنبه 15 تیر 1390, 11:53 صبح
آقا اینا مشکلم نیست . همه چی رو تست کردم.



دقت كنيد كه چون بر اساس tid و view و اون هم بصورت نزولي دارين مرتب ميكنيد، طبيعتاً viewهاي 0 ميان آخر. مرتب سازي رو اصلاح كنيد (مثلاً بر اساس id صعودي) تا آخرين ركورد به شكل درست انتخاب بشه.

ببین مشکل من مرتب سازی نیست . اون میاد رکورد select شده رو مرتب می کنه !! درسته
خب حالا من موقع select گرفتن باید تصحیح کنم .


شما اصلا خط آخر `view` desc رو در نظر نگیرید . بر اساس tid مرتب کردم .
من مشکلم رو واضح گفتم . در view همیشه اونی که محتویات بیشتری داره یقینا حجم بیشتری هم داره ، پس میاد اون رو نشون می ده من نمی خوام اونطوری باشه . می خوام رکوردی که درج می شه view هم آخرین رو بهم نشون بده.

در group من نمی تونستم از * استفاده کنم چون یک سری دستورات باید اعمال می شد . پس من بقیه فیلدها رو به خوبی نشون می دم یعنی آخرین رکوردی که درج می شه ولی توی نمایش آخرین viewموندم .

برای معرفی view دستور خواصی نباید در کنار ش بذارم که بگه بر اساس آخرین tid بیاد 0 و 1 رو بزنه ؟

MMSHFE
چهارشنبه 15 تیر 1390, 12:06 عصر
ميشه دقيقاً بگين دستور SELECT كه ميخواين، چه كاري بايد انجام بده و يه توضيح هم درباره ساختار جدول و مقادير فيلدها بدين و اينكه هر فيلد دقيقاً چه چيزي رو ذخيره ميكنه؟

رضا قربانی
چهارشنبه 15 تیر 1390, 12:50 عصر
ببینید یه شخصی میاد و چند تا پیام ارسال می کنه که توی صفحه ادمین نام اون شخص فقط یه بار زده می شه (ticket_user) که انداختمش توی گروپ که یکی فقط نشون میده و آخرین تاریخ ارسالی پیام که با max اومدم نشونش دادم (ticket_pdate) و یک view دارم که مقدارش یا 1 هست یا 0 که اگر یک بود یعنی پاسخ داده شد و یک tid .

حالا من می خوام این view هم مثل اونا بر اساس آخرین پیامی که در رکورد درج می شه بزنه نه اینکه بر اساس حجم بیشترین رکورد بزنه.

مثلا tid یوزری که پیام ارسال می کنه 44 هست که باید view بر اساس رکورد 44 شماره 1 یا 0 بزنه ولی میاد می ره روی رکوردی که داخلش متن بیشتری درج شده .

من به خدا همه چیز رو واضح از اول توضیح دادم . دیگه واضح تر نمی تونم

رضا قربانی
چهارشنبه 15 تیر 1390, 19:07 عصر
کسی نبود ؟

امیـرحسین
چهارشنبه 15 تیر 1390, 23:03 عصر
این کار کلا جالب و بهینه نیست ولی راه حل Subquery هست. شبیه این:
SELECT
COUNT(field1) AS total,
MAX(field2) AS maxim,
(SELECT field3 FROM tbl WHERE 1 ORDER BY id DESC LIMIT 1) AS lastOne
FROM tbl WHERE 1 LIMIT 1

همیشه WHERE رو قرار بدید حتی با مقدار TRUE (مثل نمونه‌ی بالا) و در این حالت، LIMIT 1 در InnoDB بسیار در سرعت تاثیر داره.

رضا قربانی
پنج شنبه 16 تیر 1390, 12:24 عصر
من الان به این صورت عمل کردم


$sql1 = 'SELECT count(*) as m,`ticket_user`,max(ticket_pdate) as ticket_pdate,(SELECT `view` FROM `tbl_all_ticket` WHERE TRUE ORDER BY tid DESC limit 1 ) AS L '
. ' FROM `tbl_all_ticket` '
. ' group by `ticket_user` '
. ' ORDER BY `tid` DESC LIMIT '.$start.', '.$end.'';



حالا وقتی یک کاربر باشه و پیام بده درست می زنه . یعنی بر طبق آخرین ارسالش 0 و 1 می زنه . ولی حالا اگه بیشتر از یک کاربر با نام مختلف پیام بدن سیستم اولویت رو می ده به اونی که بیشترین تاریخ رو داره و پیام تمام کاربر ها رو بر طبق view اون می زنه . یعنی همش یا 1 می شه یا 0 .

با distinct هم تست کردم ولی بازم مثل بالا شد . یعنی وقتی داخل سلکت یه سلکت دیگه می دیم کلا رکوردها با اون ست می شن


$sql1 = 'SELECT DISTINCT ticket_user,ticket_pdate,(SELECT `view` FROM `tbl_all_ticket` WHERE TRUE ORDER BY tid DESC limit 1 ) AS L '
. ' FROM `tbl_all_ticket` '

. ' ORDER BY `tid` DESC LIMIT '.$start.', '.$end.'';


برنامه نویسی که من انجام دادم باید حتما از group استفاده کنم و فقط هم مشکلم نمایش صحیح view برای هر رکورد هست .


f1 f1 f1 Me :d

رضا قربانی
پنج شنبه 16 تیر 1390, 18:09 عصر
F1 Me...F1

امیـرحسین
پنج شنبه 16 تیر 1390, 20:38 عصر
چه اصراریه که همه‌ی اطلاعات بی‌ارتباط به هم رو در یک کوئری بگیرید؟ توابع GROUP (مثل COUNT و MAX) رو باید مقادیر مشخص ادغام نکنید. اگر خیلی نگران بهینگی هستید از Stored Procedures استفاده کنید.
دو تا کوئری به مراتب بهتر از SubQuery هست. SubQuery به جدولی که داریم ازش کوئری میگیریم خیلی کار بدیه و واسه شرایط خیلی خاصه...

رضا قربانی
شنبه 18 تیر 1390, 04:58 صبح
آقا بذار یه مثال ساده و خیلی بهتر بزنم :لبخند:

فرض کن من سه تا فیلد دارم . id-view-user
ببینید حالا یک یوزری میاد 10 تا پیام می ده وview هم در کنارش یا 0 می خوره یا 1 . حالا زمانی که کاربر رکورد جدیدی ثبت کرد اون رکورد view یا صفر می شه یا 1 که می خوام بر اساس آخرین id نمایش بده .

نتیجه صحبت های بالام به این ختم می شه یعنی اگر یوزر 10 پیام درج کنه فقط یکبار ثابت می مونه و جولوش 0 و 1 تغییر می کنه :


$sql ="select * from `tbl` group by `user` ORDER BY `id` DESC" ;

ببینید این تا یک user ثبت شده باشه درست ، و طبق روال بر اساس آخرین آی دی 0 و 1 می زنه . اما اما اما اگر بیشتر از دو user رکورد درج کنند این دیگه بر اساس id نمی زنه بر اساس حجم می ره روی رکورد و اون رو نمایش می ده ..


من شرایطم خیلی خواصه و مربوط به صفحه ادمین می شه

شما چه راهی رو پیشنهاد می کنید :متفکر:

farshad sepehri
شنبه 18 تیر 1390, 18:44 عصر
سلام رضا جان .ببین از این روش میشه استفاده کرد .


select col (s) from tbl_name
where cond(s)
order by col(s)name
group by col(s) name
having cond(d)



تو قسمت having از شرط دومت استفاده کن ولی فقط یه طوری بنویس که گروه بندیت بر اساس اون باشه

رضا قربانی
شنبه 18 تیر 1390, 23:36 عصر
نه متاسفانه . نتونستم هنوز ، این چیزا نیست

رضا قربانی
یک شنبه 19 تیر 1390, 18:28 عصر
من فایل رو براتون آماده کردم و فقط کافیه بانک رو در mysql ایمپورت کنید .
همه چی رو در خود فایل واضح توضیح دادم و ممنون می شم ببینید مشکلم کجاست

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

رضا قربانی
پنج شنبه 30 تیر 1390, 00:25 صبح
کسی می تونه کمکمون کنه . گیر کردیم . همه چیرو آماده کردمو فقط باید چند تا کد اضافه کنید و ببینید جواب می ده یا نه.

لطفا راهنمایی نمایید

رضا قربانی
سه شنبه 04 مرداد 1390, 02:20 صبح
با تشکر از همه ی عزیزانی که ما رو راهنمایی کردند

از جمله آقا مهرداد گلم و استاد گرامی آقای حمید امامیان که لطف کردن و کوئری صحیح رو برای ما نوشتن .


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


$sql.="select * from tbl_group where user in ( select user from (select user,max(pdate) as p from tbl_group
group by user) as internal) and pdate in ( select p from (select user,max(pdate) as p from tbl_group
group by user) as external) ";

دستشون درد نکنه
موفق باشید