PDA

View Full Version : فیلتر having



sama552
چهارشنبه 17 فروردین 1390, 12:19 عصر
سلام دوستان
من یک store procedure دارم که قراره لیست کارتهایی که بیشتر از 30 تااست ودر step ی 6 قرار داره را برام لیست کند ولی وقتی شرط having رو برای storeprocedure میگذارم فقط می تونه تعداد روبرام بیاره ولی من لیست card-id هایی رو می خوام که بیشتر از 30 تا در step ی 6 قرار دارند را بیارد

select dbo.RelationStep.Card_Id
from
SELECT dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id,count(dbo.RelationStep .Card_Id)
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

محمد سلیم آبادی
چهارشنبه 17 فروردین 1390, 14:15 عصر
سلام،
(بهتر بود کد رو داخل تگ کد قرار می دادین تا قابل خوندن بشه)
بین کوئری که ارسال کردین و گفته هایتان تناقض وجود داره، شما card_id هایی را می خواهین که تعدادشان (با در نظر گرفتن step =6) بیش از 30 باشد ولی در خط آخر کوئری عدد 10 نوشته شده.
در کل من مشکل خاصی در کوئری که ارسال کردین نمی بینم. کافیه دو خط اول کوئری را حذف کنید و عدد 10 رو به 30 ارتقاع بدین.

یعنی اگر فقط به ستون card_id نیاز دارین کوئری زیر باید جواب مورد نظر را تولید کنه:

SELECT R.Card_Id
FROM dbo.Card AS C
JOIN dbo.RelationStep AS R
ON C.Id = R.Card_Id
WHERE (R.Step = 6)
GROUP BY R.card_id
HAVING COUNT(*) > 30;

sama552
یک شنبه 21 فروردین 1390, 12:31 عصر
سلام،
(بهتر بود کد رو داخل تگ کد قرار می دادین تا قابل خوندن بشه)
بین کوئری که ارسال کردین و گفته هایتان تناقض وجود داره، شما card_id هایی را می خواهین که تعدادشان (با در نظر گرفتن step =6) بیش از 30 باشد ولی در خط آخر کوئری عدد 10 نوشته شده.
در کل من مشکل خاصی در کوئری که ارسال کردین نمی بینم. کافیه دو خط اول کوئری را حذف کنید و عدد 10 رو به 30 ارتقاع بدین.

یعنی اگر فقط به ستون card_id نیاز دارین کوئری زیر باید جواب مورد نظر را تولید کنه:

SELECT R.Card_Id
FROM dbo.Card AS C
JOIN dbo.RelationStep AS R
ON C.Id = R.Card_Id
WHERE (R.Step = 6)
GROUP BY R.card_id
HAVING COUNT(*) > 30;


سلام
از این که وقت گذاشتید و تاپیک من رو پاسخ دادید ممنونم
ولی مشکلم هنوز حل نشده اولا اینکه مشکل من با عدد 10 و 30 نبود که درتاپیک ÷اسخ داده بودید مشکل من این بود که من می خواستم query ی مورد نظر لیست step,cours_Id,student_Idوcard_Idرا برام بیاره به شرطی که تعداد کارتها بیشتر از 10 تا یا هر تعدادی باشد
ولی query ای که الان برای شما منویسم

SELECT dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id,count(dbo.RelationStep .Card_Id)
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

این نتیجه را بر میگردونه که نام ستون هاstep,student_Id,cours_Id,count(card_Id)

6 121 95 32
6 121 101 22
6 121 105 77
6 121 109 34
6 121 110 26
6 121 111 21
6 121 112 15
6 121 114 47
6 121 179 92

است
حالا من میخوام به علاوه ستون های step,student_Id,cours_Id
لیست کارتهایی که شامل این شر ط اند را هم داشته باشم در صورتیکه این کوئری فقط تعداد را می یار در ضمن کوئری قبلی هم که گذاشته بودید مشکلم رو حل نکرد
با توجه به توضیحاتی که دادم ممنون میشم اگر راهنمایی کنید

ahmadpj
یک شنبه 21 فروردین 1390, 14:13 عصر
شايد با يك select ديگه مشكل حل بشه. در select شما ريز ركوردهايي كه ميخواين به دست نميارين بلكه گروه بندي شده ي اونها رو به دست ميارين، كه بايد از يك select ديگه براي ريز ركوردها استفاده كنين.

اين رو امتحان كنين:


select * from dbo.Card INNER JOIN dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id WHERE card_id in


(

SELECT card_Id FROM dbo.Card INNER JOIN

dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id

WHERE (dbo.RelationStep.Step = 6)

GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id

HAVING count(dbo.RelationStep.Card_Id) > 10


)

sama552
یک شنبه 21 فروردین 1390, 14:38 عصر
شايد با يك select ديگه مشكل حل بشه. در select شما ريز ركوردهايي كه ميخواين به دست نميارين بلكه گروه بندي شده ي اونها رو به دست ميارين، كه بايد از يك select ديگه براي ريز ركوردها استفاده كنين.

اين رو امتحان كنين:


select * from dbo.Card INNER JOIN dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id WHERE card_id in


(

SELECT card_Id FROM dbo.Card INNER JOIN

dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id

WHERE (dbo.RelationStep.Step = 6)

GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id

HAVING count(dbo.RelationStep.Card_Id) > 10


)


با سلام
ممنون از راهنماییتون ولی اصلا select داخلی برای من چیزی نشون نمیده

SELECT card_Id FROM dbo.Card INNER JOIN

dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id

WHERE (dbo.RelationStep.Step = 6)

GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id

HAVING count(dbo.RelationStep.Card_Id) > 10

ولی این سه خط اول لیست کارت هامو می آره
SELECT dbo.Card.Id FROM dbo.Card INNER JOIN

dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id

WHERE (dbo.RelationStep.Step = 6)
ولی دو خط بعدی را که اضافه می کنم هیچ خروجی ای نشون نمیده

ahmadpj
یک شنبه 21 فروردین 1390, 22:35 عصر
بله حق با شماست، من select شما رو کپی کردم و همینجوری اسم فیلد آی دی کارت رو آوردم، ولی اون select داخلی درست نیست چون جلوی select نمی تونیم اسم فیلدی رو بنویسیم که در قسمت group by مشخص نکردیم، مگر اینکه تابعی از فیلدها باشه مثل count یا sum
بگذریم...

شما خودتون یه select دارین که نتیجه ش شده این:

step,student_Id,cours_Id,count(card_Id)

6 121 95 32
6 121 101 22
6 121 105 77
6 121 109 34
6 121 110 26
6 121 111 21
6 121 112 15
6 121 114 47
6 121 179 92

منظور من اینه که با یک select دیگه میشه به ریز رکوردها رسید، با این شرط که select بیرونی مقادیر خودش رو محدود به همین فهرست select داخلی کرده باشه. اما باید select داخلی فقط شامل یک فیلد باشه و اگه مجبور باشیم دو فیلد رو مشخص کنیم شاید مجبور بشیم دو تا select داخلی داشته باشیم

پس نیازی به داشتن این 4 ستون نیست و فقط ستونهایی که نیاز داریم کافیه
مثلا فرض کنیم با مشخص کردن دو فیلد student_Id و Course_Id میشه کارت ها رو پیدا کرد، select شما رو دوبار استفاده می کنیم اما هر بار فقط با یکی از فیلدهاش



select * from dbo.Card INNER JOIN dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id WHERE dbo.RelationStep.Step = 6
and Course_Id in
(

SELECT dbo.Card.Course_Id
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

)


and student_Id in
(

SELECT student_Id
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

(



این یکی دیگه باید جواب بده

محمد سلیم آبادی
یک شنبه 21 فروردین 1390, 22:52 عصر
اینو امتحان کنین ببین همونی هست که دنبالشی:

SELECT C.*, R.step, R.student_Id
FROM
(
SELECT C.id
FROM dbo.Card AS C
JOIN dbo.RelationStep AS R
ON C.id = card_id
GROUP BY c.id
HAVING COUNT(CASE WHEN R.step = 6 THEN 1 END) > 10
) AS D
JOIN
dbo.Card AS C
ON D.id = C.id
JOIN dbo.RelationStep AS R
ON C.id = R.card_id
AND R.step = 6;

sama552
دوشنبه 22 فروردین 1390, 09:13 صبح
بله حق با شماست، من select شما رو کپی کردم و همینجوری اسم فیلد آی دی کارت رو آوردم، ولی اون select داخلی درست نیست چون جلوی select نمی تونیم اسم فیلدی رو بنویسیم که در قسمت group by مشخص نکردیم، مگر اینکه تابعی از فیلدها باشه مثل count یا sum
بگذریم...

شما خودتون یه select دارین که نتیجه ش شده این:

step,student_Id,cours_Id,count(card_Id)

6 121 95 32
6 121 101 22
6 121 105 77
6 121 109 34
6 121 110 26
6 121 111 21
6 121 112 15
6 121 114 47
6 121 179 92

منظور من اینه که با یک select دیگه میشه به ریز رکوردها رسید، با این شرط که select بیرونی مقادیر خودش رو محدود به همین فهرست select داخلی کرده باشه. اما باید select داخلی فقط شامل یک فیلد باشه و اگه مجبور باشیم دو فیلد رو مشخص کنیم شاید مجبور بشیم دو تا select داخلی داشته باشیم

پس نیازی به داشتن این 4 ستون نیست و فقط ستونهایی که نیاز داریم کافیه
مثلا فرض کنیم با مشخص کردن دو فیلد student_Id و Course_Id میشه کارت ها رو پیدا کرد، select شما رو دوبار استفاده می کنیم اما هر بار فقط با یکی از فیلدهاش



select * from dbo.Card INNER JOIN dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id WHERE dbo.RelationStep.Step = 6
and Course_Id in
(

SELECT dbo.Card.Course_Id
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

)


and student_Id in
(

SELECT student_Id
FROM dbo.Card INNER JOIN
dbo.RelationStep ON dbo.Card.Id = dbo.RelationStep.Card_Id
WHERE (dbo.RelationStep.Step = 6)
GROUP BY dbo.RelationStep.Step, dbo.Card.Course_Id, dbo.RelationStep.Student_Id
HAVING count(dbo.RelationStep.Card_Id) > 10

(



این یکی دیگه باید جواب بده


ممنون دوست عزیز این کوئری کاملا درسته