PIVOT و UNPIVOT در SQL Server – قسمت دوم

PIVOT و UNPIVOT در SQL Server – قسمت دوم

نوشته شده توسط: مهدی شیشه بری
تاریخ انتشار: ۰۲ تیر ۱۳۹۵
آخرین بروزرسانی: ۱۴ مهر ۱۴۰۲
زمان مطالعه: 6 دقیقه
۵
(۳)

مقدمه PIVOT و UNPIVOT در SQL Server

در قسمت اول، با ساختار PIVOT و نحوه چگونگی استفاده از آن آشنا شدید. این بار به سراغ دیتابیس معروف Northwind می رویم و می خواهیم بدانیم در جدول Customers به ازای کشورهای uk، spain و usa چه تعداد کارمند داریم.

بنابراین در ابتدای کار می بایست تکلیف سه مورد زیر را مشخص کنیم:

  •  Aggregate Column: فیلد CustomerID
  •  PIVOT Column: فیلد Country

 لیستی که قرار است گزارش براساس آن تهیه شود که در مثال فرضی ما، مقادیر فیلد Country و شامل uk، spain و usa خواهد بود.
 
اسکریپت زیر را اجرا می کنیم:

SELECT * FROM
(SELECT Country,CustomerID FROM Customers)C
PIVOT
(COUNT(CustomerID) FOR Country
IN ([uk],[usa],[spain]))pTable

خوب، تا این جای کار همه چیز مطابق با خواسته ما بود اما آیا شما می دانید که در جدول Customers چه کشورهایی وجود دارد؟ اگر تعداد این کشورها زیاد باشد، آیا منطقی است که پس از شناسایی آن ها، لیست عریض و طویلی از عنوان کشورها را در جلو IN و در ساختار PIVOT، ردیف کنیم؟ آیا این امکان وجود ندارد که در آینده عناوین کشورهای جدیدی به جدول مان اضافه شوند؟ و …
پاسخ مناسب به حل مشکلات مطرح شده، استفاده از Dynamic T-SQL خواهد بود.

دوره کوئری نویسی نیک آموز
Dynamic T-SQL در واقع اسکریپت هایی است که به صورت Dynamic ایجاد می کنیم و در همان لحظه، آن ها را اجرا می کنیم. با استفاده از Dynamic T-SQL می توان شرایطی پویا و متنوع در زمان اجرای یک کوئری ایجاد کرد.
در اسکریپت زیر، متغیرهای مورد نیاز را تعریف و مقداردهی کرده و سپس با الحاق مناسبی با عبارات T-SQL، از طریق EXEC آن ها را اجرا می کنیم.
اکنون برای آن که بتوانیم یک Dynamic PIVOT داشته باشیم، دقیقا از این تکنیک استفاده می کنیم.
فرض می کنیم که می خواهیم بدانیم از هر کشور چه تعداد مشتری داریم. پس می بایست لیست کشورهای موجود را از جدول Customers استخراج کنیم.
 

DECLARE @country VARCHAR(MAX)
SET @country=''
SELECT @country=@country+Country+',' FROM Customers
GROUP BY Country
SET @country=LEFT(@country,LEN(@country)-1)

ابتدا متغیرcountry@ را تعریف می کنیم. در خط دوم اسکریپت بالا، ابتدا مقدار country@ را برابر Blank قرار می دهیم. توجه داشته باشید که اگر این کار را انجام ندهید با مشکل روبرو خواهید شد زیرا در ابتدا، مقدار country@ در هنگام تعریف، برابر با NULL خواهد بود و همواره جمع یک رشته با NULL برابر با NULL خواهد شد!
در عبارت SELECT، تمامی کشورها را از طریق جدول Customers در متغیرcountry@ به همراه جداکننده ویرگول، ذخیره می کنیم. توجه داشته باشید که استفاده از GROUP BY به منظور جلوگیری از درج تکراری عناوین کشورها است.
در خط آخر هم با توجه به این که در انتهای رشته ی country@ یک علامت ویرگول اضافی داریم، آن را حذف می کنیم.
لیست تمامی کشورها در متغیر country@ ذخیره شده و می بایست آن را به عنوان لیست مورد جستجو در جلو عبارت IN در ساختار PIVOT قرار دهیم.

EXEC('SELECT * FROM
(SELECT Country,customerID FROM Customers)C
PIVOT
(count(customerID) FOR Country
IN ('+@country+'))pTable')


 و اما حالا شما به عنوان تمرین، تلاش کنید کوئری ای بنویسید که خروجی زیر را نمایش دهد. این خروجی قرار است گزارشی باشد که عناوین همه customerIDها در Header قرار گرفته و متناسب با هر کدام، CompanyNameشان نمایش داده شود.

چه رتبه ای می‌دهید؟

میانگین ۵ / ۵. از مجموع ۳

اولین نفر باش

title sign
معرفی نویسنده
title sign
دیدگاه کاربران

    • عالی تشکر از نویسنده محترم.

    • با سلام
      قسمت UNPIVOT اگه ممکن لینک کنید من پیداش نکردم در سایت.

    • با سلام
      قسمت UNPIVOT اگه ممکن لینک کنید من پیداش نکردم در سایت.

    • بسیار عالی بود. مفهوم کاملا واضح بیان شده و شیوه نوشتاری هم عالی بود
      کمال تشکر را دارم

    • بسیار عالی بود. مفهوم کاملا واضح بیان شده و شیوه نوشتاری هم عالی بود
      کمال تشکر را دارم

    • واقعا عالی بود ممنون از شما

    • سلام خیلی خیلی ممنون بابت مقاله بسیار خوبتون
      ببخشید یک سوال داشتم من از این قابلیت در پروسیجر استفاده میکنم و وقتی میخوام پروسیجر رو به پروژه ام اضافه کنم(از linq استفاده میکنم) میگه نوعش رو نمی شناسه
      از temp table هم استفاده کردم که وقتی کوئری اجرا میشه بریزه توی temp table اما بازهم میگه نمیشناسه
      خیلی ممنون میشم اگه راهنمایی کنید
      تشکر

    • سلام خیلی خیلی ممنون بابت مقاله بسیار خوبتون
      ببخشید یک سوال داشتم من از این قابلیت در پروسیجر استفاده میکنم و وقتی میخوام پروسیجر رو به پروژه ام اضافه کنم(از linq استفاده میکنم) میگه نوعش رو نمی شناسه
      از temp table هم استفاده کردم که وقتی کوئری اجرا میشه بریزه توی temp table اما بازهم میگه نمیشناسه
      خیلی ممنون میشم اگه راهنمایی کنید
      تشکر

    •    با سلام و خسته نباشید خدمت شما

      جناب مهندس عزیز خیلی عالی توضیح دادید و من خیلی استفاده کردم اگر ممکن هست در مورد pivot که بحث خیلی مهمی هست بیشتر مقاله در سایت خوب نیک آموز بگذارید و حتی با مثالهای بیشتر ممنونم از شما.

      •   سلام
        خوشحالم که مقاله برای شما مفید بوده.
        سعی می کنم در آینده مقالات بیشتری در این زمینه ارائه کنم.

    •     سلام

      ممنون از مقاله خوبتون
  • 1
  • 2
هر روز یک ایمیل، هر روز یک درس
آموزش SQL Server بصورت رایگان
همین حالا فرم زیر را تکمیل کنید
دانلود رایگان جلسه اول
نیک آموز علاوه بر آموزش، پروژه‌های بزرگ در حوزه هوش تجاری و دیتا انجام می‌دهد.
close-link