View Full Version : چگونگی چینش خاص کوری بر اساس یک فیلد ؟؟؟ حرفه ای
  
NasimBamdad
شنبه 25 آبان 1392, 10: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, 12: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, 14: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, 15: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, 12:11 عصر
مرسیییییییی . ممنونم خیلی کمک کردی . 
میگم دوست عزیز این Else 100 آخرش یعنی چی ؟
cherchil_hra
دوشنبه 27 آبان 1392, 07:37 صبح
میگم دوست عزیز این Else 100 آخرش یعنی چی ؟
 
من کد شما رو کپی و paste کردم. اضافه است، حذفش کن
محمد سلیم آبادی
دوشنبه 27 آبان 1392, 12: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);
 
vBulletin® v4.2.5, Copyright ©2000-1404, Jelsoft Enterprises Ltd.