View Full Version : مشکل update با استفاده از دادهای یک select دیگر و عدم انجام روی رکورد های تکراری
rexi1r
چهارشنبه 16 تیر 1395, 03:49 صبح
با سلام دوستان من یه کوئری نوشتم که ابتدا یه لیست از داده رو داخل یه جدول local ذخیره میکنه و بعدش با استفاده از داده های داخل اون میخوام یه فیلد از یه جدول دیگه رو آپدیت کنم .اما مشکل اینجا که مثلا دوتا رکورد یکسان داخل اون جدول local ام هست و بنابراین اون دستور update من باید دوبار عملیات update رو روی اون یک روکورد خاص انجام بده که متاسفانه خودش رکورد های duplicate رو از جدول local حذف میکنه و فقط یکبار عملیات اپدیت رو انجام میده .
UPDATE Users
SET Users.deducted_coins += 2,
Users.coins -= 2
WHERE Users.phonenumber IN (SELECT cs.phone FROM @UserLeft as cs)
141273
اگر به عکس دقت کنید ما دو تا رکورد متفاوت تو جدول local خودمون داریم که شماره تلفن یکسان دارن.پس باید دوبار عملیات update روی جدول users و اون رکورد خاص انجام بشه.ولی شرط where ظاهرا تکراری ها رو حذف میکنه و فقط یکبار آپدیت انجام میگیره.
rexi1r
پنج شنبه 17 تیر 1395, 09:03 صبح
چه ربطی به سوال من داره؟؟؟؟؟ سوال رو اگه واضح ننوشتم لطفا بگید تا توضیحات بیشتری اضافه کنم.ممنون میشم اگر دوستان اطلاعاتی دارن راهنمایی کنن.
Mahmoud.Afrad
پنج شنبه 17 تیر 1395, 14:26 عصر
در IN فقط بودن یا نبودن بررسی میشه و اصلا تعداد مهم نیست(مبحث مجموعه ها در ریاضی و عضو بودن یک عنصر در یک مجموعه)
برای استفاده از تعداد باید ابتدا اون رو محاسبه کنید
declare @UserLeft table(phone varchar , phoneCount int)
insert into @UserLeft(phone , phoneCount)
select UserLeft.phone, COUNT(UserLeft.phone)
from UserLeft
group by UserLeft.phone
UPDATE UsersTbl
SET UsersTbl.deducted_coins += uu.phoneCount * 2 ,
UsersTbl.coins -= uu.phoneCount * 2
from UsersTbl
inner join @UserLeft uu on UsersTbl.phonenumber = uu.phone
یا
; with cte
as
(
select UserLeft.phone, COUNT(UserLeft.phone) as phoneCount
from UserLeft
group by UserLeft.phone
)
UPDATE UsersTbl
SET UsersTbl.deducted_coins += cte.phoneCount * 2 ,
UsersTbl.coins -= cte.phoneCount * 2
from UsersTbl
inner join cte on cte.phone = UsersTbl.phonenumber
پ.ن: منطق برنامتون رو نمیدونم چیه ولی با توجه به اینکه مقادیر قدیم رو با مقادیر جدید برای همه رکوردها جمع می کنید و هر بار این اتفاق دوباره تکرار میشه ، به نظرم ممکنه یکسری از رکوردها چند بار باعث افزایش coin بشن(خطای منطقی براتون شاید بوجود بیاد مگر اینکه مقادیر رو جمع نکنید). اگر دو ستون deducted_coins و coins صرفا محاسباتی هستند نیازی بهشون نیست و در مواقع مورد نیاز محاسبه بشن بهتره.
rexi1r
جمعه 18 تیر 1395, 15:06 عصر
استاد عزیز ممنون بابت پاسخ.واسه من تعداد مهم نیست.من یه جدولی مجازی درست میکنم که فرضا داخلش پنج تا رکورد هست دوتا رکورد با آی دی های یکسان 6 و مثلا سه تا رکوردش مقدار آی دی 5 دارن.تا اینجا خب مشکلی نیست .حالا میخوام یه دستور آپدیت بنویسم که دقیقا اینکار رو انجام بده.رکورد اول همون جدول مجازی رو نگاه کنه و آیدیش رو بخونه (که اینجا آی دیش مقدار 6 داره) بعد بره تو جدول user مقدار coin مربوط به اون آی دی یعنی 6 رو به مقدار 2 تا کم کنه.دوباره بره سراغ رکورد دوم جدول مجازی و مقدار آیدی رو بخونه که باز هم مقدار آی دی 6 و بره تو جدول user و مقدار coin رو باز هم دوتا کم کنه(یعنی تا اینجا به ازای دوتا رکوردی که تو جدول بودن با مقدار آی دی یکسان 6 دوبار عملیات کم کردن سکه برای اون آی دی خاص انجام شده )و برای آی دی 5 هم همین اتفاق میافته یعنی 3 بار عملیات کم کردن سکه انجام میشه .
حالا مشکل کجاست ؟اینجا که دستور in تکراری ها رو حذف میکنه یعنی توی اون جدول مجازی میاد کلا یکبار عملیات رو برای آی دی 6 و یکبار هم برای آی دی 5 روی جدول user در نظر میگیره و کاری به رکورد های دیگه نداره.
*دوتا فیلد coin و deducted_coins هردوتا نیاز هست که ذخیره بمونن و محاسبه ای نیستن.
Mahmoud.Afrad
جمعه 18 تیر 1395, 21:29 عصر
کد که قرار دادم. توضیح هم دادم که باید تعداد محاسبه بشه تا بتونید در 2 ضرب کنید. اصلا کد بنده رو تست کردید؟
اگر متوجه نشدید، کوئری که @UserLeft رو ایجاد و مقدار دهی کردید رو بزارید.
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.