۱۴۰۴/۰۶/۲۹ Nebular

نکته های SQL SERVER

در SQL Server:

  • COUNT(*)تعداد همه ردیف‌ها را می‌شمارد (چه ستون NULL باشد چه نباشد).
  • COUNT(ColumnName) → فقط ردیف‌هایی که مقدار آن ستون NULL نیست را می‌شمارد.

در باره DISTINCT

SELECT COUNT(DISTINCT City) FROM Customers;
  • DISTINCT City
    یعنی فقط شهرهای یکتا (غیرتکراری) رو انتخاب کن.
    مثلا اگر جدول 100 مشتری داشته باشه ولی فقط 5 شهر مختلف داخلش باشه، خروجی DISTINCT = اون 5 شهر.
  • COUNT(...)
    تعداد اون مقادیر یکتا رو می‌شماره.

2️⃣ کاربرد اصلی

این دستور زمانی استفاده میشه که بخوایم بدونیم یک ستون چند مقدار منحصر به‌فرد داره.

  • تعداد شهرهای مختلف مشتری‌ها
  • تعداد جنس‌های مختلف محصول‌ها
  • تعداد کدهای یکتای سفارش

تابع Aggregate مثل AVG() نمی‌تواند مستقیماً در WHERE استفاده شود.

WHERE Salary > AVG(Salary) // wrong

در SQL Server برای دیدن لیست دیتابیس‌ها دو روش اصلی داریم

1.استفاده از DMV (Dynamic Management View):

SELECT * FROM sys.databases;

این کوئری اطلاعات کامل دیتابیس‌ها را می‌دهد (نام، حالت، مالک، تاریخ ایجاد و …).

2.استفاده از Stored Procedure سیستمی:

EXEC sp_databases;

این هم دیتابیس‌های موجود را لیست می‌کند (ساده‌تر و فقط نام‌ها + اندازه).


دستور برای تغییر مالکیت یک جدول

ALTER AUTHORIZATION 

مثال

ALTER AUTHORIZATION ON SCHEMA::Sales TO ManagerUser;

Computed Column چیست؟

  • ستونی است که مقدارش از سایر ستون‌ها محاسبه می‌شود.
    مثال ساده:
CREATE TABLE Employees
(
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    FullName AS (FirstName + ' ' + LastName)  -- Computed Column
)
  • FullName به‌صورت خودکار از دو ستون دیگر محاسبه می‌شود.

2️⃣ چرا SCHEMABINDING مهم است؟

  • اگر بخواهی یک فانکشن را در Computed Column استفاده کنی، فانکشن نباید تغییر کند یا جدولی که به آن وابسته است تغییر کند.
  • SCHEMABINDING یعنی: فانکشن به جداول و ستون‌های مرجعش «قفل» می‌شود و تغییر ساختار جداول مرتبط بدون حذف فانکشن امکان‌پذیر نیست.
  • بدون SCHEMABINDING، SQL Server اجازه نمی‌دهد فانکشن روی ستون محاسبه شده استفاده شود، به خصوص اگر بخواهی ستون Persisted یا Index داشته باشد.

مثال Scalar Function برای Computed Column:

CREATE FUNCTION dbo.fn_FullName(@First NVARCHAR(50), @Last NVARCHAR(50))
RETURNS NVARCHAR(101)
WITH SCHEMABINDING
AS
BEGIN
    RETURN @First + ' ' + @Last
END;

CREATE TABLE Employees
(
    FirstName NVARCHAR(50),
    LastName NVARCHAR(50),
    FullName AS dbo.fn_FullName(FirstName, LastName) PERSISTED
)
  • نکته: PERSISTED یعنی مقدار ستون محاسبه شده در دیتابیس ذخیره می‌شود و Index می‌تواند روی آن ساخته شود. برای این حالت، فانکشن باید SCHEMABINDING داشته باشد.

✅ Data Warehouse چیست؟

Data Warehouse (DW) یک سیستم متمرکز برای ذخیره و مدیریت داده‌ها به‌صورت تحلیلی است.

هدف اصلی: تجمیع داده‌ها از منابع مختلف برای تحلیل، گزارش‌گیری و تصمیم‌گیری استراتژیک، نه پردازش تراکنش‌های روزمره.


🔹 تفاوت با Database عملیاتی (OLTP)

ویژگیOLTP (Operational DB)Data Warehouse (DW)
هدفپردازش تراکنش‌ها (Insert, Update, Delete)تحلیل داده‌ها و گزارش‌گیری
ساختارنرمال شده (3NF یا بیشتر)معمولا Star Schema / Snowflake Schema
حجم دادهکم تا متوسطبزرگ و حجیم (Gigabyte تا Terabyte)
تعداد Queryخیلی زیاد ولی کوتاهکمتر ولی پیچیده و طولانی
به‌روزرسانیروزانه، لحظه‌ایمعمولا ETL از منابع مختلف

🔹 معماری Data Warehouse

  1. Source Systems
    • بانک‌های اطلاعاتی عملیاتی، فایل‌ها، APIها
  2. ETL (Extract, Transform, Load)
    • استخراج داده‌ها از منابع، تبدیل به فرمت مناسب، بارگذاری در DW
  3. Data Warehouse
    • جایی که داده‌ها به صورت تحلیلی و تاریخی ذخیره می‌شوند
  4. Data Marts / BI Tools
    • گزارش‌ها، داشبوردها، OLAP Cubeها برای کاربران کسب‌وکار

🔹 مثال استادانه (با SQL Server)

فرض کن سه جدول عملیاتی داریم:

  1. Orders (سفارش‌ها)
  2. Customers (مشتریان)
  3. Products (محصولات)

در OLTP: جداول به صورت 3NF هستند، تراکنش‌ها سریع و کوچک.

در Data Warehouse:

  • طراحی می‌کنیم Star Schema:

Fact Table (OrdersFact)

| OrderID | CustomerID | ProductID | Quantity | Amount | OrderDateKey |

Dimension Tables (CustomersDim, ProductsDim, DateDim)

  • تحلیل می‌کنیم:
    • مجموع فروش هر مشتری
    • فروش هر محصول در یک ماه
    • روند سالانه فروش

این طراحی Queryهای تحلیلی را سریع می‌کند و کاربران نیازی به دسترسی به جداول عملیاتی پیچیده ندارند.


🔹 نکات کلیدی استادانه

  1. DW معمولا Read-Optimized است
    • یعنی بیشتر Query می‌زنیم و کمتر Update/Insert داریم
  2. تاریخی و تحلیلی است
    • می‌توان تحلیل روندها، مقایسه سالانه و پیش‌بینی انجام داد
  3. Schema متفاوت از OLTP
    • Star, Snowflake, Fact & Dimension Tables
  4. ETL حیاتی است
    • کیفیت داده‌ها، پاک‌سازی و تطبیق داده‌ها برای تحلیل درست بسیار مهم است

COALESCE چیست؟

COALESCE یک تابع توالی بررسی NULL است و اولین مقداری که غیر NULL باشد را برمی‌گرداند.

به زبان ساده: وقتی چند ستون یا مقدار داریم، می‌خواهیم اولین مقدار واقعی (Not NULL) را برگردانیم.


🔹 سینتکس

COALESCE (expression1, expression2, ..., expression_n)
  • SQL Server از چپ به راست مقادیر را بررسی می‌کند
  • اولین مقداری که NULL نباشد را برمی‌گرداند
  • اگر همه NULL باشند → نتیجه NULL می‌شود

🔹 مثال ساده

فرض کن جدول Employees داریم:

EmployeeIDFirstNameMiddleNameLastName
1AliNULLKhani
2SaraMaryamAhmadi
3NULLNULLRezaei

می‌خواهیم نام کامل را بسازیم و اگر FirstName NULL بود، از MiddleName استفاده کنیم:

SELECT EmployeeID,
       COALESCE(FirstName, MiddleName, 'No Name') AS DisplayName,
       LastName
FROM Employees;

نتیجه:

EmployeeIDDisplayNameLastName
1AliKhani
2SaraAhmadi
3No NameRezaei

✅ نکته: COALESCE اولین مقدار غیر NULL را برمی‌گرداند.


🔹 تفاوت با ISNULL

ویژگیISNULLCOALESCE
تعداد پارامترفقط ۲چند پارامتر
Standard SQLنهبله
رفتار نوع دادهنوع داده اولتابع استاندارد SQL Server نوع داده را بر اساس بالاترین precedence انتخاب می‌کند

🔹 مثال پیشرفته (تحلیل Data)

فرض کن جدول Sales داریم:

SaleIDOnlineSaleStoreSale
1100NULL
2NULL250
3NULLNULL

می‌خواهیم مقدار فروش واقعی را برگردانیم:

SELECT SaleID, COALESCE(OnlineSale, StoreSale, 0) AS TotalSale
FROM Sales;

نتیجه:

SaleIDTotalSale
1100
2250
30

🔹 جمع‌بندی استادانه

  • COALESCE = بررسی چند مقدار و برگرداندن اولین مقدار غیر NULL
  • برای جایگزینی NULL، ساخت نام کامل، انتخاب مقدار پیش‌فرض و تحلیل داده بسیار کاربردی است
  • استاندارد SQL است و در اکثر دیتابیس‌ها (SQL Server, Oracle, PostgreSQL) کار می‌کند

وقتی که ما داریم از group by استفاده میکنیم دقیقا چه چیز هایی رو میشه توی select اورد؟

وقتی از GROUP BY استفاده می‌کنی، داری به SQL می‌گی:

لطفاً داده‌ها رو بر اساس این ستون‌ها گروه‌بندی کن،
و برای هر گروه فقط یک سطر خروجی بساز.


🔸 قاعده طلایی (SQL Rule)

در SELECT فقط و فقط می‌تونی یکی از این دو نوع ستون رو بنویسی:

  1. ✅ ستون‌هایی که در عبارت GROUP BY آورده‌ای.
  2. ✅ ستون‌هایی که در داخل تابع تجمیعی (Aggregate Function) هستند.

🔹 مثال ساده

فرض کن جدول Orders اینه:

OrderIDCustomerIDAmount
1101200
2101500
3102300

✅ درست:

SELECT CustomerID, SUM(Amount)
FROM Orders
GROUP BY CustomerID;

اینجا:

  • CustomerID در GROUP BY هست ✅
  • Amount داخل تابع SUM() هست ✅
    بنابراین مجاز و درست.

❌ غلط:

SELECT CustomerID, OrderID, SUM(Amount)
FROM Orders
GROUP BY CustomerID;

اینجا:

  • OrderID نه در GROUP BY هست ❌
  • نه در تابعی مثل SUM یا MAX ❌
    SQL Server نمی‌فهمه برای هر CustomerID، کدوم OrderID رو انتخاب کنه → پس خطا میده.

🔹 Aggregate Functions که مجاز هستند:

تو SELECT در کنار GROUP BY می‌تونی از توابع تجمیعی مثل زیر استفاده کنی:

تابعتوضیح
SUM(column)مجموع
COUNT(column)تعداد ردیف‌ها
AVG(column)میانگین
MIN(column)کمترین مقدار
MAX(column)بیشترین مقدار

🔹 مثال ترکیبی درست:

SELECT 
  CustomerID,
  COUNT(OrderID) AS OrdersCount,
  SUM(Amount) AS TotalSales,
  MAX(Amount) AS BiggestOrder
FROM Orders
GROUP BY CustomerID;

✅ همه چیز مطابق قاعده است:

  • ستون CustomerID در GROUP BY آمده
  • بقیه ستون‌ها فقط در توابع تجمیعی استفاده شده‌اند

🔹 نکته پیشرفته:

اگر بخوای ستونی رو بیاری که نه در GROUP BY هست نه aggregate،
باید مشخص کنی کدوم ردیف از گروه منظورت هست (مثلاً با ROW_NUMBER() یا join).

مثلاً:

SELECT CustomerID, OrderID, Amount
FROM (
  SELECT *,
         ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY Amount DESC) AS rn
  FROM Orders
) AS O
WHERE rn = 1;

اینجا گفتی: “از هر Customer فقط سطری رو بیار که بالاترین مبلغ رو داره”.


🧠 جمع‌بندی:

نوع ستونمجازه در SELECT با GROUP BY؟مثال
در GROUP BY هستCustomerID
در تابع تجمیعی هستSUM(Amount)
در هیچ‌کدوم نیستOrderID
با window function انتخاب شده✅ (در SQL مدرن)ROW_NUMBER() OVER(…)
Accept Cookies
Accept Cookies
[your-shortcode]