ورود

View Full Version : بدست آوردن ایتم های غیر تکراری از دو جدول در ارتباط با هم



blackrose1986
شنبه 04 خرداد 1392, 01:19 صبح
سلام . من دو جدول با مشخصات زیر دارم :
جدول staffبا فیلد های (sId,sName) که sId کلیداصلی هست .
جدول updateStaff با فیلدهای (usId,sId,price,date) که usId کلیداصلی و sId کلید خارجی که ازجدول staff اومده.

حالا من میخوام یه کوئری با sql داشته باشم که تمام کالا های غیر تکراری رو بر حسب آخرین تاریخ درج با قیمتشون نشون بده .
برای مثال :
http://www.mediafire.com/convkey/cc8f/9j9lwfdz2n0uu8w4g.jpg (http://www.mediafire.com/view/9j9lwfdz2n0uu8w/1.png)

و حالا میخوام نتیجه به این شکل باشه

http://www.mediafire.com/convkey/35e1/r2tlgglcf9q39bf4g.jpg (http://www.mediafire.com/view/r2tlgglcf9q39bf/2.png)

البته من این سوال رو در سایت stackoverflow هم کردم ولی فعلا جوابی نگرفتم خوشحال میشم اساتید ایرانی بتونن کمکم کنن .
با تشکر

cherchil_hra
شنبه 04 خرداد 1392, 08:08 صبح
اول از همه بیشترین تاریخ ها رو بر اساس sId آنها، با این روش پیدا می کنیم:

SELECT *, MAX([date]) OVER(PARTITION BY [sId]) AS MaxDate
FROM mytable

یک ستون به اسم MaxDate به خروجی جدول شما اضافه میشه که بر اساس sid بزگترین تاریخ رو بدست میاره
104635

در مرحله بعد، زمان join با جدول staff، شما باید maxDate رو با Date مقایسه کنید تا فقط سطرهایی که با maxDate برابر هستند نمایش داده بشوند:


SELECT s.[sId],
s.sName,
Result.Price
FROM (
SELECT *,MAX([date]) OVER(PARTITION BY [sId]) AS MaxDate
FROM mytable
) AS Result
INNER JOIN staff AS s
ON s.[sId] = Result.[sId]
WHERE Result.MaxDate = Result.[date]


که نتیجه خروجی مورد نظر شما خواهد بود.

محمد سلیم آبادی
شنبه 04 خرداد 1392, 11:24 صبح
select sid, sname, price
from
(
select row_number() over(partition by u.sid order by date desc) as rnk, s.Sname, u.*
from staff f
inner join updatestaff u
on f.sid = u.sid
)d
where rnk = 1
order by sid;

Salah Sanjabian
شنبه 04 خرداد 1392, 11:30 صبح
سلام جوابتون جالب یود . اول Max رو بدست آوردین بعد Join
یه روش دیگه اول Join بعد Max

SELECT D.sId ,D.sName,D.price
FROM (
SELECT staff.sId ,staff.sName,price,
updateStaff.date
FROM staff
INNER JOIN updateStaff
ON staff.sId = updateStaff.sid
) D
WHERE
D.date=
(
SELECT MAX(date)
FROM updateStaff
WHERE updateStaff.sid=s.SID
)

blackrose1986
شنبه 04 خرداد 1392, 12:49 عصر
سلام به همه دوستان و اساتید گرامی ... کوئری ها مطابق با خواسته من و درست بود ... ممنون از کمکتون
اما من تا به حال دستور OVER(PARTITION BY رو ندیده بودم .
اگه میشه راجع به این دستور بیشتر توضیح بدین

MAX([date]) OVER(PARTITION BY [sId])
آیا این دستور مثل Group By عمل میکنه ؟
ممنونم

فقط یک نکته که در اصلاح جواب دوست عزیز Salah Sanjabian : در خط آخر WHERE updateStaff.sid=s.SID باید اینطور نوشته بشه WHERE updateStaff.sid=D.sId

باز هم ازراهنمایی همتون ممنون

Salah Sanjabian
شنبه 04 خرداد 1392, 16:22 عصر
تو قسمتی که گفتی Over میاد رکورد ها رو بر اساس SID گروه بندی میکنه و تو هرگروه آخرین تاریخ یا همون Max رو بدست میاره بهتره رفرنس انگلیسی رو واست اینجا بذارم تا خودت بهتر متوجه بشی درمورد Over

The OVER Clause
The OVER clause exposes a window of rows to certain kinds of calculations. Think of a window of rows simply as a certain set of rows that the calculation operates on. Aggregate and ranking functions, for example, are the types of calculations that support the OVER clause. Because the OVER clause exposes a window of rows to those functions, they are known as window functions.

Because the whole point of an aggregate function is to aggregate a set of values, aggregate functions traditionally operate in the context of GROUP BY queries

این کوئری رو در نظر بگیر

SELECT orderid, custid, val,
SUM(val) OVER() AS totalvalue,
SUM(val) OVER(PARTITION BY custid) AS custtotalvalue
FROM Sales.OrderValues;


بدون این که از Group By استفاده کنه با استفاده از Over اینکارو با موفقیت انجام میده . ستون اول میاد جمع Val همه رکورد هارو بدست میاره و ستون دوم میاد جمع Val رو بر اساس Custid یدست میاره درواقع همون گروه یندی براساس Custid .یه ذره ریزه کاری دیگه داره اون دیگه با خودت:لبخندساده:

محمد سلیم آبادی
شنبه 04 خرداد 1392, 19:15 عصر
سلام جوابتون جالب یود . اول Max رو بدست آوردین بعد Join
یه روش دیگه اول Join بعد Max

SELECT D.sId ,D.sName,D.price
FROM (
SELECT staff.sId ,staff.sName,price,
updateStaff.date
FROM staff
INNER JOIN updateStaff
ON staff.sId = updateStaff.sid
) D
WHERE
D.date=
(
SELECT MAX(date)
FROM updateStaff
WHERE updateStaff.sid=s.SID
)


سلام
query که نوشتی را میشه به شکل زیر بهینه کرد:
SELECT *
FROM updateStaff U
INNER JOIN
(
SELECT sid, MAX(date) AS maximum
FROM updateStaff
GROUP BY sid
)D
ON U.sid = D.sid
AND U.date = D.maximum
INNER JOIN Staff S
ON U.sid = S.sid;