PDA

View Full Version : چگونگی چینش خاص کوری بر اساس یک فیلد ؟؟؟ حرفه ای



NasimBamdad
شنبه 25 آبان 1392, 09:53 صبح
سلام و خسته نباشید

یک کوری دارم که مثلا 100 تا رکورد داره . در این کوری یک فیلد داریم به اسم GroupID . می خواهیم کوری رو بر اساس این فیلد به صورت زیر Sort کنیم

می خوایم در کوری ما اولا :
اون رکورد هایی که GroupID شان برابر 1 هست لیست بشن ،
بعد اون هایی که 3 هستند ،
بعد اون هایی که 2 هستند
و در آخر اون هایی که برابر 6 هستند .

یعنی یک چیزی مثل این

Select * From tbl1 where GroupID = 1
THEN GroupID = 3
Then GroupID = 2
THENE GroupID = 6


Best Regars

cherchil_hra
شنبه 25 آبان 1392, 11:34 صبح
از این روش استفاده کن :
SELECT *,
CASE GroupID
WHEN 2 THEN 3
WHEN 3 THEN 2
ELSE GroupID
END OrderNO
FROM tbl1
ORDER BY OrderNO

اگر فقط بین 2 و 3 این اختلاف هست می تونی به این صورت بنویسی:
SELECT *,
CASE
WHEN GroupID = 3 THEN 1.5
ELSE GroupID
END OrderNO
FROM tbl1
ORDER BY
OrderNO

در sql 2012، جای دستور Case بالایی می تونی از iif استفاده کنی:
IIF (GroupID = 3,1.5,GroupID) as OrderNO

موفق باشید!

NasimBamdad
شنبه 25 آبان 1392, 13:36 عصر
این کوری من هست .


SELECT top 100 PERCENT dbo.patients.id AS PID, dbo.patients.fname, dbo.patients.lname, dbo.pezeshk.pezeshk_name, dbo.pezeshk.nezam_code,
dbo.pezeshk.khadamat_code, dbo.patients.serial, dbo.patients.sexID, dbo.patients.expr_date, dbo.patients.nos_date, dbo.patients.page_no,
dbo.patients.bimar_status, dbo.invoice.tarefe, dbo.invoice.sazman, dbo.invoice.feranshiz, dbo.khedmat_type.kh_code_khadamat, dbo.pezeshk.pezeshktypeID,
dbo.khedmat_type.kh_groupID,(Select Sum(tarefe) From invoice) AS Tarefe_Total,(Select Sum(sazman) From invoice) AS Sazman_Total,(Select Sum(feranshiz) From invoice) AS Feranshiz_Total
FROM dbo.patients INNER JOIN
dbo.pezeshk ON dbo.patients.pezeshkID = dbo.pezeshk.id INNER JOIN
dbo.invoice ON dbo.patients.id = dbo.invoice.patientid INNER JOIN
dbo.khedmat_type ON dbo.invoice.khID = dbo.khedmat_type.id
WHERE dbo.patients.bimeID = '2' AND dbo.patients.khadamatID = '1' AND dbo.patients.centerID = '2' AND patients.nos_date BETWEEN '1390/01/01' AND '1399/01/01'
ORDER BY (CASE dbo.khedmat_type.kh_groupID
WHEN '1' THEN 1
WHEN '3' THEN 2
WHEN '2' THEN 3
WHEN '4' THEN 4
WHEN '5' THEN 5
WHEN '6' THEN 6
Else 100 END) ASC


خیلی هم خوب داره جواب میده و رکورد هام به صورت مناسب لیست شدند .

حالا این کوری رو لازم دارم که بر اساس 2 فیلد مجدد فیلتر بشوند ، از تابع Row_Number برای این کار استفاده کردم و کوری من به صورت زیر تغییر کرده است


Select * From (SELECT top 100 PERCENT dbo.patients.id AS PID, dbo.patients.fname, dbo.patients.lname, dbo.pezeshk.pezeshk_name, dbo.pezeshk.nezam_code,
dbo.pezeshk.khadamat_code, dbo.patients.serial, dbo.patients.sexID, dbo.patients.expr_date, dbo.patients.nos_date, dbo.patients.page_no,
dbo.patients.bimar_status, dbo.invoice.tarefe, dbo.invoice.sazman, dbo.invoice.feranshiz, dbo.khedmat_type.kh_code_khadamat, dbo.pezeshk.pezeshktypeID,
dbo.khedmat_type.kh_groupID,(Select Sum(tarefe) From invoice) AS Tarefe_Total,(Select Sum(sazman) From invoice) AS Sazman_Total,(Select Sum(feranshiz) From invoice) AS Feranshiz_Total,row_number() over(partition by dbo.patients.serial, dbo.patients.nos_date_miladi order by dbo.patients.nos_date_miladi) as rnk
FROM dbo.patients INNER JOIN
dbo.pezeshk ON dbo.patients.pezeshkID = dbo.pezeshk.id INNER JOIN
dbo.invoice ON dbo.patients.id = dbo.invoice.patientid INNER JOIN
dbo.khedmat_type ON dbo.invoice.khID = dbo.khedmat_type.id
WHERE dbo.patients.bimeID = '2' AND dbo.patients.khadamatID = '1' AND dbo.patients.centerID = '2' AND patients.nos_date BETWEEN '1380/01/01' AND '1399/01/01'
Order by (CASE dbo.khedmat_type.kh_groupID
WHEN '1' THEN 1
WHEN '2' THEN 2
WHEN '3' THEN 3
WHEN '4' THEN 4
WHEN '5' THEN 5
WHEN '6' THEN 6
Else 100 END)
)d where rnk = 1 Order By nos_date


اما متاسفانه با اعمال تغییرات که برای حذف رکورد های تکراری بود ، این عملیات SORT کردن دیگه کار نمی کنه ! متاسفانه !

راه حل چیست !؟

cherchil_hra
شنبه 25 آبان 1392, 14:50 عصر
2 تا کار می تونی انجام بدی:
- یک فیلد (OrderNo) اضافه کنی، مثل همون چیزی که نوشتم. پس به جای نوشتن case در مقابل order، خروجی case رو تبدیلش کن به ستون.

- لازم نیست در select داخلی کار sort کردن رو انجام بدی، فیلد OrderNo رو در select بیرونیت استفاده کن.
Order By nos_date,OrderNo


اگر هم این مدلی نمی خوای، چون فیلد dbo.khedmat_type.kh_groupID در select بیرونیت دیده میشه، دستور :
ORDER BY (CASE dbo.khedmat_type.kh_groupID
WHEN '1' THEN 1
WHEN '3' THEN 2
WHEN '2' THEN 3
WHEN '4' THEN 4
WHEN '5' THEN 5
WHEN '6' THEN 6
Else 100 END) ASC

به select بیرونی بیار:
WHERE rnk = 1
ORDER BY
nos_date,CASE Ty.kh_groupID
WHEN '1' THEN 1
WHEN '2' THEN 2
WHEN '3' THEN 3
WHEN '4' THEN 4
WHEN '5' THEN 5
WHEN '6' THEN 6
ELSE 100
END

موفق باشید!

NasimBamdad
یک شنبه 26 آبان 1392, 11:11 صبح
مرسیییییییی . ممنونم خیلی کمک کردی .

میگم دوست عزیز این Else 100 آخرش یعنی چی ؟

cherchil_hra
دوشنبه 27 آبان 1392, 06:37 صبح
میگم دوست عزیز این Else 100 آخرش یعنی چی ؟

من کد شما رو کپی و paste کردم. اضافه است، حذفش کن

محمد سلیم آبادی
دوشنبه 27 آبان 1392, 11:10 صبح
IIF بسیار خوانا و کوتاه است.
اگر مایل بودی و در صورت داشتن SQL 2012 میتونید از اون استفاده کنید به این شکل:

ORDER BY nos_date,
IIF(Ty.kh_groupID IN ('1','2','3','4','5','6'), Ty.kh_groupID + 0, Ty.kh_groupID);