ورود

View Full Version : چند expression قبل از IN



titbasoft
یک شنبه 21 فروردین 1384, 20:23 عصر
می دونم که در SQL-Server نمی شه قبل از IN از چند فیلد استفاده کرد (همون کاری که توی oracle می شه انجام داد و فکر کنم طبق قوانین ANSI هم باید بشه این کار رو کرد). یه چیزی به این شکل:

SELECT * FROM t1 WHERE c1,c2 IN (SELECT c1,c2 FROM t2)
اما لطفا یه راه حل برای سناریوی زیر ارائه بدین:
جدول parent ما Composit PK (چندتائی) داره. حالا ما یک query از جدول parent گرفتیم که حاوی 3 تا رکورده. حالا می خواهیم رکوردهایی از جدول child رو بدست بیاریم که parent شون یکی از اون 3 تا است.
من خودم چند تا فیلد رو با یه الگوریتم خاص تبدیل کردم به یک فیلد و ازش استفاده کردم ولی به نظر منطقی نمیاد. :(

AminSobati
یک شنبه 21 فروردین 1384, 23:46 عصر
دوست عزیزم،
جدوال زیر رو در نظر بگیرین: یکی اطلاعات دانشجوها و دیگری اطلاعات امتحاناتی که در اونها شرکت کردند:

CREATE TABLE Students(
FName varchar(50),
LName varchar(50),
PRIMARY KEY(FName,LName))

CREATE TABLE StudentExam (
FName varchar(50),
LName varchar(50),
Exam varchar(50))

INSERT Students VALUES ('Ali','Asadian')
INSERT Students VALUES ('Reza','Karimi')
INSERT Students VALUES ('Nima','Salehi')

INSERT StudentExam VALUES ('Ali','Asadian','Access')
INSERT StudentExam VALUES ('Ali','Asadian','VB')
INSERT StudentExam VALUES ('Reza','Karimi','SQL')
INSERT StudentExam VALUES ('Reza','Karimi','XML')
INSERT StudentExam VALUES ('Reza','Karimi','VB')
INSERT StudentExam VALUES ('Nima','Salehi','SQL')
INSERT StudentExam VALUES ('Nima','Salehi','C')
در حقیقت Query مورد نظر شما یک JOIN ساده خواهد بود مشروط بر اینکه شرط موجود در Query از Parent رو با شرط موجود در Query از Child ادغام کنید. مثلا Query از جدول Parent اگر این باشه:

SELECT FName,LName FROM Students WHERE FName LIKE '%i%'
پس Query اصلی شما این خواهد بود:

SELECT * FROM StudentExam SE JOIN Students S ON
SE.FName=S.FName AND
SE.LName=S.LName WHERE
S.FName LIKE '%i%'
اما اگر بنا به هر دلیلی این ادغام نباید یا نمیتونه صورت بگیره، از تابع EXISTS میتونین استفاده کنین:

SELECT * FROM StudentExam SE WHERE EXISTS
(
SELECT FName,LName FROM Students WHERE FName LIKE '%i%' AND
SE.FName=FName AND SE.LName=LName
)
حالا اگر نگاهی به Exec Plan هر دو Query بندازین، دقیقا یک چیز رو میبینین!

titbasoft
دوشنبه 22 فروردین 1384, 00:26 صبح
اون لحظه ای که داشتم سوالم رو می نوشتم داشتم فکر می کردم که از طریق join باید بشه این کار رو کرد.
کمک بزرگی کردید. ممنون :wink:


حالا اگر نگاهی به Exec Plan هر دو Query بندازین، دقیقا یک چیز رو میبینین! :تشویق:
دقیقا درسته چون در هر دو ، از جدول parent با شرط وجود i و از جدول child با شرط برابری PK دیتا ها جمع آوری شده و در یک nested loop با هم تطبیق پیدا می کنند.

AminSobati
دوشنبه 22 فروردین 1384, 09:10 صبح
من در Query آخر، تقریبا باز شرط رو ادغام کردم. برای اینکه Query از Parent کاملا دست نخورده باقی بمونه میتونیم اون رو داخل SubQuery قرار بدیم:

SELECT * FROM StudentExam SE WHERE EXISTS
(
SELECT FName,LName FROM
(SELECT * FROM Students WHERE FName LIKE '%i%') TmpTable WHERE
SE.FName=FName AND SE.LName=LName
)