PDA

View Full Version : استفاده از courser و Rownumber



tefos666
شنبه 03 تیر 1391, 15:36 عصر
88650

با سلام - بنده دو جدول دارم که یکی شامل عناوین فاکتور (مشخصات مشتری - تاریخ و ...) می باشد و دیگری شامل اقلام فاکتور (کالاهایی که خرید کرده) - چون برای 1 شماره فاکتور n قلم جنس وارد می گردد لذا رابطه 1 به n دارند ، این 2 جدول با استفاده از 3 کلید بهم دیگر متصل شده اند ، حال بنا به دلایلی بنده نیاز به آن پیدا کرده ام که از تابعی مثل rownumber استفاده نمایم به صورتی که مثلا ش فاکتور 333 اگر در جدول دوم 10 بار تکرار شده فیلد link_ID آن 10 بار 1 شود و کالای دوم اگر ش ف 334 تعداد 4 بار بود فیلد link_ID در تمام سطرهایی که هرجا 334 بود Rownumber آن 2 شود یعنی به صورت دقیقتر مثل partion by عمل کند ، با این تفاوت که علاوه بر حفظ ترتیب rownumber هرجا ش فاکتور عوض شد rownumber عوض شود در غیر اینصورت rownumber تکرار شود



راهی که بنده به ذهنم رسید یک group by زدم بروی جدول اقلام فاکتور و شماره فاکتور را بهمراه تعداد تکرارش در آوردم ، حالا می خواهم اساتید کمک کنند تا با استفاده از یک کرسر و یا هرروش دیگری بروی select دوم فیلد link_ID را به صورت ذکر شده update کنم - نمونه کار هم به تصویر ضمیمه شده - باتشکر




--- avoid orderno
Declare @temp nvarchar(1000)
SELECT dbo.OrderDetail.OrderNo, COUNT(dbo.OrderDetail.OrderNo) AS tedad, dbo.OrderHeader.StrDate
FROM dbo.OrderDetail INNER JOIN
dbo.OrderHeader ON dbo.OrderDetail.OrderNo = dbo.OrderHeader.OrderNo AND dbo.OrderDetail.OrderTypeNo = dbo.OrderHeader.OrderTypeNo AND
dbo.OrderDetail.FinancYear = dbo.OrderHeader.FinancYear
GROUP BY dbo.OrderDetail.OrderNo, dbo.OrderHeader.StrDate
HAVING (dbo.OrderHeader.StrDate BETWEEN '1391/01/01' AND '1391/01/01')
-- avoid sale doc to update
SELECT @temp as [Lnk_ID], row_number()OVER ( PARTITION BY dbo.OrderHeader.OrderNo,dbo.OrderHeader.StrDate ORDER BY
dbo.OrderHeader.StrDate) AS RowNumber ,dbo.OrderHeader.TitleCode2,dbo.OrderHeader.Detail code2,dbo.OrderHeader.StrDate,dbo.OrderHeader.Orde rNO
,dbo.OrderDetail.GoodCode
FROM dbo.OrderDetail INNER JOIN
dbo.OrderHeader ON dbo.OrderDetail.OrderNo = dbo.OrderHeader.OrderNo AND dbo.OrderDetail.OrderTypeNo = dbo.OrderHeader.OrderTypeNo AND
dbo.OrderDetail.FinancYear = dbo.OrderHeader.FinancYear
where (dbo.OrderHeader.StrDate between '1391/01/01' and '1391/01/01')
and (dbo.OrderHeader.OrderNo=dbo.OrderDetail.OrderNo)
and (dbo.OrderHeader.OrderTypeNo=dbo.OrderDetail.Order TypeNo)
and (dbo.OrderHeader.FinancYear=dbo.OrderDetail.Financ Year)
order by dbo.OrderHeader.OrderNO
-- use curser

baktash.n81@gmail.com
شنبه 03 تیر 1391, 18:04 عصر
سلام

اول یه جدول می سازیم با CTE که Rownumber هم به عنوان یه ستون توش باشه ...


with CTEname(RowNumber,f1,f2,...)
as
(SelectRow_Number()Over (Orderby f1 , f2 ...), f1 , f2 From myTable1 )


بعد جدول دوم رو با حاصل این جدول Join و Update می کنیم ...


Update myTable2 Set link_ID=CTEname.RN From myTable2 join CTEname on myTable1.F1=CTEname.F1


البته من نمی دونم این کار به چه دردی می خوره ... و اینکه نفهمیدم چرا با 3 تا کلید جداول بهم وصلند ...

tefos666
شنبه 03 تیر 1391, 19:39 عصر
با سپاس فراوان بابت پاسخ - ولی مشکل بنده متاسفانه پابرجاست


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

شماره ردیف | کد فاکتور | تعداد اقلام
+++++++++++++++++++++++++++++++++++
01 | 2012 | 3
02 | 2016 | 2

و اطلاعات جدول دوم به صورت زیر

فیلد temp | کد فاکتور | کد کالا | تعداد| مبلغ
+++++++++++++++++++++++++++++++++++++++++++++++
نال | 2012 | 1001 | 2 | 16000
نال | 2012 | 1006 | 4 | 14000
نال | 2012 | 1005 | 2 | 16020
نال | 2016 | 6045 | 1 | 18620
نال | 2016 | 7005 | 2 | 13070

من چون در جدول اول 3 قلم دارم پس در جدول دوم ملاحظه می نمایید که مد فاکتور 2012 به تعداد 3 بار آورده شده و همچنین کالای دیگر 2 بار و .....

من می خواهم در فیلد temp اطلاعات همسان با شماره ردیف جدول اول باشد (پس از update) یعنی جدول زیر بدرد من می خورد

فیلد temp | کد فاکتور | کد کالا | تعداد | مبلغ
++++++++++++++++++++++++++++++++++++++++++++++++++ +
01 | 2012 | 1001 | 2 | 16000
01 | 2012 | 1006 | 4 | 14000
01 | 2012 | 1005 | 2 | 16020
02 | 2016 | 6045 | 1 | 18620
02 | 2016 | 7005 | 2 | 13070


===============================================
همانگونه که ملاحظه کردید اگر از partion by استفاده کنم خروجی به صورت زیر می شود

فیلد temp | کد فاکتور | کد کالا | تعداد | مبلغ
++++++++++++++++++++++++++++++++++++++++++++++
01 | 2012 | 1001 | 2 | 16000
02 | 2012 | 1006 | 4 | 14000
03 | 2012 | 1005 | 2 | 16020
01 | 2016 | 6045 | 1 | 18620
02 | 2016 | 7005 | 2 | 13070
یعنی با هر بار تغیر فاکتور counter صفر می شود و این گزینه به درد من نمی خورد
و یا اگر از row_number هم استفاده کنم خروجی به صورت زیر می شود که باز هم به درد من نمی خورد

فیلد temp | کد فاکتور | کد کالا | تعداد | مبلغ
+++++++++++++++++++++++++++++++++++++++++++++++
01 | 2012 | 1001 | 2 | 16000
02 | 2012 | 1006 | 4 | 14000
03 | 2012 | 1005 | 2 | 16020
04 | 2016 | 6045 | 1 | 18620
05 | 2016 | 7005 | 2 | 13070



باتشکر .

baktash.n81@gmail.com
یک شنبه 04 تیر 1391, 07:33 صبح
راه حلی که نوشتم Row_number رو تو جدول اول بدست می آره بعد تو جدول دوم Update می کنه نه اینکه Row_Number جدول دوم رو حساب کنه برای اینکه با همه داده ها کار نکنی هم می تونی توی CTE اونارو فیلتر کنی هم می تونی هنگام Join اینکارو بکنی .... احتمالا شما اصلا کدی رو که گذاشتم امتحان نکردی

nedata
یک شنبه 04 تیر 1391, 08:17 صبح
Update Table2
Set Temp=t1.RowN
From table1 t1 join Table2 t2 on
t1.FactorNo=t2.FactorNo