فرض کنید میخواهیم سطرهای جدول را 6 تا 6 تا سوا کنیم و به هر کدام یک عددی انتساب دهیم و هر قسم تولید شده را نیز 2 تا 2 تا سوا کنیم و بهش عدد انتساب دهیم.
به تصویر زیر توجه بفرمایید. ابتدا دادهها به دو دسته ششتایی تقسیم شدن(ستون ntl)، سپس هر کدام از این دستهها نیز به سه دسته دوتایی تقسیم شدن(ستون grp) هدف ما تولید دو ستون ntl و grp توسط query میباشد.
برای بدست آوردن مقادیر دو ستون مذکور روشهای متنوعی وجود دارد که برخی از آنها را در انیجا پوشش میدم.
قبل از هر چیزی ابتدا جدول را ایجاد و 12 سطر زیر را در آن انتشار دهید:
CREATE TABLE T (nbr INT NOT NULL);
INSERT T VALUES (1), (2), (3), (4), (5), (6),
(7), (8), (9), (10), (11), (12);
روش اول:
این روش، تعمیم پذیری و پویایی ندارد و برای هر سناریویی مناسب نخواهد بود. ولی از آنجایی که دیدم کوئری زیر میتواند یک نمونه از کاربرد Ntile باشه آن را مطرح کردم.
SELECT nbr, ntl, NTILE(3) OVER(PARTITION BY ntl ORDER BY nbr) AS grp
FROM (
SELECT nbr, NTILE(2) OVER(ORDER BY nbr) ntl
FROM T
) AS D;
تابع ntile داخلی سطرهای جدول را به دو قسم تقسیم میکند و برای قسم اول عدد 1 و برای قسم دوم عدد 2 را در نظر میگیرد.
تابع ntile بیرونی بر اساس دو عدد 1و 2 گروه بندی انجام داده و هر گروه را به 3 قسمت تقسیم میکند. قسمت اول 1، دوم 2 و سوم 3 خواهد بود.
لازم به ذکر است که باید خارج قسمت تقسیم تعدادسطرها بر عدد ntile یک عدد صحیح باشد تا خروجی مناسب داشته باشیم. و همچنین بایستی بدانیم که تعداد سطرهای جدول چنتاست تا آن را به گونه ای تقسیم کنیم که خارج قسمت برابر شود با عدد مورد نظر ما یعنی 6.
روش دوم:
در این روش بر خلاف روش قبل که همه چیز توسط تابع بدست میآمد باید خودمان دست به کار شویم و فرمولی را بدست آوریم که نتیجه مورد نظر را تولید کند.
برای حل این مساله ابتدا باید سطرهای جدول را 6 تا 6 تا سوا کنیم و عناصر هر دسته را شماره گذاری کنیم (از 1 تا 6 بر اساس ترتیب مقدار nbr) سپس با کمک سایر فرمولها دستهها را دوتا دوتا شماره گذاری میکنیم.
به تصویر زیر توجه بفرمایید:
در کادر نارنجی رنگ همانطور که اشاره شد ما سطرهای شمارگذاری شده ای داریم که در رنج 1 تا 6 هستند. و در کادر بنفش ستون مورد نظر ما قرار دارد. ستون بنفش با کمک ستون نارنجی بدست آمده است.
اگر تقسیم صحیح را div و باقیمانده صحیح را mod بگیریم فرولهای مورد نظر به این شرح خواهد بود:
طبق کوئری زیر ستون نارنجی(rnk1/rnk2) را به دو طریق میتوان ایجاد نمود و ستون بنفش(grp1/grp2) را نیز به دو طریق میتوان ایجاد نمود.
SELECT nbr, rnk1, rnk2,
(rnk1 + 1) / 2 AS grp2,
(rnk1 - 1) / 2 + 1 AS grp2
FROM
(
SELECT nbr,
ROW_NUMBER() OVER(PARTITION BY (nbr + 5) / 6 ORDER BY nbr) rnk1,
(nbr - 1) % 6 + 1 AS rnk2
FROM t
)d