<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: SQL</title><link>https://academy.hsoub.com/programming/sql/page/3/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: SQL</description><language>ar</language><item><title>&#x62F;&#x648;&#x627;&#x644; &#x627;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r855/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_04/11.jpg.0339658380e2e111ccdcb91c462474eb.jpg" /></p>
<p>
	تستعرض هذه المقالة عددًا من أنواع الدوال، مثل الدوال التجميعية (Aggregate Functions) والدوال التحليلية (Analytic Functions) والدوال العددية.
</p>

<h2>
	الدوال التجميعية aggregate functions
</h2>

<p>
	تستعرض هذه الفقرة مجموعة من <a href="https://ar.wikipedia.org/wiki/%D9%88%D8%B8%D9%8A%D9%81%D8%A9_%D9%83%D9%84%D9%8A%D8%A9" rel="external nofollow">الدوال التجميعية</a> المُستخدمة في SQL، وهي دوال تأخذ مجموعة من القيم، وتعيد قيمة واحدة.
</p>

<h3>
	التجميع الشرطي Conditional aggregation
</h3>

<p>
	إليك جدول المدفوعات التالي:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
	<thead>
		<tr>
			<th>
				Customer
			</th>
			<th>
				Payment_type
			</th>
			<th>
				Amount
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Peter
			</td>
			<td>
				Credit
			</td>
			<td>
				100
			</td>
		</tr>
		<tr>
			<td>
				Peter
			</td>
			<td>
				Credit
			</td>
			<td>
				300
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				Credit
			</td>
			<td>
				1000
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				Debit
			</td>
			<td>
				500
			</td>
		</tr>
	</tbody>
</table>

<p>
	تحسب الشيفرة التالية المجموع الكلي لرصيد أو دين كل موظف في الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_7" style=""><span class="kwd">select</span><span class="pln"> customer</span><span class="pun">,</span><span class="pln">
     sum</span><span class="pun">(</span><span class="kwd">case</span><span class="pln"> </span><span class="kwd">when</span><span class="pln"> payment_type </span><span class="pun">=</span><span class="pln"> </span><span class="str">'credit'</span><span class="pln"> </span><span class="kwd">then</span><span class="pln"> amount </span><span class="kwd">else</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> credit</span><span class="pun">,</span><span class="pln">
     sum</span><span class="pun">(</span><span class="kwd">case</span><span class="pln"> </span><span class="kwd">when</span><span class="pln"> payment_type </span><span class="pun">=</span><span class="pln"> </span><span class="str">'debit'</span><span class="pln"> </span><span class="kwd">then</span><span class="pln"> amount </span><span class="kwd">else</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> debit
</span><span class="kwd">from</span><span class="pln"> payments
</span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> customer</span></pre>

<p>
	سنحصل على النتيجة التالية:
</p>

<table>
	<thead>
		<tr>
			<th>
				Customer
			</th>
			<th>
				Credit
			</th>
			<th>
				Debit
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Peter
			</td>
			<td>
				400
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				1000
			</td>
			<td>
				500
			</td>
		</tr>
	</tbody>
</table>

<p>
	إليك الآن المثال التالي:
</p>

<pre class="ipsCode">select customer,
     sum(case when payment_type = 'credit' then 1 else 0 end) as credit_transaction_count,
     sum(case when payment_type = 'debit' then 1 else 0 end) as debit_transaction_count
from payments
group by customer
</pre>

<p>
	هذا هو الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				Customer
			</th>
			<th>
				credit_transaction_count
			</th>
			<th>
				debit_transaction_count
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Peter
			</td>
			<td>
				2
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
		</tr>
	</tbody>
</table>

<p>
	 
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h3>
	ضمّ القوائم List Concatenation
</h3>

<p>
	تجمّع عملية ضمّ القوائم (List Concatenation) عناصر عمود أو تعبيرًا عن طريق دمج القيم في سلسلة نصية واحدة لكل مجموعة. يمكن أيضًا تحديد سلسلة نصية لفصل القيم (إما سلسلة نصية فارغة أو فاصلة عند حذفها)، كما يمكن تحديد ترتيب القيم المُعادة. ورغم أنّها ليست جزءًا من معيار SQL القياسي، إلا أنّ كلّ أنظمة قواعد البيانات العلائقية تدعمها.
</p>

<ul>
	<li>
		<strong>MySQL</strong>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_10" style=""><span class="pln">SELECT </span><span class="typ">ColumnA</span><span class="pln">
   </span><span class="pun">,</span><span class="pln"> GROUP_CONCAT</span><span class="pun">(</span><span class="typ">ColumnB</span><span class="pln"> ORDER BY </span><span class="typ">ColumnB</span><span class="pln"> SEPARATOR </span><span class="str">','</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pln">
 GROUP BY </span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<ul>
	<li>
		<strong>Oracle</strong> و <strong>DB2</strong>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_12" style=""><span class="pln">SELECT </span><span class="typ">ColumnA</span><span class="pln">
   </span><span class="pun">,</span><span class="pln"> LISTAGG</span><span class="pun">(</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> </span><span class="str">','</span><span class="pun">)</span><span class="pln"> WITHIN GROUP </span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">ColumnB</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pln">
 GROUP BY </span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<ul>
	<li>
		<strong>PostgreSQL</strong>
	</li>
</ul>

<pre class="ipsCode">SELECT ColumnA
   , STRING_AGG(ColumnB, ',' ORDER BY ColumnB) AS ColumnBs
 FROM TableName
 GROUP BY ColumnA
 ORDER BY ColumnA;
</pre>

<ul>
	<li>
		<strong>SQL Server قبل 2016</strong>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_14" style=""><span class="pln"> WITH CTE_TableName AS </span><span class="pun">(</span><span class="pln">
   SELECT </span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnB</span><span class="pln">
       FROM </span><span class="typ">TableName</span><span class="pun">)</span><span class="pln">
SELECT t0</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln">
 </span><span class="pun">,</span><span class="pln">   STUFF</span><span class="pun">((</span><span class="pln">
     SELECT </span><span class="str">','</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> t1</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pln">
     FROM CTE_TableName t1
     WHERE t1</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> t0</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln">
     ORDER BY t1</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pln">
         FOR XML PATH</span><span class="pun">(</span><span class="str">''</span><span class="pun">)),</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">''</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
   FROM CTE_TableName t0
 GROUP BY t0</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<ul>
	<li>
		<strong>SQL Server 2017 و SQL Azure</strong>
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_16" style=""><span class="pln">SELECT </span><span class="typ">ColumnA</span><span class="pln">
 </span><span class="pun">,</span><span class="pln">   STRING_AGG</span><span class="pun">(</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> </span><span class="str">','</span><span class="pun">)</span><span class="pln"> WITHIN GROUP </span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">ColumnB</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pln">
 GROUP BY </span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<ul>
	<li>
		<strong>SQLite</strong> بدون ترتيب:
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_18" style=""><span class="pln">SELECT </span><span class="typ">ColumnA</span><span class="pln">
   </span><span class="pun">,</span><span class="pln"> GROUP_CONCAT</span><span class="pun">(</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> </span><span class="str">','</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pln">
 GROUP BY </span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<p>
	يتطلب الترتيب استخدام استعلامً فرعي (subquery)، أو تعبيرًا جدوليًا CTE، وهو مجموعة ننائج مؤقتة يمكنك الرجوع إليها داخل عبارات SELECT أو INSERT أو UPDATE أو DELETE الأخرى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_20" style=""><span class="pln"> WITH CTE_TableName AS </span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnB</span><span class="pln">
       FROM </span><span class="typ">TableName</span><span class="pln">
       ORDER BY </span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnB</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="typ">ColumnA</span><span class="pln">
       </span><span class="pun">,</span><span class="pln"> GROUP_CONCAT</span><span class="pun">(</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> </span><span class="str">','</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ColumnBs</span><span class="pln">
    FROM CTE_TableName
 GROUP BY </span><span class="typ">ColumnA</span><span class="pln">
 ORDER BY </span><span class="typ">ColumnA</span><span class="pun">;</span></pre>

<h3>
	SUM
</h3>

<p>
	تجمع الدالة <code>‎Sum‎</code> قيم صفوف مجموعة النتائج. وفي حال حذف العبارة group by، فستُجمَع قيم كلّ الصفوف.
</p>

<p>
	المثال التالي لا يستخدم العبارة group by:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_22" style=""><span class="kwd">select</span><span class="pln"> sum</span><span class="pun">(</span><span class="pln">salary</span><span class="pun">)</span><span class="pln"> </span><span class="typ">TotalSalary</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> employees</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				TotalSalary
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2500
			</td>
		</tr>
	</tbody>
</table>

<p>
	إليك مثال يستخدم group by:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_24" style=""><span class="kwd">select</span><span class="pln"> </span><span class="typ">DepartmentId</span><span class="pun">,</span><span class="pln"> sum</span><span class="pun">(</span><span class="pln">salary</span><span class="pun">)</span><span class="pln"> </span><span class="typ">TotalSalary</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> employees
</span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">DepartmentId</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				DepartmentId
			</th>
			<th>
				TotalSalary
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				2000
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				500
			</td>
		</tr>
	</tbody>
</table>

<h3>
	المتوسط AVG
</h3>

<p>
	تعيد الدالة التجميعية ‎‎<code>AVG()</code>‎‎ متوسط قيم تعبير معيّن، والتي عادةً ما تكون قيمًا رقمية في عمود.
</p>

<p>
	لنفترض أنّ لدينا جدولًا يحتوي على تعداد سكان مدن العالم. مثلا، سجلّ مدينة نيويورك سيكون من هذا القبيل:
</p>

<table>
	<thead>
		<tr>
			<th>
				city_name
			</th>
			<th>
				population
			</th>
			<th>
				year
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				New York City
			</td>
			<td>
				8,550,405
			</td>
			<td>
				2015
			</td>
		</tr>
		<tr>
			<td>
				New York City
			</td>
			<td>
				...
			</td>
			<td>
				...
			</td>
		</tr>
		<tr>
			<td>
				New York City
			</td>
			<td>
				8,000,906
			</td>
			<td>
				2005
			</td>
		</tr>
	</tbody>
</table>

<p>
	يحسب الاستعلام التالي متوسط عدد سكان مدينة نيويورك في الولايات المتحدة الأمريكية في السنوات العشر الماضية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_26" style=""><span class="kwd">select</span><span class="pln"> city_name</span><span class="pun">,</span><span class="pln"> AVG</span><span class="pun">(</span><span class="pln">population</span><span class="pun">)</span><span class="pln"> avg_population
</span><span class="kwd">from</span><span class="pln"> city_population
</span><span class="kwd">where</span><span class="pln"> city_name </span><span class="pun">=</span><span class="pln"> </span><span class="str">'NEW YORK CITY'</span><span class="pun">;</span></pre>

<p>
	لاحظ كيف لم توضع السنة في الاستعلام، وذلك لأنّنا نريد حساب متوسط عدد السكان بمرور الوقت.
</p>

<p>
	سنحصل على النتائج التالية:
</p>

<table>
	<thead>
		<tr>
			<th>
				city_name
			</th>
			<th>
				avg_population
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				New York City
			</td>
			<td>
				8,250,754
			</td>
		</tr>
	</tbody>
</table>

<p>
	<strong>تنبيه</strong>: تحوّل الدالة AVG القيم إلى أعداد، وهذا أمر ينبغي أن تأخذه بالحسبان دائمًا، خصوصا عندما تعمل بقيم التاريخ والوقت.
</p>

<h3>
	Count
</h3>

<p>
	يمكنك استخدام الدالة Count لحساب عدد الصفوف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_28" style=""><span class="pln">SELECT count</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">TotalRows</span><span class="pln">
FROM employees</span><span class="pun">;</span></pre>

<p>
	النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				TotalRows
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				4
			</td>
		</tr>
	</tbody>
</table>

<p>
	يعدّ المثال التالي الموظفين في كل قسم:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_30" style=""><span class="pln">SELECT </span><span class="typ">DepartmentId</span><span class="pun">,</span><span class="pln"> count</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">NumEmployees</span><span class="pln">
FROM employees
GROUP BY </span><span class="typ">DepartmentId</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				DepartmentId
			</th>
			<th>
				NumEmployees
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				3
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				1
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكنك العدّ بحسب الأعمدة أو التعابير مع عدم احتساب القيم المعدومة <code>‎NULL‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_32" style=""><span class="pln">SELECT count</span><span class="pun">(</span><span class="typ">ManagerId</span><span class="pun">)</span><span class="pln"> mgr
FROM EMPLOYEES</span><span class="pun">;</span></pre>

<p>
	النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				mgr
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				3
			</td>
		</tr>
	</tbody>
</table>

<p>
	(هناك قيمة واحدة فقط معدومة في العمود <code>managerID</code>)
</p>

<p>
	يمكنك أيضًا استخدام <code>DISTINCT</code> داخل دالة أخرى (مثل <code>COUNT</code>) لتجبنّب إعادة العناصر المكرّرة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_34" style=""><span class="pln"> SELECT COUNT</span><span class="pun">(</span><span class="typ">ContinentCode</span><span class="pun">)</span><span class="pln"> </span><span class="typ">AllCount</span><span class="pln">
  </span><span class="pun">,</span><span class="pln">         COUNT</span><span class="pun">(</span><span class="pln">DISTINCT </span><span class="typ">ContinentCode</span><span class="pun">)</span><span class="pln"> </span><span class="typ">SingleCount</span><span class="pln">
 FROM </span><span class="typ">Countries</span><span class="pun">;</span></pre>

<p>
	ستعيد الشيفرة أعلاه قيمًا مختلفة. إذ لن تحسب <code>SingleCount</code> إلا عدد القارّات الفريدة (أي غير المكررة)، وذلك على خلاف <code>AllCount</code> التي ستعيد التكرارات أيضًا.
</p>

<p>
	إذا طبّقنا الشيفرة أعلاه على جدول القارات التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				ContinentCode
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				OC
			</td>
		</tr>
		<tr>
			<td>
				EU
			</td>
		</tr>
		<tr>
			<td>
				AS
			</td>
		</tr>
		<tr>
			<td>
				NA
			</td>
		</tr>
		<tr>
			<td>
				NA
			</td>
		</tr>
		<tr>
			<td>
				AF
			</td>
		</tr>
		<tr>
			<td>
				AF
			</td>
		</tr>
	</tbody>
</table>

<p>
	فسنحصل على الخرج التالي:
</p>

<pre class="ipsCode">AllCount: 7 SingleCount: 5 
</pre>

<h3>
	القيمة الدنيا Min
</h3>

<p>
	تبحث الدالة <code>Min</code> عن أصغر قيمة في العمود:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_42" style=""><span class="kwd">select</span><span class="pln"> min</span><span class="pun">(</span><span class="pln">age</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> employee</span><span class="pun">;</span></pre>

<p>
	سيعيد المثال أعلاه أصغر قيمة في العمود <code>‎age‎</code> من جدول <code>‎employee‎</code>.
</p>

<h3>
	القيمة القصوى Max
</h3>

<p>
	تبحث الدالة <code>Max</code> عن القيمة القصوى في العمود:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_39" style=""><span class="kwd">select</span><span class="pln"> max</span><span class="pun">(</span><span class="pln">age</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> employee</span><span class="pun">;</span></pre>

<p>
	سيعيد المثال أعلاه أكبر قيمة في العمود <code>‎age‎</code> من جدول <code>‎employee‎</code>.
</p>

<h2>
	الدوال العددية والصفّية Scalar/Single Row Functions
</h2>

<p>
	توفّر SQL العديد من الدوال العددية (scalar functions) المُضمّنة. والتي تأخذ قيمة واحدة كمُدخل، وتعيد قيمة واحدة لكل صفّ في مجموعة النتائج.
</p>

<p>
	يمكنك استخدام الدوال العددية في أيّ موضع تكون التعابير جائزة فيه داخل ‏‏‏‏<a href="https://ar.wikipedia.org/wiki/%D8%AA%D9%8A-%D8%B3%D9%83%D9%8A%D9%88%D9%84" rel="external nofollow">عبارات T-SQL</a> .
</p>

<h3>
	التاريخ والوقت
</h3>

<p>
	في SQL، يُستخدم النوعان <code>date</code> و <code>time</code> لتخزين المعلومات المتعلقة بالوقت. يتضمّن هذان النوعان الوقت (time) والتاريخ (date) والتوقيت الصغير (smalldatetime) والتوقيت (datetime) والتوقيت 2 - مبني على 24 ساعة - (datetime2) والتوقيت الإزاحي - أي فارق التوقيت مع التوقيت العالمي الموحد UTC‏ - (datetimeoﬀset).
</p>

<p>
	لكل واحد من هذه الأنواع تنسيق خاص كما يوضّح الجدول التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				نوع البيانات
			</th>
			<th>
				التنسيق
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				time
			</td>
			<td>
				hh:mm:ss[.nnnnnnn]
			</td>
		</tr>
		<tr>
			<td>
				date
			</td>
			<td>
				YYYY-MM-DD
			</td>
		</tr>
		<tr>
			<td>
				smalldatetime
			</td>
			<td>
				YYYY-MM-DD hh:mm:ss
			</td>
		</tr>
		<tr>
			<td>
				datetime
			</td>
			<td>
				YYYY-MM-DD hh:mm:ss[.nnn]
			</td>
		</tr>
		<tr>
			<td>
				datetime2
			</td>
			<td>
				YYYY-MM-DD hh:mm:ss[.nnnnnnn]
			</td>
		</tr>
		<tr>
			<td>
				datetimeoﬀset
			</td>
			<td>
				YYYY-MM-DD hh:mm:ss[.nnnnnnn] [+/-]hh:mm
			</td>
		</tr>
	</tbody>
</table>

<p>
	تعيد الدالة <code>‎DATENAME‎</code> اسم أو جزء محدّد من قيمة التاريخ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_44" style=""><span class="pln">SELECT DATENAME </span><span class="pun">(</span><span class="pln">weekday</span><span class="pun">,</span><span class="str">'2017-01-14'</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">Datename</span></pre>

<p>
	الخرج الناتج عن الشيفرة أعلاه:
</p>

<table>
	<thead>
		<tr>
			<th>
				Datename
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Saturday
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكنك استخدام الدالة <code>‎GETDATE‎</code> لتحديد التاريخ والوقت الحاليين لجهاز الكمبيوتر الذي ينفّذ شيفرة SQL الحالية كما هو موضّح في المثال التالي (لا تشمل هذه الدالة اختلاف المنطقة الزمنية.)
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_46" style=""><span class="pln">SELECT GETDATE</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">Systemdate</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				Systemdate
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2017-01-14 11:11:47.7230728
			</td>
		</tr>
	</tbody>
</table>

<p>
	تعيد الدالة <code>‎DATEDIFF‎</code> الفرق بين تاريخين. ويحدد المعامل الأوّل الممرّر إلى هذه الدالة الجزء الذي تريد استخدامه من التاريخ لحساب الاختلاف. يمكن أن يساوي: year أو month أو week أو day أو hour أو minute أو second أو millisecond. يحدّد المعامل الثاني والثالث تاريخ البداية وتاريخ الانتهاء اللذين تريد حساب الفرق الزمني بينها على التوالي.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_48" style=""><span class="pln">SELECT </span><span class="typ">SalesOrderID</span><span class="pun">,</span><span class="pln"> DATEDIFF</span><span class="pun">(</span><span class="pln">day</span><span class="pun">,</span><span class="pln"> </span><span class="typ">OrderDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ShipDate</span><span class="pun">)</span><span class="pln">
AS </span><span class="str">'Processing time'</span><span class="pln">
FROM </span><span class="typ">Sales</span><span class="pun">.</span><span class="typ">SalesOrderHeader</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				SalesOrderID
			</th>
			<th>
				Processing time
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				43659
			</td>
			<td>
				7
			</td>
		</tr>
		<tr>
			<td>
				43660
			</td>
			<td>
				7
			</td>
		</tr>
		<tr>
			<td>
				43661
			</td>
			<td>
				7
			</td>
		</tr>
		<tr>
			<td>
				43662
			</td>
			<td>
				7
			</td>
		</tr>
	</tbody>
</table>

<p>
	تتيح لك الدالة <code>‎DATEADD‎</code> إضافة مجال زمني إلى جزء محدّد من التاريخ كما يوضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_50" style=""><span class="pln">SELECT DATEADD </span><span class="pun">(</span><span class="pln">day</span><span class="pun">,</span><span class="pln"> </span><span class="lit">20</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2017-01-14'</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">Added20MoreDays</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				Added20MoreDays
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2017-02-03 00:00:00.000
			</td>
		</tr>
	</tbody>
</table>

<h3>
	التعديلات على الحروف Character modiﬁcations
</h3>

<p>
	توفّر SQL بعض الدوال التي يمكنها معالجة الأحرفِ، مثلا، يمكن تحويل الأحرف إلى أحرف كبيرة أو صغيرة، أو تحويل الأرقام إلى أرقام منسّقة تنسيقًا خاصًّا.
</p>

<p>
	تحوّل الدالة <code>‎lower(char)‎</code> الأحرف المُمرّرة إليها إلى أحرف صغيرة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_56" style=""><span class="pln">SELECT customer_id</span><span class="pun">,</span><span class="pln"> lower</span><span class="pun">(</span><span class="pln">customer_last_name</span><span class="pun">)</span><span class="pln"> FROM customer</span><span class="pun">;</span></pre>

<p>
	يعيد الاستعلام أعلاه الاسم الأخير صغيرًا، أي يحوّل <code>SMITH</code> إلى <code>smith</code>.
</p>

<h3>
	دوال الإعدادات والتحويل
</h3>

<p>
	الدالة <code>‎@@SERVERNAME‎</code> هي إحدى أمثلة دوال الإعدادات في SQL. توفّر هذه الدالة اسم الخادم المحلي الذي ينفّذ تعليمات SQL.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_58" style=""><span class="pln">SELECT </span><span class="pun">@</span><span class="lit">@SERVERNAME</span><span class="pln"> AS </span><span class="str">'Server'</span></pre>

<p>
	الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				Server
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				SQL064
			</td>
		</tr>
	</tbody>
</table>

<p>
	في SQL، تحدث معظم عمليات تحويلات البيانات ضمنيًا، ودون أيّ تدخل من المستخدم. إن أردت تنفيذ عملية تحويل لا يمكن إجراؤها ضمنيًا، فيمكنك استخدام الدالتين <code>‎CAST‎</code> أو <code>‎CONVERT‎</code>.
</p>

<p>
	صياغة <code>‎CAST‎</code> أبسط من صياغة <code>‎CONVERT‎</code>، بيْد أنّ إمكانياتها محدودة. سنستخدم في المثال التالي كلا الدالتين <code>‎CAST‎</code> و <code>‎CONVERT‎</code> لتحويل نوع بيانات الوقت (datetime) إلى النوع <code>‎varchar‎</code>. تستخدم الدالة <code>‎CAST‎</code> دائمًا التنسيق الافتراضي. على سبيل المثال، تُمثّل التواريخ والأوقات بالتنسيق YYYY-MM-DD. بالمقابل، تستخدم الدالة <code>‎CONVERT‎</code> تنسيق التاريخ والوقت الذي تحدّده أنت. سنختار في المثال التالي التنسيق 3، والذي يمثّل التنسيق dd / mm / yy.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_60" style=""><span class="pln">USE </span><span class="typ">AdventureWorks2012</span><span class="pln">
GO
SELECT </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' '</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' was hired on '</span><span class="pln"> </span><span class="pun">+</span><span class="pln">
     CAST</span><span class="pun">(</span><span class="typ">HireDate</span><span class="pln"> AS varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">))</span><span class="pln"> AS </span><span class="str">'Cast'</span><span class="pun">,</span><span class="pln">
     </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' '</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' was hired on '</span><span class="pln"> </span><span class="pun">+</span><span class="pln">
     CONVERT</span><span class="pun">(</span><span class="pln">varchar</span><span class="pun">,</span><span class="pln"> </span><span class="typ">HireDate</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Convert'</span><span class="pln">
FROM </span><span class="typ">Person</span><span class="pun">.</span><span class="typ">Person</span><span class="pln"> AS p
JOIN </span><span class="typ">HumanResources</span><span class="pun">.</span><span class="typ">Employee</span><span class="pln"> AS e
ON p</span><span class="pun">.</span><span class="typ">BusinessEntityID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">BusinessEntityID</span><span class="pln">
GO</span></pre>

<p>
	ستحصل على الخرج التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				Cast
			</th>
			<th>
				Convert
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				David Hamiltion was hired on 2003-02-04
			</td>
			<td>
				David Hamiltion was hired on 04/02/03
			</td>
		</tr>
	</tbody>
</table>

<p>
	هناك مثال آخر على دوال التحويل، وهي الدالة <code>‎PARSE‎</code>. تحوّل هذه الدالة سلسلة نصية إلى نوع بيانات آخر.
</p>

<p>
	في صياغة الدالة، عليك تحديد السلسلة النصية التي ترغب في تحويلها متبوعة بالكلمة المفتاحية <code>‎AS‎</code>، ثمّ تكتب نوع البيانات المطلوب. اختياريًا، يمكنك أيضًا تحديد الإعداد الثقافي، والذي يحدّد تنسيق السلسلة النصية. في حال لم تحدّده، فستُستخدم لغة الجلسة.
</p>

<p>
	إذا تعذّر تحويل السلسلة النصية إلى تنسيق عددي أو تاريخ أو وقت ، فسيُطرَح خطأ. وسيتعيّن عليك حينئِذ استخدام <code>‎CAST‎</code> أو <code>‎CONVERT‎</code> لإجراء عملية التحويل.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_62" style=""><span class="pln">SELECT PARSE</span><span class="pun">(</span><span class="str">'Monday, 13 August 2012'</span><span class="pln"> AS datetime2 USING </span><span class="str">'en-US'</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Date in English'</span></pre>

<p>
	الخرج التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				Date in English
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2012-08-13 00:00:00.0000000
			</td>
		</tr>
	</tbody>
</table>

<h3>
	الدوال المنطقية والرياضية
</h3>

<p>
	تقدّم SQL دالتين منطقيتين، وهما <code>CHOOSE</code> و <code>IIF</code>. تعيد الدالة <code>‎CHOOSE‎</code> عنصرًا من قائمة من القيم استنادًا إلى فهرسه في القائمة.
</p>

<p>
	ينبغي أن يكون المعامل الأول، الذي يمثل الفهرس، عددًا صحيحًا. المعاملات التالية تحدّد قيم القائمة.
</p>

<p>
	في المثال التالي، سنستخدم الدالة <code>‎CHOOSE‎</code> لإعادة المُدخَل الثاني في قائمة الإدارات.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_64" style=""><span class="pln">SELECT CHOOSE</span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Human Resources'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Sales'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Admin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Marketing'</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">Result</span><span class="pun">;</span></pre>

<p>
	النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				Result
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Sales
			</td>
		</tr>
	</tbody>
</table>

<p>
	تعيد الدالة <code>‎IIF‎</code> القيمة true إن تحقّق شرطها، خلاف ذلك، تُعيد القيمة false.
</p>

<p>
	في صياغة عبارة الشرط، يحدّد معامل التعبير الشرطي (boolean<em>expression) التعبير المنطقي. فيما يحدّد المعامل الثاني (true</em>value) القيمة التي يجب إعادتها إذا لم يتحقّق الشرط، ويحدّد المعامل الثالث (false_value) القيمة التي يجب أن تُعاد خلاف ذلك.
</p>

<p>
	يستخدم المثال التالي الدالة <code>IIF</code> لإعادة إحدى قيمتين. إذا كانت مبيعات الموظف السنوية تتجاوز 200000، فسيكون ذلك الموظف مؤهّلاً للحصول على مكافأة. خلاف ذلك لن يكون مؤهّلا للحصول على مكافأة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_66" style=""><span class="pln">SELECT </span><span class="typ">BusinessEntityID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SalesYTD</span><span class="pun">,</span><span class="pln">
     IIF</span><span class="pun">(</span><span class="typ">SalesYTD</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">200000</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Bonus'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'No Bonus'</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Bonus?'</span><span class="pln">
FROM </span><span class="typ">Sales</span><span class="pun">.</span><span class="typ">SalesPerson</span><span class="pln">
GO</span></pre>

<p>
	هذا هو الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				BusinessEntityID
			</th>
			<th>
				SalesYTD
			</th>
			<th>
				Bonus?
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				274
			</td>
			<td>
				559697.5639
			</td>
			<td>
				Bonus
			</td>
		</tr>
		<tr>
			<td>
				275
			</td>
			<td>
				3763178.1787
			</td>
			<td>
				Bonus
			</td>
		</tr>
		<tr>
			<td>
				285
			</td>
			<td>
				172524.4512
			</td>
			<td>
				No Bonus
			</td>
		</tr>
	</tbody>
</table>

<p>
	تتضمّن SQL العديد من الدوال الرياضية التي يمكنك استخدامها لإجراء عمليات حسابية على المُدخلات ثمّ إعادة نتائج عددية.
</p>

<p>
	أحد أمثلة ذلك هي الدالة <code>‎SIGN‎</code>، والتي تُعيد قيمة تمثّل إشارة التعبير. إذ تشير القيمة ‎‎-1 إلى تعبير سلبي، فيما تشير القيمة ‎‎+1 إلى تعبير موجب ، أمّا 0 فيشير إلى الصفر!
</p>

<p>
	في المثال التالي، القيمة المُدخلة هي عدد سالب، لذا تُعاد ‎‎النتيجة ‎‎-1.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_68" style=""><span class="pln">SELECT SIGN</span><span class="pun">(-</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">'Sign'</span></pre>

<p>
	الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				Sign
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				-1
			</td>
		</tr>
	</tbody>
</table>

<p>
	هناك دالة رياضية أخرى، وهي الدالة <code>‎POWER‎</code>. والتي تحسب أسّ تعبير مرفوع إلى قوة محددة.
</p>

<p>
	في صياغة الدالة، يحدّد المعامل الأول التعبير العددي، فيما يحدّد المعامل الثاني الأسّ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_70" style=""><span class="pln">SELECT POWER</span><span class="pun">(</span><span class="lit">50</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">Result</span></pre>

<p>
	النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				Result
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				125000
			</td>
		</tr>
	</tbody>
</table>

<h2>
	الدوال التحليلية
</h2>

<p>
	تُستخدم الدوال التحليلية لحساب قيمة معيّنة بناءً على مجموعة من القيم. على سبيل المثال، يمكنك استخدام الدوال التحليلية لحساب المجاميع الجارية (running totals)، أو النسب المئوية، أو النتيجة الأكبر داخل مجموعة.
</p>

<h3>
	LAG و LEAD
</h3>

<p>
	توفر الدالة <code>‎LAG‎</code> البيانات الخاصّة بالصفوف التي تسبق الصف الحالي في مجموعة النتائج. على سبيل المثال ، في عبارة <code>‎SELECT‎</code>، يمكنك موازنة قيم الصف الحالي مع قيم الصف السابق. يمكنك استخدام تعبير عددي لتحديد القيم التي يجب موازنتها.
</p>

<p>
	يمثّل معامل الإزاحة (offset) عدد الصفوف السابقة للصف الحالي التي ستُستخدم في المقارنة. في حال عدم تحديده، فستُستخدم القيمة الافتراضية 1.
</p>

<p>
	يحدّد المعامل الافتراضي default القيمة التي يجب إعادتها عندما يكون التعبير الموجود في الموضع offset معدومًا (<code>‎NULL‎</code>). إذا لم تحدّد قيمة لهذا المعامل، فستُستخدم القيمة الافتراضية <code>‎NULL‎</code>.
</p>

<p>
	توفّر الدالة <code>‎LEAD‎</code> بيانات عن الصفوف التي تعقُب الصفّ الحالي في مجموعة الصفوف. على سبيل المثال، في عبارة <code>‎SELECT‎</code>، يمكنك موازنة قيم الصف الحالي مع قيم الصف اللاحق. يمكن تحديد القيم التي يجب موازنتها باستخدام تعبير رقمي.
</p>

<p>
	يمثّل معامل الإزاحة (offset) عدد الصفوف اللاحقة للصف الحالي التي ستُستخدم في المقارنة. يحدد المعامل default القيمة التي ينبغي أن تُعاد عندما يكون التعبير الموجود عند موضع الإزاحة معدومًا (<code>‎NULL‎</code>). إذا لم تحدد هذين المعاملين، فستُستخدم القيمتان الافتراضيتان لهذين المعاملين، واللتان تساويان 1 و <code>‎NULL‎</code> على التوالي.
</p>

<p>
	يستخدم المثال التالي الدالتين <code>LEAD</code> و <code>LAG</code> لمقارنة قيم المبيعات الحالية لكل موظف مع قيم الموظفين المذكورين قبله وبعده، مع ترتيب السجلات بناءً على قيمة العمود <code>BusinessEntityID</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_72" style=""><span class="pln">SELECT </span><span class="typ">BusinessEntityID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SalesYTD</span><span class="pun">,</span><span class="pln">
LEAD</span><span class="pun">(</span><span class="typ">SalesYTD</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">BusinessEntityID</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">"Lead value"</span><span class="pun">,</span><span class="pln">
LAG</span><span class="pun">(</span><span class="typ">SalesYTD</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">BusinessEntityID</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">"Lag value"</span><span class="pln">
FROM </span><span class="typ">SalesPerson</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				BusinessEntityID
			</th>
			<th>
				SalesYTD
			</th>
			<th>
				Lead value
			</th>
			<th>
				Lag value
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				274
			</td>
			<td>
				559697.5639
			</td>
			<td>
				3763178.1787
			</td>
			<td>
				0.0000
			</td>
		</tr>
		<tr>
			<td>
				275
			</td>
			<td>
				3763178.1787
			</td>
			<td>
				4251368.5497
			</td>
			<td>
				559697.5639
			</td>
		</tr>
		<tr>
			<td>
				276
			</td>
			<td>
				4251368.5497
			</td>
			<td>
				3189418.3662
			</td>
			<td>
				3763178.1787
			</td>
		</tr>
		<tr>
			<td>
				277
			</td>
			<td>
				3189418.3662
			</td>
			<td>
				1453719.4653
			</td>
			<td>
				4251368.5497
			</td>
		</tr>
		<tr>
			<td>
				278
			</td>
			<td>
				1453719.4653
			</td>
			<td>
				2315185.6110
			</td>
			<td>
				3189418.3662
			</td>
		</tr>
		<tr>
			<td>
				279
			</td>
			<td>
				2315185.6110
			</td>
			<td>
				1352577.1325
			</td>
			<td>
				1453719.4653
			</td>
		</tr>
	</tbody>
</table>

<h3>
	PERCENTILE<em>DISC و PERCENTILE</em>CONT
</h3>

<p>
	تسرد الدالة <code>‎PERCENTILE_DISC‎</code> قيمة أوّل مُدخَل يكون التوزيع التراكمي (cumulative distribution) عنده أعلى من <a href="https://ar.wikipedia.org/wiki/%D9%85%D8%A6%D9%8A%D9%86_(%D8%A5%D8%AD%D8%B5%D8%A7%D8%A1)" rel="external nofollow">المئين</a> الذي قدّمته باستخدام المعامل <code>‎numeric_literal‎</code>.
</p>

<p>
	تُجمَّع القيم حسب مجموعة الصفوف (rowset) أو حسب التوزيع (partition) كما هو محدّد في عبارة <code>‎WITHIN GROUP‎</code>.
</p>

<p>
	تشبه <code>‎PERCENTILE_CONT‎</code> الدالة <code>‎PERCENTILE_DISC‎</code>، بيْد أنّها تُعيد متوسّط مجموع أول مُدخل يحقق الشرط مع المُدخل التالي.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_74" style=""><span class="pln">SELECT </span><span class="typ">BusinessEntityID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JobTitle</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SickLeaveHours</span><span class="pun">,</span><span class="pln">
    CUME_DIST</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pln"> ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pln"> ASC</span><span class="pun">)</span><span class="pln">
    AS </span><span class="str">"Cumulative Distribution"</span><span class="pun">,</span><span class="pln">
    PERCENTILE_DISC</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span><span class="pln"> WITHIN GROUP</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pun">)</span><span class="pln">
       OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">"Percentile Discreet"</span><span class="pln">
FROM </span><span class="typ">Employee</span><span class="pun">;</span></pre>

<p>
	لإيجاد القيمة التي تطابق أو تتجاوز المئين 0.5، عليك تمرير المئين كقيمة عددية حرفية (numeric literal) إلى دالة المئين الكسري <code>‎PERCENTILE_DISC‎</code>. ينتج عن تطبيق هذه الدالة على مجموعة النتائج قائمة مؤلفة من قيم الصف التي يكون التوزيع التراكمي عندها أعلى من المئين المحدّد.
</p>

<table>
	<thead>
		<tr>
			<th>
				BusinessEntityID
			</th>
			<th>
				JobTitle
			</th>
			<th>
				SickLeaveHours
			</th>
			<th>
				Cumulative Distribution
			</th>
			<th>
				Percentile Discreet
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				272
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				55
			</td>
			<td>
				0.25
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				268
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.75
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				269
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.75
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				267
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				57
			</td>
			<td>
				1
			</td>
			<td>
				56
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكنك أيضًا استخدام دالة المئين المتصل - Percentile Continuous‏ - <code>‎PERCENTILE_CONT‎</code>، والتي ينتج عن تطبيقها على مجموعة النتائج متوسط مجموع قيمة النتيجة مع أعلى قيمة موالية تحقق الشرط.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_76" style=""><span class="pln">SELECT </span><span class="typ">BusinessEntityID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JobTitle</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SickLeaveHours</span><span class="pun">,</span><span class="pln">
    CUME_DIST</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pln"> ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pln"> ASC</span><span class="pun">)</span><span class="pln">
    AS </span><span class="str">"Cumulative Distribution"</span><span class="pun">,</span><span class="pln">
    PERCENTILE_DISC</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span><span class="pln"> WITHIN GROUP</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pun">)</span><span class="pln"> 
       OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">"Percentile Discreet"</span><span class="pun">,</span><span class="pln">
    PERCENTILE_CONT</span><span class="pun">(</span><span class="lit">0.5</span><span class="pun">)</span><span class="pln"> WITHIN GROUP</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pun">)</span><span class="pln"> 
       OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pun">)</span><span class="pln"> AS </span><span class="str">"Percentile Continuous"</span><span class="pln">
FROM </span><span class="typ">Employee</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				BusinessEntityID
			</th>
			<th>
				JobTitle
			</th>
			<th>
				SickLeaveHours
			</th>
			<th>
				Cumulative Distribution
			</th>
			<th>
				Percentile Discreet
			</th>
			<th>
				Percentile Continuous
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				272
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				55
			</td>
			<td>
				0.25
			</td>
			<td>
				56
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				268
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.75
			</td>
			<td>
				56
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				269
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.75
			</td>
			<td>
				56
			</td>
			<td>
				56
			</td>
		</tr>
		<tr>
			<td>
				267
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				57
			</td>
			<td>
				1
			</td>
			<td>
				56
			</td>
			<td>
				56
			</td>
		</tr>
	</tbody>
</table>

<h3>
	FIRST_VALUE
</h3>

<p>
	يمكنك استخدام الدالة <code>‎FIRST_VALUE‎</code> لتحديد القيمة الأولى في مجموعة نتائج مرتّبة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_78" style=""><span class="pln">SELECT </span><span class="typ">StateProvinceID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TaxRate</span><span class="pun">,</span><span class="pln">
     FIRST_VALUE</span><span class="pun">(</span><span class="typ">StateProvinceID</span><span class="pun">)</span><span class="pln">
     OVER</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">TaxRate</span><span class="pln"> ASC</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">FirstValue</span><span class="pln">
FROM </span><span class="typ">SalesTaxRate</span><span class="pun">;</span></pre>

<p>
	في هذا المثال، تُستخدم الدالة <code>‎FIRST_VALUE‎</code> لإعادة قيمة الحقل <code>‎ID‎</code> الخاص بالولاية أو المقاطعة التي لها أدنى معدّل للضريبة. فيما تُستخدم العبارة <code>‎OVER‎</code> لترتيب معدّلات الضريبة للحصول على أدنى معدّل.
</p>

<p>
	إليك جدول الضرائب:
</p>

<table>
	<thead>
		<tr>
			<th>
				StateProvinceID
			</th>
			<th>
				Name
			</th>
			<th>
				TaxRate
			</th>
			<th>
				FirstValue
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				74
			</td>
			<td>
				Utah State Sales Tax
			</td>
			<td>
				5.00
			</td>
			<td>
				74
			</td>
		</tr>
		<tr>
			<td>
				36
			</td>
			<td>
				Minnesota State Sales Tax
			</td>
			<td>
				6.75
			</td>
			<td>
				74
			</td>
		</tr>
		<tr>
			<td>
				30
			</td>
			<td>
				Massachusetts State Sales Tax
			</td>
			<td>
				7.00
			</td>
			<td>
				74
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				Canadian GST
			</td>
			<td>
				7.00
			</td>
			<td>
				74
			</td>
		</tr>
		<tr>
			<td>
				57
			</td>
			<td>
				Canadian GST
			</td>
			<td>
				7.00
			</td>
			<td>
				74
			</td>
		</tr>
		<tr>
			<td>
				63
			</td>
			<td>
				Canadian GST
			</td>
			<td>
				7.00
			</td>
			<td>
				74
			</td>
		</tr>
	</tbody>
</table>

<h3>
	LAST_VALUE
</h3>

<p>
	تعيد الدالة <code>‎LAST_VALUE‎</code> القيمة الأخيرة في مجموعة نتائج مرتبة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_80" style=""><span class="pln">SELECT </span><span class="typ">TerritoryID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">StartDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">BusinessentityID</span><span class="pun">,</span><span class="pln">
    LAST_VALUE</span><span class="pun">(</span><span class="typ">BusinessentityID</span><span class="pun">)</span><span class="pln"> 
    OVER</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">TerritoryID</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">LastValue</span><span class="pln">
FROM </span><span class="typ">SalesTerritoryHistory</span><span class="pun">;</span></pre>

<p>
	يستخدم المثال أعلاه الدالة <code>‎LAST_VALUE‎</code> لإعادة القيمة الأخيرة لكل مجموعة من الصفوف في مجموعة القيم المُرتبة.
</p>

<table>
	<thead>
		<tr>
			<th>
				TerritoryID
			</th>
			<th>
				StartDate
			</th>
			<th>
				BusinessentityID
			</th>
			<th>
				LastValue
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				2005-07-01 00.00.00.000
			</td>
			<td>
				280
			</td>
			<td>
				283
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				2006-11-01 00.00.00.000
			</td>
			<td>
				284
			</td>
			<td>
				283
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				2005-07-01 00.00.00.000
			</td>
			<td>
				283
			</td>
			<td>
				283
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2007-01-01 00.00.00.000
			</td>
			<td>
				277
			</td>
			<td>
				275
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2005-07-01 00.00.00.000
			</td>
			<td>
				275
			</td>
			<td>
				275
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				2007-01-01 00.00.00.000
			</td>
			<td>
				275
			</td>
			<td>
				277
			</td>
		</tr>
	</tbody>
</table>

<h3>
	PERCENT<em>RANK و CUME</em>DIST
</h3>

<p>
	تحسب الدالة <code>‎PERCENT_RANK‎</code> ترتيب الصفّ بالنسبة لمجموعة الصفوف. تُحسب النسبة المئوية نسبةً إلى عدد الصفوف في المجموعة التي تقلّ قيمتها عن الصف الحالي.
</p>

<p>
	تُعطى للقيمة الأولى في مجموعة النتائج دائمًا النسبة المئوية 0. بالمقابل، فالنسبة المئوية للقيمة العليا - أو الأخيرة - في المجموعة تساوي دائمًا 1.
</p>

<p>
	تحسب الدالة <code>‎CUME_DIST‎</code> الموضع النسبي (relative position) لقيمة معيَّنة في مجموعة من القيم من خلال تحديد النسبة المئوية للقيم التي تصغُر أو تساوي تلك القيمة. تُسمّى هذه العملية التوزيع التراكمي (cumulative distribution).
</p>

<p>
	سنستخدم في هذا المثال عبارة <code>‎ORDER‎</code> لتقسيم - أو تصنيف - الصفوف التي أعَادتها العبارة <code>‎SELECT‎</code> بناءً على المسمّيات الوظيفية للموظّفين، مع ترتيب النتائج في كل مجموعة على أساس عدد ساعات الإجازات المرضية التي استخدمها الموظفون.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_82" style=""><span class="pln">SELECT </span><span class="typ">BusinessEntityID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JobTitle</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SickLeaveHours</span><span class="pun">,</span><span class="pln">
PERCENT_RANK</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pln"> ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pln"> DESC</span><span class="pun">)</span><span class="pln">
     AS </span><span class="str">"Percent Rank"</span><span class="pun">,</span><span class="pln">
CUME_DIST</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">JobTitle</span><span class="pln"> ORDER BY </span><span class="typ">SickLeaveHours</span><span class="pln"> DESC</span><span class="pun">)</span><span class="pln">
     AS </span><span class="str">"Cumulative Distribution"</span><span class="pln">
FROM </span><span class="typ">Employee</span><span class="pun">;</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				BusinessEntityID
			</th>
			<th>
				JobTitle
			</th>
			<th>
				SickLeaveHours
			</th>
			<th>
				Percent Rank
			</th>
			<th>
				Cumulative Distribution
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				267
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				57
			</td>
			<td>
				0
			</td>
			<td>
				0.25
			</td>
		</tr>
		<tr>
			<td>
				268
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.333333333333333
			</td>
			<td>
				0.75
			</td>
		</tr>
		<tr>
			<td>
				269
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				56
			</td>
			<td>
				0.333333333333333
			</td>
			<td>
				0.75
			</td>
		</tr>
		<tr>
			<td>
				272
			</td>
			<td>
				Application Specialist
			</td>
			<td>
				55
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
		</tr>
		<tr>
			<td>
				262
			</td>
			<td>
				Assitant to the Cheif Financial Officer
			</td>
			<td>
				48
			</td>
			<td>
				0
			</td>
			<td>
				1
			</td>
		</tr>
		<tr>
			<td>
				239
			</td>
			<td>
				Beneﬁts Specialist
			</td>
			<td>
				45
			</td>
			<td>
				0
			</td>
			<td>
				1
			</td>
		</tr>
		<tr>
			<td>
				252
			</td>
			<td>
				Buyer
			</td>
			<td>
				50
			</td>
			<td>
				0
			</td>
			<td>
				0.111111111111111
			</td>
		</tr>
		<tr>
			<td>
				251
			</td>
			<td>
				Buyer
			</td>
			<td>
				49
			</td>
			<td>
				0.125
			</td>
			<td>
				0.333333333333333
			</td>
		</tr>
		<tr>
			<td>
				256
			</td>
			<td>
				Buyer
			</td>
			<td>
				49
			</td>
			<td>
				0.125
			</td>
			<td>
				0.333333333333333
			</td>
		</tr>
		<tr>
			<td>
				253
			</td>
			<td>
				Buyer
			</td>
			<td>
				48
			</td>
			<td>
				0.375
			</td>
			<td>
				0.555555555555555
			</td>
		</tr>
		<tr>
			<td>
				254
			</td>
			<td>
				Buyer
			</td>
			<td>
				48
			</td>
			<td>
				0.375
			</td>
			<td>
				0.555555555555555
			</td>
		</tr>
	</tbody>
</table>

<p>
	ترتّب الدالة <code>‎PERCENT_RANK‎</code> المُدخلات في كل مجموعة. فمقابل كل مُدخل، تحسب النسبة المئوية للمدخلات الأخرى في المجموعة التي لها قيم أصغر من المُدخل الممرّر.
</p>

<p>
	الدالة <code>‎CUME_DIST‎</code> مشابهة للدالة السايقة، بيْد أنّها تُعيد النسبة المئوية للقيم التي تصغُر القيمة الحالية أو تساويها.
</p>

<h2>
	دوال النافذة Window Functions
</h2>

<h3>
	التحقق من وجود قيم مكررة في عمود
</h3>

<p>
	لنفترض أن لدينا جدول البيانات التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				id
			</th>
			<th>
				example
			</th>
			<th>
				unique_tag
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				example
			</td>
			<td>
				unique_tag
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				foo
			</td>
			<td>
				simple
			</td>
		</tr>
		<tr>
			<td>
				42
			</td>
			<td>
				bar
			</td>
			<td>
				simple
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				baz
			</td>
			<td>
				hello
			</td>
		</tr>
		<tr>
			<td>
				51
			</td>
			<td>
				quux
			</td>
			<td>
				world
			</td>
		</tr>
	</tbody>
</table>

<p>
	يعيد المثال التالي كل هذه الصفوف مع راية تحدّد ما إذا كان الوسم <code>tag</code> مُستخدمًا من قبل صفّ آخر.
</p>

<pre class="ipsCode prettyprint lang-ruby prettyprinted" id="ips_uid_5929_85" style=""><span class="pln">SELECT id</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> tag</span><span class="pun">,</span><span class="pln"> COUNT</span><span class="pun">(*)</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">PARTITION BY tag</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AS flag FROM items</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				id
			</th>
			<th>
				name
			</th>
			<th>
				tag
			</th>
			<th>
				flag
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				example
			</td>
			<td>
				unique_tag
			</td>
			<td>
				false
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				foo
			</td>
			<td>
				simple
			</td>
			<td>
				true
			</td>
		</tr>
		<tr>
			<td>
				42
			</td>
			<td>
				bar
			</td>
			<td>
				simple
			</td>
			<td>
				true
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				baz
			</td>
			<td>
				hello
			</td>
			<td>
				false
			</td>
		</tr>
		<tr>
			<td>
				51
			</td>
			<td>
				quux
			</td>
			<td>
				world
			</td>
			<td>
				false
			</td>
		</tr>
	</tbody>
</table>

<p>
	في حالة لم تكن قاعدة بياناتك تدعم <code>OVER</code> و <code>PARTITION</code>، فيمكنك استخدام الشيفرة التالية للحصول على النتيجة نفسها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_87" style=""><span class="pln">SELECT id</span><span class="pun">,</span><span class="pln"> name</span><span class="pun">,</span><span class="pln"> tag</span><span class="pun">,</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT COUNT</span><span class="pun">(</span><span class="pln">tag</span><span class="pun">)</span><span class="pln"> FROM items B WHERE tag </span><span class="pun">=</span><span class="pln"> A</span><span class="pun">.</span><span class="pln">tag</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AS flag FROM items A</span></pre>

<h3>
	إيجاد السجلات الخارجة عن التسلسل باستخدام الدالة LAG
</h3>

<p>
	إليك الجدول التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				ID
			</th>
			<th>
				STATUS
			</th>
			<th>
				STATUS_TIME
			</th>
			<th>
				STATUS_BY
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				ONE
			</td>
			<td>
				2016-09-28-19.47.52.501398
			</td>
			<td>
				USER_1
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				ONE
			</td>
			<td>
				2016-09-28-19.47.52.501511
			</td>
			<td>
				USER_2
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				THREE
			</td>
			<td>
				2016-09-28-19.47.52.501517
			</td>
			<td>
				USER_3
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				TWO
			</td>
			<td>
				2016-09-28-19.47.52.501521
			</td>
			<td>
				USER_2
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				THREE
			</td>
			<td>
				2016-09-28-19.47.52.501524
			</td>
			<td>
				USER_4
			</td>
		</tr>
	</tbody>
</table>

<p>
	يجب أن تُرتب العناصر بحسب قيمة الحقل <code>‎STATUS‎</code>، بداية من القيمة "ONE" ثمّ "TWO" ثمّ "THREE".
</p>

<p>
	لاحظ أنّ التسلسل في الجدول غير مرتب، إذ أنّ هناك انتقالًا فوريًا من "ONE" إلى "THREE". عليك إيجاد طريقة للعثور على المستخدمين (<code>‎STATUS_BY‎</code>) الخارجين عن الترتيب.
</p>

<p>
	تساعد الدالة التحليلية <code>‎LAG()‎</code> في حل هذه المشكلة، إذ تعيد لكل صفّ، قيمة الصف السابق له:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_89" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="pun">(</span><span class="pln">
 SELECT
  t</span><span class="pun">.*,</span><span class="pln">
 LAG</span><span class="pun">(</span><span class="pln">status</span><span class="pun">)</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">PARTITION BY id ORDER BY status_time</span><span class="pun">)</span><span class="pln"> AS prev_status
 FROM test t
</span><span class="pun">)</span><span class="pln"> t1 WHERE status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'THREE'</span><span class="pln"> AND prev_status </span><span class="pun">!=</span><span class="pln"> </span><span class="str">'TWO'</span></pre>

<p>
	في حالة لم تكن قاعدة بياناتك تدعم <code>LAG</code>، يمكنك استخدام الشيفرة التالية للحصول على النتيجة نفسها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_91" style=""><span class="pln">SELECT A</span><span class="pun">.</span><span class="pln">id</span><span class="pun">,</span><span class="pln"> A</span><span class="pun">.</span><span class="pln">status</span><span class="pun">,</span><span class="pln"> B</span><span class="pun">.</span><span class="pln">status </span><span class="kwd">as</span><span class="pln"> prev_status</span><span class="pun">,</span><span class="pln"> A</span><span class="pun">.</span><span class="pln">status_time</span><span class="pun">,</span><span class="pln"> B</span><span class="pun">.</span><span class="pln">status_time </span><span class="kwd">as</span><span class="pln"> prev_status_time
FROM </span><span class="typ">Data</span><span class="pln"> A</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Data</span><span class="pln"> B
WHERE A</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> B</span><span class="pun">.</span><span class="pln">id
AND   B</span><span class="pun">.</span><span class="pln">status_time </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">SELECT MAX</span><span class="pun">(</span><span class="pln">status_time</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Data</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> status_time </span><span class="pun">&lt;</span><span class="pln"> A</span><span class="pun">.</span><span class="pln">status_time </span><span class="kwd">and</span><span class="pln"> id </span><span class="pun">=</span><span class="pln">
A</span><span class="pun">.</span><span class="pln">id</span><span class="pun">)</span><span class="pln">
AND   A</span><span class="pun">.</span><span class="pln">status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'THREE'</span><span class="pln"> AND NOT B</span><span class="pun">.</span><span class="pln">status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'TWO'</span></pre>

<h3>
	حساب المجموع الجاري running total
</h3>

<p>
	إليك جدول البيانات التالي:
</p>

<table>
	<thead>
		<tr>
			<th>
				date
			</th>
			<th>
				amount
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2016-03-12
			</td>
			<td>
				200
			</td>
		</tr>
		<tr>
			<td>
				2016-03-11
			</td>
			<td>
				-50
			</td>
		</tr>
		<tr>
			<td>
				2016-03-14
			</td>
			<td>
				100
			</td>
		</tr>
		<tr>
			<td>
				2016-03-15
			</td>
			<td>
				100
			</td>
		</tr>
		<tr>
			<td>
				2016-03-10
			</td>
			<td>
				-250
			</td>
		</tr>
	</tbody>
</table>

<p>
	بحسب المثال التالي المجموع الجاري للعمود <code>amount</code> في الجدول أعلاه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_93" style=""><span class="pln">SELECT date</span><span class="pun">,</span><span class="pln"> amount</span><span class="pun">,</span><span class="pln"> SUM</span><span class="pun">(</span><span class="pln">amount</span><span class="pun">)</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">ORDER BY date ASC</span><span class="pun">)</span><span class="pln"> AS running
FROM operations
ORDER BY date ASC</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
	<thead>
		<tr>
			<th>
				date
			</th>
			<th>
				amount
			</th>
			<th>
				running
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2016-03-10
			</td>
			<td>
				-250
			</td>
			<td>
				-250
			</td>
		</tr>
		<tr>
			<td>
				2016-03-11
			</td>
			<td>
				-50
			</td>
			<td>
				-300
			</td>
		</tr>
		<tr>
			<td>
				2016-03-12
			</td>
			<td>
				200
			</td>
			<td>
				-100
			</td>
		</tr>
		<tr>
			<td>
				2016-03-14
			</td>
			<td>
				100
			</td>
			<td>
				0
			</td>
		</tr>
		<tr>
			<td>
				2016-03-15
			</td>
			<td>
				100
			</td>
			<td>
				-100
			</td>
		</tr>
	</tbody>
</table>

<h3>
	إضافة إجمالي الصفوف المُختارة لكل صف
</h3>

<p>
	يضيف المثال التالي إجمالي الصفوف المختارة لكل صف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_96" style=""><span class="pln">SELECT your_columns</span><span class="pun">,</span><span class="pln"> COUNT</span><span class="pun">(*)</span><span class="pln"> OVER</span><span class="pun">()</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">Ttl_Rows</span><span class="pln"> FROM your_data_set</span></pre>

<table>
	<thead>
		<tr>
			<th>
				id
			</th>
			<th>
				name
			</th>
			<th>
				Ttl_Rows
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				example
			</td>
			<td>
				5
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				foo
			</td>
			<td>
				5
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				bar
			</td>
			<td>
				5
			</td>
		</tr>
		<tr>
			<td>
				4
			</td>
			<td>
				baz
			</td>
			<td>
				5
			</td>
		</tr>
		<tr>
			<td>
				5
			</td>
			<td>
				quux
			</td>
			<td>
				5
			</td>
		</tr>
	</tbody>
</table>

<p>
	بدلاً من استخدام استعلامين، الأول للحصول على المجموع، والثاني للحصول على الصفّ، يمكنك استخدام التجميع - aggregate - كدالة نافذة (window function) واستخدام مجموعة النتائج الكاملة كنافذة (window). يمكن أن يجنّبك هذا تعقيدات عمليات الضمّ الذاتي (self joins) الإضافية.
</p>

<h3>
	الحصول على أحدث N صفًّا في عدة مجموعات
</h3>

<p>
	إليك البيانات التالية:
</p>

<table>
	<thead>
		<tr>
			<th>
				User_ID
			</th>
			<th>
				Completion_Date
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				2016-07-20
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				2016-07-21
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2016-07-20
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2016-07-21
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2016-07-22
			</td>
		</tr>
	</tbody>
</table>

<p>
	إن استخدمت القيمة n = 1 في المثال التالي، ستحصل على أحدث صفّ لكل معرِّف <code>‎user_id‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5929_98" style=""><span class="pun">;</span><span class="kwd">with</span><span class="pln"> CTE </span><span class="kwd">as</span><span class="pln">
</span><span class="pun">(</span><span class="pln">SELECT </span><span class="pun">*,</span><span class="pln">
 ROW_NUMBER</span><span class="pun">()</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">User_ID</span><span class="pln">
 ORDER BY </span><span class="typ">Completion_Date</span><span class="pln"> DESC</span><span class="pun">)</span><span class="pln"> </span><span class="typ">Row_Num</span><span class="pln">
FROM </span><span class="typ">Data</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FORM CTE WHERE </span><span class="typ">Row_Num</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="pln"> n</span></pre>

<p>
	الخرج سيكون:
</p>

<table>
	<thead>
		<tr>
			<th>
				User_ID
			</th>
			<th>
				Completion_Date
			</th>
			<th>
				Row_Num
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				2016-07-21
			</td>
			<td>
				1
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				2016-07-22
			</td>
			<td>
				1
			</td>
		</tr>
	</tbody>
</table>

<p>
	ترجمة -وبتصرّف- للفصول من 42 إلى 45 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AF%D9%88%D8%A7%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-sql-r854/" rel="">دوال التعامل مع النصوص في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-sql-r853/" rel="">مواضيع متقدمة في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">855</guid><pubDate>Wed, 22 Apr 2020 18:07:00 +0000</pubDate></item><item><title>&#x645;&#x648;&#x627;&#x636;&#x64A;&#x639; &#x645;&#x62A;&#x642;&#x62F;&#x645;&#x629; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-sql-r853/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/10.jpg.1262309e2925912a3e93648562cdbf72.jpg" /></p>

<p>
	ستعرض هذه المقالة عددًا من المواضيع المتقدمة في SQL، مثل إدارة الصلاحيات، واستخدام ملفات XML في الاستعلامات، والمفاتيح الرئيسية والفهارس وأرقام الصفوف.
</p>

<h2>
	GRANT و REVOKE
</h2>

<p>
	تُستخدم العبارة <code>GRANT</code> لمنح الإذن لمستخدم ما بإجراء عملية على قاعدة البيانات، فيما تُستخدم العبارة <code>REVOKE</code> لسحب الإذن أو الصلاحية منه.
</p>

<p>
	يمنح المثال التالي الإذن للمستخدمَين <code>‎User1‎</code> و <code>‎User2‎</code> بإجراء العمليتين <code>‎SELECT‎</code> و <code>‎UPDATE‎</code> على الجدول <code>‎Employees‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_7" style="">
<span class="pln">GRANT SELECT</span><span class="pun">,</span><span class="pln"> UPDATE
ON </span><span class="typ">Employees</span><span class="pln">
TO </span><span class="typ">User1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">User2</span><span class="pun">;</span></pre>

<p>
	يسحب المثال التالي من المستخدمَين <code>‎User1‎</code> و <code>‎User2‎</code> صلاحية تنفيذ العمليتين <code>‎SELECT‎</code> و <code>‎UPDATE‎</code> على جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_9" style="">
<span class="pln">REVOKE SELECT</span><span class="pun">,</span><span class="pln"> UPDATE
ON </span><span class="typ">Employees</span><span class="pln">
FROM </span><span class="typ">User1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">User2</span><span class="pun">;</span></pre>

<h2>
	استخدام ملفات XML في SQL
</h2>

<p>
	يمكن تعريف جدول بيانات من ملف XML واستخدامه في استعلامات SQL مثل أيّ جدول عادي:
</p>

<pre class="ipsCode prettyprint prettyprinted" id="ips_uid_9317_11" style="">
<span class="pln">DECLARE </span><span class="lit">@xmlIN</span><span class="pln"> XML </span><span class="pun">=</span><span class="pln"> </span><span class="str">'&lt;TableData&gt;
&lt;aaa Main="First"&gt;
    &lt;row name="a" value="1" /&gt;
    &lt;row name="b" value="2" /&gt;
    &lt;row name="c" value="3" /&gt;
&lt;/aaa&gt;
&lt;aaa Main="Second"&gt;
    &lt;row name="a" value="3" /&gt;
    &lt;row name="b" value="4" /&gt;
    &lt;row name="c" value="5" /&gt;
&lt;/aaa&gt;
&lt;aaa Main="Third"&gt;
    &lt;row name="a" value="10" /&gt;
    &lt;row name="b" value="20" /&gt;
    &lt;row name="c" value="30" /&gt;
&lt;/aaa&gt;
&lt;/TableData&gt;'</span><span class="pln">
SELECT t</span><span class="pun">.</span><span class="pln">col</span><span class="pun">.</span><span class="pln">value</span><span class="pun">(</span><span class="str">'../@Main'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'varchar(10)'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Header</span><span class="pun">],</span><span class="pln">
t</span><span class="pun">.</span><span class="pln">col</span><span class="pun">.</span><span class="pln">value</span><span class="pun">(</span><span class="str">'@name'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'VARCHAR(25)'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="pln">name</span><span class="pun">],</span><span class="pln"> 
t</span><span class="pun">.</span><span class="pln">col</span><span class="pun">.</span><span class="pln">value</span><span class="pun">(</span><span class="str">'@value'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'VARCHAR(25)'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Value</span><span class="pun">]</span><span class="pln">
FROM </span><span class="lit">@xmlIn</span><span class="pun">.</span><span class="pln">nodes</span><span class="pun">(</span><span class="str">'//TableData/aaa/row'</span><span class="pun">)</span><span class="pln"> AS t </span><span class="pun">(</span><span class="pln">col</span><span class="pun">)</span></pre>

<p>
	الخرج الناتج:
</p>

<pre class="ipsCode" id="ips_uid_9317_14">
Header        name      Value
First          a          1
First          b          2
First          c          3
Second         a          3
Second         b          4
Second         c          5
Third          a          10
Third          b          20
Third          c          30
</pre>

<h2>
	المفاتيح الرئيسية Primary Keys
</h2>

<p>
	تُستخدَم المفاتيح الرئيسية لتمييز صفوف جدول من قاعدة بيانات. ولا يُسمح إلا بمفتاح رئيسي واحد في كلّ جدول.
</p>

<p>
	تنشئ الشيفرة التالية جدولًا للموظفين، مع جعل المُعرّف <code>Id</code> مفتاحه الرئيسي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_16" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    PRIMARY KEY </span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">...</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	يمكن أيضًا تركيب مفتاح من حقل واحد أو أكثر، هذا النوع من المفاتيح يُسمّى المفاتيح المُركّبة، وتُصاغ على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_18" style="">
<span class="pln">CREATE TABLE EMPLOYEE </span><span class="pun">(</span><span class="pln">
    e1_id INT</span><span class="pun">,</span><span class="pln">
    e2_id INT</span><span class="pun">,</span><span class="pln">
   PRIMARY KEY </span><span class="pun">(</span><span class="pln">e1_id</span><span class="pun">,</span><span class="pln"> e2_id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span></pre>

<h3>
	استخدام الزيادة التلقائية Auto Increment
</h3>

<p>
	تسمح العديد من قواعد البيانات بزيادة قيمة المفتاح الرئيسي تلقائيًا عند إضافة مفتاح جديد. يضمن هذا السلوك أن تكون كلّ المفاتيح مختلفة عن بعضها.
</p>

<p>
	إليك الأمثلة التوضيحية التالية:
</p>

<ul>
<li>
		<a href="https://dev.mysql.com/doc/refman/5.7/en/create-table.html#create-table-types-attributes" rel="external nofollow">MySQL</a>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_20" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    PRIMARY KEY </span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<ul>
<li>
		<a href="https://www.postgresql.org/docs/current/static/datatype-numeric.html#DATATYPE-SERIAL" rel="external nofollow">PostgreSQL</a>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_22" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> SERIAL PRIMARY KEY
</span><span class="pun">);</span></pre>

<ul>
<li>
		<a href="https://msdn.microsoft.com/en-us/library/ms186775.aspx" rel="external nofollow">SQL Server</a>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_24" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> NOT NULL IDENTITY</span><span class="pun">,</span><span class="pln">
    PRIMARY KEY </span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<ul>
<li>
		<a href="http://www.sqlite.org/autoinc.html" rel="external nofollow">SQLite</a>
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_26" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INTEGER PRIMARY KEY 
</span><span class="pun">);</span></pre>

<h2>
	الفهارس Indexes
</h2>

<p>
	الفهارس هي بنيات تحتوي على مؤشّرات تشير إلى محتويات جدول مُرتّب ترتيبًا محدّدًا، تُستخدم الفهارس لتحسين أداء الاستعلامات. فهي تشبه فهرس الكتاب، حيث تُفهرَس الصفحات (صفوف الجدول) بأرقام مميّزة تسهّل الوصول إليها.
</p>

<p>
	توجد عدّة أنواع من الفهارس، ويمكنك إنشاؤها على أيّ جدول. يحسّن استخدَام فهارس الأعمدة في عبارات <code>WHERE</code> أو <code>JOIN</code> أو <code>ORDER BY</code> أداء الاستعلامات تحسينًا.
</p>

<h3>
	الفهارس المُرتّبة Sorted Index
</h3>

<p>
	إذا كانت الفهارس مُرتّبة بنفس الترتيب الذي ستُسترجع به، فلن تجري التعليمة <code>‎SELECT‎</code> أيّ ترتيب إضافي أثناء الاسترجاع.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_28" style="">
<span class="pln">CREATE INDEX ix_scoreboard_score ON scoreboard </span><span class="pun">(</span><span class="pln">score DESC</span><span class="pun">);</span></pre>

<p>
	عند تنفيذ الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_31" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM scoreboard ORDER BY score DESC</span><span class="pun">;</span></pre>

<p>
	لن يُجري نظام قاعدة البيانات أيّ ترتيب إضافي طالما أنّه سيبحث في الفهرس وفق ذلك الترتيب.
</p>

<h3>
	الفهرس الجزئي أو المُصفّى Partial or Filtered Index
</h3>

<p>
	تتيح SQL Server و SQLite إنشاء فهارس تحتوي جزءًا من الأعمدة، وكذلك جزءًا من الصفوف.
</p>

<p>
	لنعتبر كمّية متزايدة من الطلبات يساوي الحقل <code>‎order_state_id‎</code> الخاص بها القيمة 2 (والتي تمثّل الحالة "مكتملة")، وكمّية أخرى ثابتة من الطلبات يساوي الحقل <code>‎order_state_id</code> الخاص بها القيمة 1 (والتي تمثّل الحالة "غير مكتملة").
</p>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_33" style="">
<span class="pln">SELECT id</span><span class="pun">,</span><span class="pln"> comment
     FROM orders
  WHERE order_state_id </span><span class="pun">=</span><span class="pln">  </span><span class="lit">1</span><span class="pln">
     AND product_id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@some_value</span><span class="pun">;</span></pre>

<p>
	يتيح لك استخدام الفهرسة الجزئية تقييد الفهرس (limit the index)، بحيث لا تُضمَّن إلا الطلبات التي لم تكتمل بعدُ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_35" style="">
<span class="pln">CREATE INDEX </span><span class="typ">Started_Orders</span><span class="pln">
 ON orders</span><span class="pun">(</span><span class="pln">product_id</span><span class="pun">)</span><span class="pln">
 WHERE order_state_id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	سيؤدي هذا إلى تقليل كمّية المؤشّرات، ويوفّر مساحة التخزين، ويقلّل من تكلفة تحديث الفهارس.
</p>

<h3>
	إنشاء فهرس
</h3>

<p>
	تنشئ الشيفرة التالية فهرسًا للعمود <code>EmployeeId</code> في الجدول <code>Cars</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_37" style="">
<span class="pln">CREATE INDEX ix_cars_employee_id ON </span><span class="typ">Cars</span><span class="pln"> </span><span class="pun">(</span><span class="typ">EmployeeId</span><span class="pun">);</span></pre>

<p>
	يحسّن استخدام الفهرس سرعة الاستعلامات التي تحاول أن ترتّب أو تختار الصفوف وفقًا لقيم <code>EmployeeId</code>، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_39" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln"> WHERE </span><span class="typ">EmployeeId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span></pre>

<p>
	يمكن أن يحتوي الفهرس أكثر من عمود واحد كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_41" style="">
<span class="pln">CREATE INDEX ix_cars_e_c_o_ids ON </span><span class="typ">Cars</span><span class="pln"> </span><span class="pun">(</span><span class="typ">EmployeeId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">CarId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">OwnerId</span><span class="pun">);</span></pre>

<p>
	في هذه الحالة، سيكون الفهرس مفيدًا للاستعلامات التي تحاول أن ترتّب أو تختار السجلات وفقًا لجميع الأعمدة المُضمّنة في حال كانت مجموعة الشروط مُرتّبة بالطريقة نفسها. هذا يعني أنه عند استرداد البيانات، سيكون بمقدورك العثور على الصفوف المُراد إعادتها باستخدام الفهرس بدلًا من البحث في كامل الجدول.
</p>

<p>
	يستخدم المثال التالي الفهرس الثاني:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_43" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln"> WHERE </span><span class="typ">EmployeeId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="typ">Order</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">CarId</span><span class="pln"> DESC</span></pre>

<p>
	يفقد الفهرس هذه المزايا في حال كان الترتيب مختلفًا كما يبيّن المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_45" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln"> WHERE </span><span class="typ">OwnerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">17</span><span class="pln"> </span><span class="typ">Order</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">CarId</span><span class="pln"> DESC</span></pre>

<p>
	لم يعد الفهرس مفيدًا الآن، لأنّه يتوجّب على قاعدة البيانات أن تسترجع الفهرس بالكامل، وعبر جميع قيم <code>EmployeeId</code> و <code>CarID</code> بُغية إيجاد العناصر التي تحقق الشرط <code>‎OwnerId = 17‎</code>.
</p>

<p>
	رغم كل ما قلناه، إلا أنّه من الممكن أن يُستخدم الفهرس رغم كل شيء؛ فقد يخمّن محسّن الاستعلامات (query optimizer) أنّ استرداد الفهرس، والتصفية بحسب قيمة <code>‎OwnerId‎</code>، ثم استرداد الصفوف المطلوبة حصرًا، سيكون أسرع من استرداد الجدول بالكامل ، خاصةً إن كان الجدول كبيرًا.
</p>

<h3>
	محو فهرس أو تعطيله وإعادة إنشائه
</h3>

<p>
	تُستخدم التعليمة <code>‎DROP‎</code> لحذف الفهرس. في هذا المثال، تمحو <code>‎DROP‎</code> فهرسًا يُسمّى <code>ix_cars_employee_id</code> في الجدول <code>Cars</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_47" style="">
<span class="pln">DROP INDEX ix_cars_employee_id ON </span><span class="typ">Cars</span><span class="pun">;</span><span class="pln"> </span></pre>

<p>
	تحذف <code>‎DROP‎</code> الفهرس نهائيًا، وفي حال كان الفهرس مُجمّعًا (clustered)، فسيُزال التجميع، ولن يكون بالإمكان إعادة بنائه دون إعادة إنشاء الفهرس، وهي عمليّة يمكن أن تكون بطيئة ومكلفة من الناحية الحسابية.
</p>

<p>
	هناك حلّ آخر، وهو تعطيل (disable) الفهرس بدل حذفه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_49" style="">
<span class="pln">ALTER INDEX ix_cars_employee_id ON </span><span class="typ">Cars</span><span class="pln"> DISABLE</span><span class="pun">;</span></pre>

<p>
	يسمح هذا للجدول بالاحتفاظ ببنية الفهرس وبياناته الوصفية (metadata). إضافة إلى إحصائيات الفهرس، وهكذا سيسهُل تقييم التغيير الحاصل. وإذا لزم الأمر، سيكون من الممكن إعادة بناء الفهرس لاحقًا دون الاضطرار إلى إعادة إنشائه من الصفر:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_51" style="">
<span class="pln">ALTER INDEX ix_cars_employee_id ON </span><span class="typ">Cars</span><span class="pln"> REBUILD</span><span class="pun">;</span></pre>

<h3>
	الفهارس المجمّعة Clustered أو الفريدة Unique أو المُرتّبة Sorted
</h3>

<p>
	لكل فهرس عدد من الخصائص، هذه الخصائص يمكن أن تُحدّد ساعة إنشاء الفهرس، أو يمكن أن تعيَّن لاحقًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_53" style="">
<span class="pln">CREATE CLUSTERED INDEX ix_clust_employee_id ON </span><span class="typ">Employees</span><span class="pun">(</span><span class="typ">EmployeeId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Email</span><span class="pun">);</span><span class="pln"> </span></pre>

<p>
	تنشئ عبارة SQL أعلاه فهرسًا مُجمّعا (clustered index) جديدًا لجَدول الموظفين <code>Employees</code>. الفهارس المُجمّعة هي فهارس تتحكّم في البنية الفعلية للجدول؛ إذ يُرتَّب الجدول بحيث يُطابق بنية الفهرس. نتيجة لهذا، لا يمكن أن يكون للجدول أكثر من فهرس مُجمّع واحد. ما يعني أنّ الشيفرة أعلاه ستفشل في حال كان الجدول يتوفّر سلفًا على فهرس مُجمّع (تسمّى الجداول التي لا تحتوي على فهارس مُجمّعة "كوْمَات" heaps).
</p>

<p>
	ينشئ المثال التالي فهرسًا فريدًا (unique index) للعمود <code>Email</code> في جدول العملاء <code>Customers</code>. علاوة على تسريع الاستعلام، يفرض الفهرس أن تكون عناوين البريد الإلكتروني فريدة (غير مكرّرة) في العمود. وإن حاولت إدراج صفّ يحتوي بريدًا إلكترونيًا موجودًا سلفا، فستفشل عملية الإدراج أو التحديث (افتراضيًا).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_55" style="">
<span class="pln">CREATE UNIQUE INDEX uq_customers_email ON </span><span class="typ">Customers</span><span class="pun">(</span><span class="typ">Email</span><span class="pun">);</span></pre>

<p>
	ينشئ المثال التالي فهرسًا لجدول العملاء <code>Customers</code>، هذا الفهرس يضع على الجدول قيودًا تنصّ على أنّ الحقل <code>EmployeeID</code> ينبغي أن يكون فريدًا. (ستفشل هذه العملية إن لم يكن العمود فريدًا - أي، إن كان هناك موظف آخر يحمل نفس القيمة.)
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_57" style="">
<span class="pln">CREATE UNIQUE INDEX ix_eid_desc ON </span><span class="typ">Customers</span><span class="pun">(</span><span class="typ">EmployeeID</span><span class="pun">);</span></pre>

<p>
	تنشئ الشيفرة التالية فهرسًا مُرتّبا ترتيبًا تنازليًا. افتراضيا، تُرتّب الفهارس (على الأقل في MSSQL server) تصاعديًا، لكن يمكن تغيير هذا السلوك كما يوضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_59" style="">
<span class="pln">CREATE INDEX ix_eid_desc ON </span><span class="typ">Customers</span><span class="pun">(</span><span class="typ">EmployeeID</span><span class="pln"> </span><span class="typ">Desc</span><span class="pun">);</span></pre>

<h3>
	إعادة بناء الفهرس
</h3>

<p>
	مع مرور الوقت، قد تصبح الفهارس المتشعّبة من النمط ب <a href="https://ar.wikipedia.org/wiki/%D8%A8%D9%8A_-_%D8%AA%D8%B1%D9%8A" rel="external nofollow">B-Tree</a> مُجزّأة (fragmented) نتيجة عمليات التحديث والحذف والإدراج. في نظام SQLServer، هناك نوعان من الفهارس، الفهارس الداخلية، والتي تكون فيها صفحة الفهرس نصف فارغة (half empty)، والفهارس الخارجية، والتي لا يتطابق فيها ترتيب الصفحة المنطقي مع الترتيب الفعلي). إعادة بناء الفهارس تشبه إلى حدّ بعيد حذفها ثمّ إعادة إنشائها.
</p>

<p>
	يمكن إعادة بناء الفهرس باستخدام الصياغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_65" style="">
<span class="pln">ALTER INDEX index_name REBUILD</span><span class="pun">;</span></pre>

<p>
	إعادة بناء الفهارس هي عملية منقطعة (oﬄine) افتراضيًا، أيّ أنّها تقفِل الجدول أثناء عملها وتمنع التعديل عليه، لكنّ العديد من أنظمة معالجة قواعد البيانات (RDBMS) تسمح بإعادة البناء عبر الشبكة (online). كما توفّر بعض أنظمة قواعد البيانات بدائل أخرى لإعادة بناء الفهارس، مثل <code>‎REORGANIZE‎</code> (في SQLServer) أو <code>‎COALESCE‎</code> / <code>‎SHRINK SPACE‎</code> (في Oracle).
</p>

<h3>
	الإدراج باستخدام فهرس فريد
</h3>

<p>
	ستفشل الشيفرة التالية في حال تم تعيين فهرس فريد للعمود <code>Email</code> في جدول العملاء:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_68" style="">
<span class="pln">UPDATE </span><span class="typ">Customers</span><span class="pln"> SET </span><span class="typ">Email</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"richard0123@example.com"</span><span class="pln"> WHERE id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	تقترح هذه الشيفرة بديلًا ممكنًا في مثل هذه الحالة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_70" style="">
<span class="pln">UPDATE </span><span class="typ">Customers</span><span class="pln"> SET </span><span class="typ">Email</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"richard0123@example.com"</span><span class="pln"> WHERE id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> ON DUPLICATE KEY</span><span class="pun">;</span></pre>

<h2>
	رقم الصف Row number
</h2>

<p>
	يمكن استخدام أرقام الصفوف في استعلامات SQL عبر الدالة <code>ROW_NUMBER</code>.
</p>

<p>
	يحذف المثال التالي جميع السجلات خلا السجلّ الأخير (جدول من نوع "واحد إلى كثير" - 1‎‎ to Many)
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_72" style="">
<span class="pln">WITH cte AS </span><span class="pun">(</span><span class="pln">
   SELECT </span><span class="typ">ProjectID</span><span class="pun">,</span><span class="pln">
     ROW_NUMBER</span><span class="pun">()</span><span class="pln"> OVER </span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">ProjectID</span><span class="pln"> ORDER BY </span><span class="typ">InsertDate</span><span class="pln"> DESC</span><span class="pun">)</span><span class="pln"> AS rn
   FROM </span><span class="typ">ProjectNotes</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
DELETE FROM cte WHERE rn </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	تضمّن الشيفرة التالية رقم الصف وفقًا لترتيب الطلبية.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_74" style="">
<span class="pln">SELECT
   ROW_NUMBER</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">ORDER BY </span><span class="typ">Fname</span><span class="pln"> ASC</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">RowNumber</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">Fname</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">LName</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<p>
	يقسّم المثال التالي أرقام الصفوف إلى مجموعات وفقًا لمعيار محدّد.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_76" style="">
<span class="pln">SELECT
  ROW_NUMBER</span><span class="pun">()</span><span class="pln"> OVER</span><span class="pun">(</span><span class="pln">PARTITION BY </span><span class="typ">DepartmentId</span><span class="pln"> ORDER BY </span><span class="typ">DepartmentId</span><span class="pln"> ASC</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">RowNumber</span><span class="pun">,</span><span class="pln">
  </span><span class="typ">DepartmentId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<h2>
	الفرق بين Group By و Distinct في SQL
</h2>

<p>
	تُستخدم العبارة <code>‎GROUP ‎BY‎</code> في SQL مع دوال التجميع (aggregation functions).
</p>

<p>
	إليك الجدول التالي:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				orderId
			</th>
			<th>
				userId
			</th>
			<th>
				storeName
			</th>
			<th>
				orderValue
			</th>
			<th>
				orderDate
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				43
			</td>
			<td>
				Store A
			</td>
			<td>
				25
			</td>
			<td>
				20-03-2016
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				57
			</td>
			<td>
				Store B
			</td>
			<td>
				50
			</td>
			<td>
				22-03-2016
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				43
			</td>
			<td>
				Store A
			</td>
			<td>
				30
			</td>
			<td>
				25-03-2016
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				82
			</td>
			<td>
				Store C
			</td>
			<td>
				10
			</td>
			<td>
				26-03-2016
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				21
			</td>
			<td>
				Store A
			</td>
			<td>
				45
			</td>
			<td>
				29-03-2016
			</td>
		</tr>
</tbody>
</table>
<p>
	يستخدم الاستعلام أدناه <code>‎GROUP BY‎</code> لإجراء عمليات حسابية تجميعية (aggregated calculations).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_78" style="">
<span class="pln">SELECT
    storeName</span><span class="pun">,</span><span class="pln">
    COUNT</span><span class="pun">(*)</span><span class="pln"> AS total_nr_orders</span><span class="pun">,</span><span class="pln">
    COUNT</span><span class="pun">(</span><span class="pln">DISTINCT userId</span><span class="pun">)</span><span class="pln"> AS nr_unique_customers</span><span class="pun">,</span><span class="pln">
    AVG</span><span class="pun">(</span><span class="pln">orderValue</span><span class="pun">)</span><span class="pln"> AS average_order_value</span><span class="pun">,</span><span class="pln">
    MIN</span><span class="pun">(</span><span class="pln">orderDate</span><span class="pun">)</span><span class="pln"> AS first_order</span><span class="pun">,</span><span class="pln">
    MAX</span><span class="pun">(</span><span class="pln">orderDate</span><span class="pun">)</span><span class="pln"> AS lastOrder
FROM
    orders
GROUP BY
    storeName</span><span class="pun">;</span></pre>

<p>
	يُعاد الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				storeName
			</th>
			<th>
				total_nr_orders
			</th>
			<th>
				nr_unique_customers
			</th>
			<th>
				average_order_value ﬁrst_order
			</th>
			<th>
				lastOrder
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Store A
			</td>
			<td>
				3
			</td>
			<td>
				2
			</td>
			<td>
				33.3
			</td>
			<td>
				20-03-2016
			</td>
			<td>
				29-03-2016
			</td>
		</tr>
<tr>
<td>
				Store B
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				50
			</td>
			<td>
				22-03-2016
			</td>
			<td>
				22-03-2016
			</td>
		</tr>
<tr>
<td>
				Store C
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				10
			</td>
			<td>
				26-03-2016
			</td>
			<td>
				26-03-2016
			</td>
		</tr>
</tbody>
</table>
<p>
	بالمقابل، تُستخدم <code>‎DISTINCT‎</code> لسرد توليفة فريدة (unique combination) من القيم المختلفة للأعمدة المحدّدة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_80" style="">
<span class="pln">SELECT DISTINCT
    storeName</span><span class="pun">,</span><span class="pln">
    userId
FROM
    orders</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج:
</p>

<table>
<thead><tr>
<th>
				storeName
			</th>
			<th>
				userId
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Store A
			</td>
			<td>
				43
			</td>
		</tr>
<tr>
<td>
				Store B
			</td>
			<td>
				57
			</td>
		</tr>
<tr>
<td>
				Store C
			</td>
			<td>
				82
			</td>
		</tr>
<tr>
<td>
				Store A
			</td>
			<td>
				21
			</td>
		</tr>
</tbody>
</table>
<h2>
	البحث عن التكرارات في جزء من الأعمدة
</h2>

<p>
	يستخدم المثال التالي دالة نافذة - Window Function - (أي دالة تجري حسابات على مجموعة من الصفوف، كما تتيح الوصول إلى بيانات السجلات التي تسبق السجل الحالي أو التي تلحقه) لعرض جميع الصفوف المُكرّرة (في جزء من الأعمدة).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9317_82" style="">
<span class="pln">WITH CTE </span><span class="pun">(</span><span class="typ">StudentId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> DOB</span><span class="pun">,</span><span class="pln"> </span><span class="typ">RowCnt</span><span class="pun">)</span><span class="pln">
</span><span class="kwd">as</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
SELECT </span><span class="typ">StudentId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DateOfBirth</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> DOB</span><span class="pun">,</span><span class="pln"> SUM</span><span class="pun">(</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> OVER </span><span class="pun">(</span><span class="typ">Partition</span><span class="pln"> </span><span class="typ">By</span><span class="pln"> </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln">
</span><span class="typ">LastName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DateOfBirth</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">RowCnt</span><span class="pln">
FROM tblStudent
</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> CTE </span><span class="kwd">where</span><span class="pln"> </span><span class="typ">RowCnt</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
ORDER BY DOB</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span></pre>

<p>
	ترجمة -وبتصرّف- للفصول من 34 إلى 40 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%85%D8%B1%D8%AC%D8%B9-%D8%A7%D9%84%D9%85%D8%AA%D9%82%D8%AF%D9%85-%D8%A5%D9%84%D9%89-%D9%84%D8%BA%D8%A9-sql-r961/%D8%B1%D8%A7%D8%A8%D8%B7" rel="">الدوال النصية String Functions في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/" rel="">حذف الجداول وقواعد البيانات في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">853</guid><pubDate>Sat, 18 Apr 2020 13:05:00 +0000</pubDate></item><item><title>&#x62D;&#x630;&#x641; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x648;&#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/9.jpg.7219dfe72ce685a320cf5487dd54370d.jpg" /></p>
<p>
	تتحدّث هذه المقالة عن كيفية حذف الجداول وقواعد البيانات (DROP و DELETE)، واقتطاع الجداول (TRUNCATE TABLE)، وكيفية استخدام الحذف المتسلسل (Cascading Delete) في SQL.
</p>

<h2>
	العبارة DELETE
</h2>

<p>
	تُستخدَم عبارة <code>DELETE</code> لحذف السجلات من جدول معيّن.
</p>

<h3>
	حذف جميع الصفوف
</h3>

<p>
	عند استخدام <code>DELETE</code> بدون عبارة <code>‎WHERE‎</code>، ستُحذف جميع الصفوف من الجدول.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_7" style=""><span class="pln">DELETE FROM </span><span class="typ">Employees</span></pre>

<p>
	على العموم، أداء العبارة <code>TRUNCATE</code> (انظر الفقرة أدناه) أفضل من أداء <code>DELETE</code>، لأنّها تتجاهل الزنادات (triggers) والفهارس وتحذف البيانات مباشرة.
</p>

<h3>
	استخدام DELETE مع WHERE
</h3>

<p>
	ستحذف الشيفرة التالية جميع الصفوف التي تفي بشرط <code>‎WHERE‎</code>، أي الصفوف التي تمثل الموظفين الذين يحملون الاسم <code>John</code> .
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_9" style=""><span class="pln">DELETE FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">FName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'John'</span></pre>

<h3>
	الاقتطاع عبر TRUNCATE
</h3>

<p>
	تُستخدم عبارة الاقتطاع <code>TRUNCATE</code> لإعادة الجدول إلى الحالة التي كان عليها عند إنشائه. إذ تُحذف جميع الصفوف من الجدول، ويُعاد تعيين القيم تلقائية الزيادة (auto-increment) إلى قيمتها الأولى.
</p>

<p>
	لا تحذف <code>TRUNCATE</code> كلّ صف على حدة كما هو الشأن مع <code>DELETE</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_11" style=""><span class="pln">TRUNCATE TABLE </span><span class="typ">Employees</span></pre>

<h3>
	حذف بعض الصفوف بناءً على نتائج عمليات المقارنة مع جداول أخرى
</h3>

<p>
	من الممكن حذف البيانات (<code>‎DELETE‎</code>) من جدول إذا كانت مطابقة (أو غير مطابقة) لبيانات جدول آخر.
</p>

<p>
	لنفترض أنّنا نريد حذف البيانات من الجدول المصدري بمجرّد تحميلها إلى الجدول الهدف.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_13" style=""><span class="pln">DELETE FROM </span><span class="typ">Source</span><span class="pln">
WHERE EXISTS </span><span class="pun">(</span><span class="pln"> SELECT </span><span class="lit">1</span><span class="pln"> </span><span class="pun">--ليست</span><span class="pln"> </span><span class="pun">مهمّة</span><span class="pln"> SELECT </span><span class="pun">القيمة</span><span class="pln"> </span><span class="pun">المحدّدة</span><span class="pln"> </span><span class="pun">في</span><span class="pln">
 FROM </span><span class="typ">Target</span><span class="pln">
 </span><span class="typ">Where</span><span class="pln"> </span><span class="typ">Source</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Target</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">)</span></pre>

<p>
	تسمح معظم أنظمة معالجة قواعد البيانات (RDBMS) الشهيرة (مثل MySQL و Oracle و PostgresSQL و Teradata) <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">بضمّ</a> الجداول خلال عملية الحذف <code>‎DELETE‎</code>، ممّا يتيح إجراء موازنات معقّدة في عبارات قصيرة.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<p>
	لنفترض الآن أنّنا نريد تجميع (Aggregate) جدول من الجدول الهدف على أساس التاريخ date وليس المُعرّف ID. لنفترض أيضًا أنّنا نريد ألّا تُحذف البيانات من المصدر إلّا بعد أن يُملأ حقل التاريخ Date الخاص بالجدول المُجمَّع (aggregate).
</p>

<p>
	في أنظمة MySQL و Oracle و Teradata، يمكن القيام بذلك باستخدام:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_15" style=""><span class="pln">DELETE FROM </span><span class="typ">Source</span><span class="pln">
WHERE </span><span class="typ">Source</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="pln">ID
     AND </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="typ">Date</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AggregateSchema</span><span class="pun">.</span><span class="typ">Aggregate</span><span class="pun">.</span><span class="typ">Date</span></pre>

<p>
	أمّا في PostgreSQL، فاستخدم الصياغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_17" style=""><span class="pln">DELETE FROM </span><span class="typ">Source</span><span class="pln">
USING  </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">,</span><span class="pln"> </span><span class="typ">AggregateSchema</span><span class="pun">.</span><span class="typ">Aggregate</span><span class="pln">
WHERE </span><span class="typ">Source</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="pln">ID
     AND </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="typ">DataDate</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AggregateSchema</span><span class="pun">.</span><span class="typ">Aggregate</span><span class="pun">.</span><span class="typ">AggDate</span></pre>

<p>
	ينتج عن هذا أساسًا عمليات <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">ضمّ داخلي</a> (INNER JOINs) بين الجدول المصدري والجدول الهدف والجدول المُجمّع (Aggregate.) يُنفّذ الحذف على الجدول المصدري في حال وجود نفس المعرّفات في الهدف، وكذلك في حال تساوي التاريخين <code>date</code> في الجدول الهدف وكذلك في الجدول المُجمَّع.
</p>

<p>
	يمكن كتابة الاستعلام نفسه (في MySQL و Oracle و Teradata) على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_19" style=""><span class="pln">DELETE </span><span class="typ">Source</span><span class="pln">
FROM </span><span class="typ">Source</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">,</span><span class="pln"> </span><span class="typ">AggregateSchema</span><span class="pun">.</span><span class="typ">Aggregate</span><span class="pln">
WHERE </span><span class="typ">Source</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="pln">ID
 AND </span><span class="typ">TargetSchema</span><span class="pun">.</span><span class="typ">Target</span><span class="pun">.</span><span class="typ">DataDate</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AggregateSchema</span><span class="pun">.</span><span class="typ">Aggregate</span><span class="pun">.</span><span class="typ">AggDate</span></pre>

<p>
	في بعض أنظمة إدارة قواعد البيانات (مثل Oracle و MySQL)، يُمكن أن استخدام عمليات الضمّ joins صراحة في عبارات <code>‎Delete‎</code>، بيْد أنّها غير مدعومة في جميع المنصات (كما هو الحال في Teradata).
</p>

<p>
	يمكن إجراء عمليات الموازنة للتحقق من سيناريوهات عدم التطابق بدلاً من سيناريوهات التطابق مع جميع أنماط الصياغات (لاحظ <code>‎NOT‎ EXISTS‎</code> أدناه):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_21" style=""><span class="pln">DELETE FROM </span><span class="typ">Source</span><span class="pln">
WHERE NOT EXISTS </span><span class="pun">(</span><span class="pln"> SELECT </span><span class="lit">1</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">لا</span><span class="pln"> </span><span class="pun">تهمّ</span><span class="pln"> SELECT </span><span class="pun">القيم</span><span class="pln"> </span><span class="pun">المحدّدة</span><span class="pln"> </span><span class="pun">في</span><span class="pln">
 FROM </span><span class="typ">Target</span><span class="pln">
 </span><span class="typ">Where</span><span class="pln"> </span><span class="typ">Source</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Target</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">)</span></pre>

<h2>
	الاقتطاع عبر TRUNCATE
</h2>

<p>
	تحذف عبارة <code>TRUNCATE</code> كافة البيانات من الجدول. فهي تكافئ إجراء عملية الحذف <code>DELETE</code> بدون تصفية، ولكن قد تكون لها بعض القيود أو التحسينات اعتمادا على برنامج قواعد البيانات المُستخدم.
</p>

<p>
	يزيل المثال التالي جميع الصفوف من جدول الموظفين <code>Employee</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_23" style=""><span class="pln">TRUNCATE TABLE </span><span class="typ">Employee</span><span class="pun">;</span></pre>

<p>
	يُفضّل عمومًا استخدام <code>TRUNCATE</code> على <code>DELETE</code>، لأنّها تتجاهل جميع الفهارس والزنادات (triggers)، وتزيل العناصر مباشرة.
</p>

<p>
	حذف الجداول (<code>DELETE</code>) هي عملية تعمل على الصفوف، بمعنى أنّها تحذف كل صفّ على حدة. أما اقتطاع الجداول، فهي عملية تعمل على صفحة كاملة من البيانات (page operation)، إذ يُعاد تخصيص (reallocate) صفحة البيانات بأكملها. إذا كان لديك جدول يحتوي مليون صفّ، فسيكون اقتطاع الجدول أسرع بكثير من استخدام عبارة حذف <code>DELETE</code> الجدول.
</p>

<p>
	بالمقابل، يمكننا تحديد الصفوف المراد حذفها باستخدام <code>DELETE</code>، ولكن لا يمكننا تحديد الصفوف المراد اقتطاعها، إذ لا يمكننا سوى اقتطاع جميع السجلات مرّة واحدة.
</p>

<p>
	يؤدّي حذف جميع الصفوف (عبر <code>DELETE</code>) ثم إدراج سجلات جديدة إلى زيادة قيمة المفتاح الرئيسي المتزايد تلقائيًا (Auto incremented Primary key) انطلاقًا من القيمة المُدرجة سابقًا، أمّا في عبارة Truncate، فسيُعاد تعيين قيمة المفتاح الرئيسي التلقائي، وسيبدأ من 1.
</p>

<p>
	لاحظ أنه عند اقتطاع جدول ما، يجب ألا تكون هناك مفاتيح خارجية (foreign keys)، وإلا فسيُطرح خطأ.
</p>

<h2>
	DROP
</h2>

<h3>
	محو جدول DROP TABLE
</h3>

<p>
	تحذف عبارة <code>DROP TABLE</code> جدولًا مع بياناته من قاعدة البيانات بشكل دائم.
</p>

<p>
	الأمثلة التالية تتحقّق من وجود الجدول قبل محوه:
</p>

<ul>
	<li>
		MySQL ≥ 3.19
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_25" style=""><span class="pln">DROP TABLE IF EXISTS </span><span class="typ">MyTable</span><span class="pun">;</span></pre>

<ul>
	<li>
		PostgreSQL ≥ 8.x
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_27" style=""><span class="pln">DROP TABLE IF EXISTS </span><span class="typ">MyTable</span><span class="pun">;</span></pre>

<ul>
	<li>
		SQL Server ≥ 2005
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_29" style=""><span class="typ">If</span><span class="pln"> </span><span class="typ">Exists</span><span class="pun">(</span><span class="typ">Select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="typ">From</span><span class="pln"> </span><span class="typ">Information_Schema</span><span class="pun">.</span><span class="typ">Tables</span><span class="pln">
      </span><span class="typ">Where</span><span class="pln"> </span><span class="typ">Table_Schema</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'dbo'</span><span class="pln">
         </span><span class="typ">And</span><span class="pln"> </span><span class="typ">Table_Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'MyTable'</span><span class="pun">)</span><span class="pln">
    </span><span class="typ">Drop</span><span class="pln"> </span><span class="typ">Table</span><span class="pln"> dbo</span><span class="pun">.</span><span class="typ">MyTable</span></pre>

<ul>
	<li>
		SQLite ≥ 3.0
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_31" style=""><span class="pln">DROP TABLE IF EXISTS </span><span class="typ">MyTable</span><span class="pun">;</span></pre>

<h3>
	محو قاعدة بيانات
</h3>

<p>
	يمكن محو قاعدة البيانات باستخدام عبارة <code>DROP DATABASE</code>.
</p>

<p>
	<strong>تنبيه</strong>: تحذف <code>DROP DATABASE</code> قاعدة البيانات نهائيًا، لذا عليك أن تحرص دائمًا على تخزين نسخة احتياطية من قاعدة البيانات إن خشيت ضياع البيانات.
</p>

<p>
	تمحو الشيفرة التالي قاعدة بيانات الموظفين:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_33" style=""><span class="pln">DROP DATABASE </span><span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="typ">Employees</span><span class="pun">]</span></pre>

<h2>
	الحذف المتسلسل Cascading Delete
</h2>

<p>
	لنفترض أنّ لديك تطبيقًا يدير فندقًا يضمّ عددًا من الغرف. لنفترض أنّ لديك العديد من العملاء، وقد قرّرت إنشاء قاعدة بيانات لتخزين المعلومات الخاصة بعملائك.
</p>

<p>
	ستحتوي قاعدة البيانات جدولًا واحدًا للعملاء، وآخر للغرف. كل عميل يمكن أن يستأجر N غرفة. هذا يعني أنّ جدول الغرف سيحتوي مفتاحًا خارجيًا (foreign key) يشير إلى جدول العملاء.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_35" style=""><span class="pln">ALTER TABLE dbo</span><span class="pun">.</span><span class="pln">T_Room WITH CHECK ADD CONSTRAINT FK_T_Room_T_Client FOREIGN KEY</span><span class="pun">(</span><span class="pln">RM_CLI_ID</span><span class="pun">)</span><span class="pln">
REFERENCES dbo</span><span class="pun">.</span><span class="pln">T_Client </span><span class="pun">(</span><span class="pln">CLI_ID</span><span class="pun">)</span><span class="pln">
GO</span></pre>

<p>
	عند خروج أحد العملاء، سيتعيّن عليك حذف بياناته من البرنامج. .لكن إن كتبت:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_37" style=""><span class="pln">DELETE FROM T_Client WHERE CLI_ID </span><span class="pun">=</span><span class="pln"> x</span></pre>

<p>
	فسترتَكب "انتهاكَ مفتاحٍ خارجي" (foreign key violation)، ذلك أنّه لا يجوز لك حذف عميل لديه غرفة.
</p>

<p>
	عليك حذف غرف العميل قبل أن تحذف العميل. لنفترض أنّك تتوقّع أنّه قد تُضاف العديد من المفاتيح الخارجية (foreign key dependencies) في قاعدة البيانات مستقبلا نتيجةً لنموّ التطبيق. قد يخلق هذا مشكلة كبيرة. لأنّه في كلّ مرّة تعدّل قاعدة البيانات، سيكون عليك تعديل شيفرة تطبيقك في كل المواضِع المرتبطة بها. وقد يكون عليك أيضًا تعديل شيفرات تطبيقات أخرى (مثل الواجهات البرمجية للأنظمة الأخرى).
</p>

<p>
	هناك حل أفضل يكفيك كلّ هذا العناء. فيكفي أن تضيف العبارة <code>‎ON DELETE CASCADE‎</code> إلى مفتاحك الخارجي.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_40" style=""><span class="pln">ALTER TABLE dbo</span><span class="pun">.</span><span class="pln">T_Room </span><span class="pun">--</span><span class="pln"> WITH CHECK </span><span class="pun">--</span><span class="pln"> SQL</span><span class="pun">-</span><span class="typ">Server</span><span class="pln"> can specify WITH CHECK</span><span class="pun">/</span><span class="pln">WITH NOCHECK
ADD CONSTRAINT FK_T_Room_T_Client FOREIGN KEY</span><span class="pun">(</span><span class="pln">RM_CLI_ID</span><span class="pun">)</span><span class="pln">
REFERENCES dbo</span><span class="pun">.</span><span class="pln">T_Client </span><span class="pun">(</span><span class="pln">CLI_ID</span><span class="pun">)</span><span class="pln">
ON DELETE CASCADE</span></pre>

<p>
	الآن يمكنك أن تكتب:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_44" style=""><span class="pln">DELETE FROM T_Client WHERE CLI_ID </span><span class="pun">=</span><span class="pln"> x</span></pre>

<p>
	وستُحذف الغرف تلقائيًا عند حذف العميل. لقد حللنا المشكلة دون الحاجة إلى إجراء تغييرات في ِشيفرة التطبيق.
</p>

<p>
	<strong>تنبيه</strong>: في Microsoft SQL-Server، لن تنجح هذه المقاربة إذا كان الجدول يشير إلى نفسه. لذا إن حاولت إجراء حذف متسلسل على بنية متشعّبة عودية (recursive tree structure)، على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_882_47" style=""><span class="pln">IF NOT EXISTS </span><span class="pun">(</span><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM sys</span><span class="pun">.</span><span class="pln">foreign_keys WHERE object_id </span><span class="pun">=</span><span class="pln"> OBJECT_ID</span><span class="pun">(</span><span class="pln">N</span><span class="str">'[dbo].[FK_T_FMS_Navigation_T_FMS_Navigation]'</span><span class="pun">)</span><span class="pln"> AND parent_object_id </span><span class="pun">=</span><span class="pln">
OBJECT_ID</span><span class="pun">(</span><span class="pln">N</span><span class="str">'[dbo].[T_FMS_Navigation]'</span><span class="pun">))</span><span class="pln">
ALTER TABLE </span><span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="pln">T_FMS_Navigation</span><span class="pun">]</span><span class="pln"> WITH CHECK ADD CONSTRAINT
</span><span class="pun">[</span><span class="pln">FK_T_FMS_Navigation_T_FMS_Navigation</span><span class="pun">]</span><span class="pln"> FOREIGN KEY</span><span class="pun">([</span><span class="pln">NA_NA_UID</span><span class="pun">])</span><span class="pln">
REFERENCES </span><span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="pln">T_FMS_Navigation</span><span class="pun">]</span><span class="pln"> </span><span class="pun">([</span><span class="pln">NA_UID</span><span class="pun">])</span><span class="pln">
ON DELETE CASCADE
GO
IF EXISTS </span><span class="pun">(</span><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM sys</span><span class="pun">.</span><span class="pln">foreign_keys WHERE object_id </span><span class="pun">=</span><span class="pln">
OBJECT_ID</span><span class="pun">(</span><span class="pln">N</span><span class="str">'[dbo].[FK_T_FMS_Navigation_T_FMS_Navigation]'</span><span class="pun">)</span><span class="pln"> AND parent_object_id </span><span class="pun">=</span><span class="pln">
OBJECT_ID</span><span class="pun">(</span><span class="pln">N</span><span class="str">'[dbo].[T_FMS_Navigation]'</span><span class="pun">))</span><span class="pln">
ALTER TABLE </span><span class="pun">[</span><span class="pln">dbo</span><span class="pun">].[</span><span class="pln">T_FMS_Navigation</span><span class="pun">]</span><span class="pln"> CHECK CONSTRAINT </span><span class="pun">[</span><span class="pln">FK_T_FMS_Navigation_T_FMS_Navigation</span><span class="pun">]</span><span class="pln">
GO</span></pre>

<p>
	فلن ينجح الأمر، لأنّ Microsoft-SQL-server لن تسمح لك بتعيين مفتاح خارجي باستخدام <code>‎ON DELETE CASCADE‎</code> على بنية متشعّبة عودية. أحد أسباب ذلك هو أنّ الشعبة قد تكون دورية، وهذا قد يؤدي إلى عملية سرمدية غير منتهية.
</p>

<p>
	نظام PostgreSQL من ناحية أخرى يمكنه القيام بذلك؛ شريطة ألّا تكون الشعبة دورية (non-cyclic). إذ أنّه في حال كانت الشعبة دورية، فسيُطرح خطأ وقت التشغيل. الحل في مثل هذه الحالة هو إنشاء دالة حذف مخصّصة.
</p>

<p>
	<strong>تنبيه</strong>: لا يمكنك حذف جدول العملاء وإعادة إدراج القيم مرّة أخرى، وإن حاولت ذلك، فستُحذف جميع المدخلات في الجدول <code>T_Room</code>.
</p>

<p>
	ترجمة -وبتصرّف- للفصول من 29 إلى 33 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D9%88%D8%A7%D8%B6%D9%8A%D8%B9-%D9%85%D8%AA%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-sql-r853/" rel="">مواضيع متقدمة في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">معالجة الأخطاء والتعديل على قواعد البيانات في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">852</guid><pubDate>Wed, 15 Apr 2020 13:09:00 +0000</pubDate></item><item><title>&#x645;&#x639;&#x627;&#x644;&#x62C;&#x629; &#x627;&#x644;&#x623;&#x62E;&#x637;&#x627;&#x621; &#x648;&#x627;&#x644;&#x62A;&#x639;&#x62F;&#x64A;&#x644; &#x639;&#x644;&#x649; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/8.jpg.506a70d96b37efd37b4ccfad31035d93.jpg" /></p>

<p>
	تستعرض هذه المقالة كيفية معالجة الأخطاء باستخدام العبارة TRY / CATCH، وكيفية حساب الاتحاد (UNION) وبعض العمليات الأخرى التي تمكّن من تعديل قواعد البيانات.
</p>

<h2>
	العبارة TRY / CATCH
</h2>

<p>
	تُستخد عبارة TRY / CATCH لإمساك الأخطاء في الشيفرات التي يُتوقع أن تطرح أخطاء.
</p>

<p>
	ستفشل عمليتا الإدراج في المثال التالي بسبب خطأ في صياغة التاريخ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_7" style="">
<span class="kwd">BEGIN</span><span class="pln"> TRANSACTION
</span><span class="kwd">BEGIN</span><span class="pln"> TRY
    INSERT INTO dbo</span><span class="pun">.</span><span class="typ">Sale</span><span class="pun">(</span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SaleDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Quantity</span><span class="pun">)</span><span class="pln">
    VALUES </span><span class="pun">(</span><span class="lit">5.2</span><span class="pun">,</span><span class="pln"> GETDATE</span><span class="pun">(),</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    INSERT INTO dbo</span><span class="pun">.</span><span class="typ">Sale</span><span class="pun">(</span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SaleDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Quantity</span><span class="pun">)</span><span class="pln">
    VALUES </span><span class="pun">(</span><span class="lit">5.2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'not a date'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    COMMIT TRANSACTION
</span><span class="kwd">END</span><span class="pln"> TRY
</span><span class="kwd">BEGIN</span><span class="pln"> CATCH
    THROW
    ROLLBACK TRANSACTION
</span><span class="kwd">END</span><span class="pln"> CATCH</span></pre>

<p>
	في المثال التالي، ستكتمل عَمليتا الإدراج دائمًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_9" style="">
<span class="kwd">BEGIN</span><span class="pln"> TRANSACTION
</span><span class="kwd">BEGIN</span><span class="pln"> TRY
    INSERT INTO dbo</span><span class="pun">.</span><span class="typ">Sale</span><span class="pun">(</span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SaleDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Quantity</span><span class="pun">)</span><span class="pln">
    VALUES </span><span class="pun">(</span><span class="lit">5.2</span><span class="pun">,</span><span class="pln"> GETDATE</span><span class="pun">(),</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    INSERT INTO dbo</span><span class="pun">.</span><span class="typ">Sale</span><span class="pun">(</span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="typ">SaleDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Quantity</span><span class="pun">)</span><span class="pln">
    VALUES </span><span class="pun">(</span><span class="lit">5.2</span><span class="pun">,</span><span class="pln"> GETDATE</span><span class="pun">(),</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    COMMIT TRANSACTION
</span><span class="kwd">END</span><span class="pln"> TRY
</span><span class="kwd">BEGIN</span><span class="pln"> CATCH
    THROW
    ROLLBACK TRANSACTION
</span><span class="kwd">END</span><span class="pln"> CATCH</span></pre>

<h2>
	الاتحاد UNION
</h2>

<p>
	تُستخدم الكلمة المفتاحية <code>UNION</code> في SQL لدمج نتائج عبارتي <code>SELECT</code> دون تكرار. أي أنّها تشبه عملية الاتحاد المعروفة في علم المجموعات.
</p>

<p>
	من أجل استخدام <code>UNION</code> لدمج النتائج، يُشترط أن يكون لكلي عبارتي <code>SELECT</code> عدد الأعمدة ونوع البيانات نفسه، ووفق الترتيب نفسه، ولكن يجوز أن تختلف أطوال الأعمدة.
</p>

<p>
	إليك الجدولين التاليين:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_11" style="">
<span class="pln">CREATE TABLE HR_EMPLOYEES
</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Position</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
CREATE TABLE FINANCE_EMPLOYEES
</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> INT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Position</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">30</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	باستخدام <code>‎UNION‎</code>، يمكننا الحصول على جميع المدراء (<code>‎manager‎</code>) العاملين في القسمين <code>HR</code> و <code>Finance</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_13" style="">
<span class="pln">SELECT
    </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln">  
FROM
    HR_EMPLOYEES  
WHERE
    </span><span class="typ">Position</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'manager'</span><span class="pln"> 
UNION ALL 
SELECT
    </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln">  
FROM
    FINANCE_EMPLOYEES  
WHERE
    </span><span class="typ">Position</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'manager'</span><span class="pln"> </span></pre>

<p>
	تزيل العبارة <code>‎UNION‎</code> الصفوف المكرّرة من نتائج الاستعلام. لكن لمّا كان من الممكن أن يشترك عدّة أشخاص في نفس الاسم، ويحتلّون نفس الموقع في كلا القسمين، فسنستخدم عبارة <code>‎UNION ALL‎</code> التي لا تزيل التكرارات.
</p>

<p>
	يمكنك <a href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">تكنِية</a> (aliasing) الأعمدة المُعادة عبر وضع الكُنى في أول عبارات select على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_16" style="">
<span class="pln">SELECT
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'First Name'</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Last Name'</span><span class="pln">
FROM
    HR_EMPLOYEES  
WHERE
    </span><span class="typ">Position</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'manager'</span><span class="pln"> 
UNION ALL 
SELECT
    </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln">  
FROM
    FINANCE_EMPLOYEES  
WHERE
    </span><span class="typ">Position</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'manager'</span><span class="pln"> </span></pre>

<p>
	هناك فرق أساسي بين <code>‎UNION‎</code> و <code>UNION ALL</code>:
</p>

<ul>
<li>
		تضمّ <code>‎UNION‎</code> مجموعتي النتائج مع إزالة التكرارات من مجموعة النتائج
	</li>
	<li>
		تضمّ <code>UNION ALL</code> مجموعتي النتائج دون إزالة التكرارات
	</li>
</ul>
<p>
	من الأخطاء الشائعة استخدامُ <code>‎UNION‎</code> في المواضع التي لا تكون فيها حاجة إلى إزالة التكرار من النتائج، فالكلفة الإضافية على الأداء قد تكون أكبر من المكاسب الناجمة عن إزالة التكرارات.
</p>

<p>
	<strong>متى تستخدم UNION</strong>
</p>

<p>
	لنفترض أنك تريد تصفية الدول بحسب قيم سمتين (attributes) مختلفتين، وأنّك أنشأت فهارس منفصلة غير مجمّعة (non-clustered indexes) لكل عمود. في هذه الحالة، يمكنك استخدام <code>‎UNION‎</code>، التي تتيح لك استخدام كلا الفهرسين مع تجنّب التكرارات.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_18" style="">
<span class="pln">SELECT C1</span><span class="pun">,</span><span class="pln"> C2</span><span class="pun">,</span><span class="pln"> C3 FROM </span><span class="typ">Table1</span><span class="pln"> WHERE C1 </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@Param1</span><span class="pln">
UNION
SELECT C1</span><span class="pun">,</span><span class="pln"> C2</span><span class="pun">,</span><span class="pln"> C3 FROM </span><span class="typ">Table1</span><span class="pln"> WHERE C2 </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@Param2</span></pre>

<p>
	لن تُستخدم إلا الفهارس البسيطة في تنفيذ الاستعلامات، كما يمكنك تقليل عدد الفهارس المنفصلة غير المجمّعة (separate non-clustered indexes)، وهذا سيؤدي إلى تحسين الأداء.
</p>

<p>
	<strong>متى تستخدم UNION ALL</strong>
</p>

<p>
	لنفترض أنك تريد تصفية جدول ما بحسب قيمتي سمتين، بيْد أنّك لا تحتاج إلى تصفية السجلات المكرّرة (إمّا لأنّ ذلك لن يضرّ، أو أنّك صمّمت قاعدة البيانات بحيث لن ينتج أيّ تكرارات عن عملية الاتحاد).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_20" style="">
<span class="pln">SELECT C1 FROM </span><span class="typ">Table1</span><span class="pln">
UNION ALL
SELECT C1 FROM </span><span class="typ">Table2</span></pre>

<p>
	يمكن أن يكون استخدام <code>UNION ALL</code> مفيدًا عند إنشاء معارض (Views) تضمّ (join) بيانات صُمِّمت لكي تُقسَّم وتُوزَّع عبر عدّة جداول (ربما لأسباب تتعلق بتحسين الأداء). ولمّا كانت البيانات مقُسمة سلفًا، فإنّ جعل محرّك قاعدة البيانات يزيل التكرارات لن يضيف أيّ قيمة، وسَيبطئ الاستعلام.
</p>

<h2>
	ALTER TABLE
</h2>

<p>
	تُستخدم العبارة <code>ALTER</code> في SQL لتعدِيل قيد (constraint) أو عمود من جدول.
</p>

<h3>
	إضافة عمود
</h3>

<p>
	يضيف المثال التالي عمودين إلى جدول الموظفين، الأول باسم <code>‎StartingDate‎</code>، ولا يمكن أن يكون معدومًا (not NULLABLE)، وقيمته الافتراضية تساوي التاريخ الحالي، أمّا العمود الثاني، فيُسمّى <code>‎DateOfBirth‎</code>، ويمكن أن يكون معدومًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_22" style="">
<span class="pln">ALTER TABLE </span><span class="typ">Employees</span><span class="pln">
ADD </span><span class="typ">StartingDate</span><span class="pln"> date NOT NULL DEFAULT </span><span class="typ">GetDate</span><span class="pun">(),</span><span class="pln">
    </span><span class="typ">DateOfBirth</span><span class="pln"> date NULL</span></pre>

<h3>
	حذف عمود
</h3>

<p>
	تحذف الشيفرَة أدناه العمود <code>salary</code> من جدول الموظفين:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_24" style="">
<span class="pln">ALTER TABLE </span><span class="typ">Employees</span><span class="pln">
DROP COLUMN salary</span><span class="pun">;</span></pre>

<h3>
	إضافة مفتاح رئيسي Primary Key
</h3>

<p>
	تضيف الشيفرة أدناه مفتاحًا رئيسيًا إلى جدول "الموظفين" في الحقل <code>‎ID‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_26" style="">
<span class="pln">ALTER TABLE EMPLOYEES ADD pk_EmployeeID PRIMARY KEY </span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span></pre>

<p>
	يؤدّي تضمين عدّة أسماء أعمدة بين قوسين بعد العبارة <code>PRIMARY KEY</code> إلى إنشاء مفتاح رئيسي مُركّب (Composite Primary Key):
</p>

<pre class="ipsCode">
ALTER TABLE EMPLOYEES ADD pk_EmployeeID PRIMARY KEY (ID, FName)
</pre>

<h3>
	تغيير عمود
</h3>

<p>
	يعدّل الاستعلام التالي نوع بيانات العمود <code>‎StartingDate‎</code>، ويغيّره من النوع <code>‎date‎</code> إلى <code>‎datetime‎</code>، كما يعيّن قيمته الافتراضية عند قيمة التاريخ الحالي.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_29" style="">
<span class="pln">ALTER TABLE </span><span class="typ">Employees</span><span class="pln">
ALTER COLUMN </span><span class="typ">StartingDate</span><span class="pln"> DATETIME NOT NULL DEFAULT </span><span class="pun">(</span><span class="pln">GETDATE</span><span class="pun">())</span></pre>

<h3>
	حذف القيود Drop Constraint
</h3>

<p>
	تحذف الشيفرة التالية قيدًا يُسمّى <code>DefaultSalary</code> من جدول الموظفين:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_31" style="">
<span class="pln">ALTER TABLE </span><span class="typ">Employees</span><span class="pln">
DROP CONSTRAINT </span><span class="typ">DefaultSalary</span></pre>

<p>
	<strong>تنبيه</strong>: عليك حذف قيود العمود قبل حذف العمود.
</p>

<h2>
	الإدراج عبر INSERT
</h2>

<h3>
	إدراج البيانات من جدول آخر باستخدام SELECT
</h3>

<p>
	يدرج المثال التالي جميع الموظفين (Employees) في جدول العملاء (Customers). ونظرًا لأنّ الجدولين يحتويان على حقول مختلفة، وقد لا تريد نقل جميع الحقول، فستحتاج إلى تحديد الحقول التي ستُدرج القيم فيها، و الحقول التي يجب اختيارها.
</p>

<p>
	لست مضطرّا للحفاظ على أسماء الحقول المترابطة (correlating ﬁeld)، بيْد أنّه ينبغي عدم تغيير نوع البيانات.
</p>

<p>
	يفترض هذا المثال أنّ هويّة حقل المعرّف (Id) مُحدّدة، وأنه تلقائيّ التزايد (auto increment).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_33" style="">
<span class="pln">INSERT INTO </span><span class="typ">Customers</span><span class="pln"> </span><span class="pun">(</span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<p>
	إن كان للجدولين نفس أسماء الحقول، وكنت تريد نقل جميع السجلات من جدول إلى آخر، فيمكنك استخدام الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_35" style="">
<span class="pln">INSERT INTO </span><span class="typ">Table1</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Table2</span></pre>

<h3>
	إدراج صف جديد
</h3>

<p>
	تدرج الشيفرة التالية صفًّا جديدًا في الجدول <code>‎Customers‎</code>. لاحظ أنّنا لم نحدّد قيمة العمود <code>‎Id‎</code>، ذلك أنّ قيمته ستضاف تلقائيًا. أمّا الأعمدة الأخرى فينبغي أن تُعيّن قيمها.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_37" style="">
<span class="pln">INSERT INTO </span><span class="typ">Customers</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="str">'Zack'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Smith'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'zack@example.com'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'7049989942'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EMAIL'</span><span class="pun">);</span></pre>

<h3>
	إدراج أعمدة معيّنة
</h3>

<p>
	تدرج الشيفرة التالية صفًّا جديدًا في الجدول <code>‎Customers‎</code>، لاحظ أنّها لن تُدرج البيانات إلّا في الأعمدة المُحدّدة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_39" style="">
<span class="pln">INSERT INTO </span><span class="typ">Customers</span><span class="pln"> </span><span class="pun">(</span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Email</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PreferredContact</span><span class="pun">)</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="str">'Zack'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Smith'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'zack@example.com'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EMAIL'</span><span class="pun">);</span></pre>

<p>
	لاحظ أنه لم يتم تقديم أيّ قيمة للعمود <code>‎PhoneNumber‎</code>. ولاحظ أيضًا أنّه ينبغي تضمين الأعمدة الموسومة بـ <code>‎not null‎</code>.
</p>

<h3>
	إدراج عدّة صفوف دفعة واحدة
</h3>

<p>
	يمكن إدراج عدّة صفوف باستخدام أمر إدراج واحد على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_41" style="">
<span class="pln">INSERT INTO tbl_name </span><span class="pun">(</span><span class="pln">field1</span><span class="pun">,</span><span class="pln"> field2</span><span class="pun">,</span><span class="pln"> field3</span><span class="pun">)</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="lit">5</span><span class="pun">,</span><span class="lit">6</span><span class="pun">),</span><span class="pln"> </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="lit">8</span><span class="pun">,</span><span class="lit">9</span><span class="pun">);</span></pre>

<p>
	قد تحتاج أحيانًا إلى إدراج كمّيات كبيرة من البيانات دُفعة واحدة، عادة ما توفّر أنظمة إدارة قواعد البيانات بعض التوصيات والميزات للمساعدة على ذلك، كما في حالة:
</p>

<ul>
<li>
		<a href="http://dev.mysql.com/doc/refman/5.7/en/load-data.html" rel="external nofollow">MySQL</a>
	</li>
	<li>
		<a href="https://msdn.microsoft.com/en-us/library/ms188365.aspx" rel="external nofollow">MSSQL</a>
	</li>
</ul>
<h2>
	الدمج عبر MERGE
</h2>

<p>
	تسمح العبارة <code>MERGE</code> (تُسمّى أيضًا <code>UPSERT</code>) بإدراج صفوف جديدة أو تحديثها. الهدف من هذه العملية هو إجراء مجموعة كاملة من العمليات تلقائيًا (لضمان بقاء البيانات متسقة)، ومنع حمل الاتصال الزائد (communication overhead) لعبارات SQL في نظام عميل / خادم (client/server system).
</p>

<h3>
	إجراء عملية الدمج لجعل المصدر يطابق الهدف
</h3>

<p>
	يجري المثال التالي عملية دمج (<code>MERGE</code>) لجعل الجدول المصدري يطابق الجدول الهدف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_43" style="">
<span class="pln">MERGE INTO targetTable t
    USING sourceTable s
        ON t</span><span class="pun">.</span><span class="pln">PKID </span><span class="pun">=</span><span class="pln"> s</span><span class="pun">.</span><span class="pln">PKID
     WHEN MATCHED AND NOT EXISTS </span><span class="pun">(</span><span class="pln">
             SELECT s</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnC</span><span class="pln">
             INTERSECT
             SELECT t</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> t</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnC</span><span class="pln">
             </span><span class="pun">)</span><span class="pln">
     THEN UPDATE SET
            t</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pln">
         </span><span class="pun">,</span><span class="pln">t</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pln">
         </span><span class="pun">,</span><span class="pln">t</span><span class="pun">.</span><span class="typ">ColumnC</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnC</span><span class="pln">
     WHEN NOT MATCHED BY TARGET
         THEN INSERT </span><span class="pun">(</span><span class="pln">PKID</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ColumnC</span><span class="pun">)</span><span class="pln">
         VALUES </span><span class="pun">(</span><span class="pln">s</span><span class="pun">.</span><span class="pln">PKID</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnA</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnB</span><span class="pun">,</span><span class="pln"> s</span><span class="pun">.</span><span class="typ">ColumnC</span><span class="pun">)</span><span class="pln">
     WHEN NOT MATCHED BY SOURCE
         THEN DELETE
     </span><span class="pun">;</span></pre>

<p>
	<strong>ملاحظة</strong>: تمنع العبارة <code>‎AND NOT EXISTS‎</code> تحديث السجلات التي لم تتغير. ويتيح استخدام البنية <code>‎INTERSECT‎</code> موازنة الأعمدة المعدومة (nullable) بدون مشاكل.
</p>

<h3>
	MySQL: عدّ أسماء المستخدمين
</h3>

<p>
	لنفترض أنّنا نريد أن نحسب عدد المستخدمين الذين لهم نفس الاسم. سننشئ أولًا جدولًا <code>‎users‎</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_45" style="">
<span class="pln">create table users</span><span class="pun">(</span><span class="pln">
    id </span><span class="kwd">int</span><span class="pln"> primary key auto_increment</span><span class="pun">,</span><span class="pln">
    name varchar</span><span class="pun">(</span><span class="lit">8</span><span class="pun">),</span><span class="pln">
    count </span><span class="kwd">int</span><span class="pun">,</span><span class="pln">
    unique key name</span><span class="pun">(</span><span class="pln">name</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	لنفترض الآن أنّنا اكتشفنا وجود مستخدم آخر جديدًا يُدعى <code>Joe</code>، ونودّ أن نأخذه في الحسبان. أولًا، سنتحقّق ممّا إذا كان هناك صفّ يحمل ذلك الاسم، فإن كان الأمر كذلك، حدّثناه وزدنا قيمته بواحد؛ خلاف ذلك، سننشئ صفًّا جديدًا.
</p>

<p>
	تستخدم MySQL الصياغة التالية: <a href="https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html" rel="external nofollow">insert … on duplicate key update …‎‎</a>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_47" style="">
<span class="pln">insert </span><span class="kwd">into</span><span class="pln"> users</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> count</span><span class="pun">)</span><span class="pln">
    values </span><span class="pun">(</span><span class="str">'Joe'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    on duplicate key update count</span><span class="pun">=</span><span class="pln">count</span><span class="pun">+</span><span class="lit">1</span><span class="pun">;</span></pre>

<h3>
	PostgreSQL: عدّ أسماء المستخدمين
</h3>

<p>
	لنفترض أنّنا نريد أن نعرف عدد المستخدمين الذين لهم نفس الاسم. سننشئ جدولًا <code>‎users‎</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_49" style="">
<span class="pln">create table users</span><span class="pun">(</span><span class="pln">
    id serial</span><span class="pun">,</span><span class="pln">
    name varchar</span><span class="pun">(</span><span class="lit">8</span><span class="pun">)</span><span class="pln"> unique</span><span class="pun">,</span><span class="pln">
    count </span><span class="kwd">int</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	كما في الفقرة السابقة، سنفترض أنّنا اكتشفنا للتو مستخدمًا جديدًا يُدعى <code>Joe</code>، ونودّ أن نأخذه في الحسبان:
</p>

<p>
	تستخدم PostgreSQLالصياغة التالية: <a href="https://www.postgresql.org/docs/current/static/sql-insert.html" rel="external nofollow">insert … on conflict … do update …‎‎</a>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_51" style="">
<span class="pln">insert </span><span class="kwd">into</span><span class="pln"> users</span><span class="pun">(</span><span class="pln">name</span><span class="pun">,</span><span class="pln"> count</span><span class="pun">)</span><span class="pln">
    values</span><span class="pun">(</span><span class="str">'Joe'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">)</span><span class="pln">
    on conflict </span><span class="pun">(</span><span class="pln">name</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">do</span><span class="pln"> update </span><span class="kwd">set</span><span class="pln"> count </span><span class="pun">=</span><span class="pln"> users</span><span class="pun">.</span><span class="pln">count </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<h2>
	التطبيق المتقاطع والتطبيق الخارجي cross apply, outer apply
</h2>

<p>
	تُستخدم العبارة <code>Apply</code> لتطبيق دالة على جدول.
</p>

<p>
	سننشئ جدولًا <code>Department</code> لتخزين المعلومات الخاصّة بالأقسام. ثم ننشئ جدولًا <code>Employee</code> يحتوي معلومات حول الموظفين. ينتمي كلّ موظّف إلى قسم معيّن، وبالتالي، فإنّ لجدول الموظّفين مرجعًا متكاملًا (referential integrity) مع جدول الأقسام.
</p>

<p>
	يختار الاستعلام الأول البيانات من جدول الأقسام، ثمّ يستخدم العبارة <code>CROSS APPLY</code> لتقييم جدول الموظفين نسبة إلى سجلّات جدول الأقسام. أمّا الاستعلام التالي، [فيضمّ](رابط الفصل 6) جدول الأقسام إلى جدول الموظفين، ثم يعيد جميع السجلات التي تحقّق شرط الضمّ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_53" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
CROSS APPLY </span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="pun">*</span><span class="pln">
    FROM </span><span class="typ">Employee</span><span class="pln"> E
    WHERE E</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> A
GO
SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
INNER JOIN </span><span class="typ">Employee</span><span class="pln"> E
    ON D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> E</span><span class="pun">.</span><span class="typ">DepartmentID</span></pre>

<p>
	لو نظرت إلى النتائج المُعادة، فستلاحظ أنّ الاستعلامين يعيدان نفس النتائج؛ قد تسأل إذن: كيف تختلف <code>CROSS APPLY</code> عن <code>JOIN</code>، وهل أداؤها أحسن.
</p>

<p>
	يختار الاستعلام الأول في الشيفرة التالية البيانات من جدول الأقسام، ثمّ يستخدم <code>OUTER APPLY</code> لتقييم جدول الموظفين نسبة إلى كلّ سجل من سجلّات جدول الأقسام. تُعطى قيم الصفوف التي ليس لها مُطابق في جدول الموظفين القيمة المعدومة <code>NULL</code>، كما هو حال الصفّين 5 و 6.
</p>

<p>
	يستخدم الاستعلام الثاني الضم الخارجي اليساري <code>LEFT OUTER JOIN</code> بين جدول الأقسام وجدول الموظفين. وكما هو متوقع، يعيد الاستعلام كافّة الصفوف من جدول الأقسام؛ بما فيها الصفوف التي ليس لها مُطابق في جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_55" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
OUTER APPLY </span><span class="pun">(</span><span class="pln">
    SELECT </span><span class="pun">*</span><span class="pln">
    FROM </span><span class="typ">Employee</span><span class="pln"> E
    WHERE E</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> A
GO
SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
LEFT OUTER JOIN </span><span class="typ">Employee</span><span class="pln"> E
    ON D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> E</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln">
GO</span></pre>

<p>
	رغم أنّ الاستعلامين أعلاه يعيدان المعلومات نفسها، فإنّ خطة التنفيذ تختلف بعض الشيء. بيْد أنّه لن يكون هناك اختلاف يُذكر في الأداء.
</p>

<p>
	في بعض الحالات، يكون استخدام المعامل <code>APPLY</code> ضروريًا. في المثال التالي، سننشئ دالة جدولية (table-valued function)، تقبل الحقل <code>DepartmentID</code> كمعامل، وتعيد جميع الموظفين المنتمين إلى القسم ذي المعرّف <code>DepartmentID</code>. يختار الاستعلام التالي البيانات من الجدول <code>Department</code> ويستخدم <code>CROSS APPLY</code> مع الدالة التي أنشأناها. يمرَّر الحقل <code>DepartmentID</code> من كل صفّ من الجدول الخارجي - outer table - (أي الجدول Department)، ثمّ يطبّق الدالة على كلّ صف بشكل يماثل الاستعلامات الفرعية المرتبطة (correlated subquery).
</p>

<p>
	يستخدم الاستعلام الثاني <code>OUTER APPLY</code> بدلاً من <code>CROSS APPLY</code>، وبالتالي، فعلى عكس التطبيق المتقاطع <code>CROSS APPLY</code> الذي لا يعيد إلّا البيانات المرتبطة (correlated data)، يعيد التطبيق الخارجي <code>OUTER APPLY</code> البيانات غير المرتبطة أيضًا، مع وضع القيم المعدومة (NULLs) في الأعمدة غير الموجودة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_57" style="">
<span class="pln">CREATE FUNCTION dbo</span><span class="pun">.</span><span class="pln">fn_GetAllEmployeeOfADepartment </span><span class="pun">(</span><span class="lit">@DeptID</span><span class="pln"> AS </span><span class="kwd">int</span><span class="pun">)</span><span class="pln">
RETURNS TABLE
AS
    RETURN
    </span><span class="pun">(</span><span class="pln">
    SELECT
       </span><span class="pun">*</span><span class="pln">
    FROM </span><span class="typ">Employee</span><span class="pln"> E
    WHERE E</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">@DeptID</span><span class="pln">
    </span><span class="pun">)</span><span class="pln">
GO
SELECT
    </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
CROSS APPLY dbo</span><span class="pun">.</span><span class="pln">fn_GetAllEmployeeOfADepartment</span><span class="pun">(</span><span class="pln">D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pun">)</span><span class="pln">
GO
SELECT
    </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Department</span><span class="pln"> D
OUTER APPLY dbo</span><span class="pun">.</span><span class="pln">fn_GetAllEmployeeOfADepartment</span><span class="pun">(</span><span class="pln">D</span><span class="pun">.</span><span class="typ">DepartmentID</span><span class="pun">)</span><span class="pln">
GO</span></pre>

<p>
	قد يتبادر إلى ذهنك السؤال التالي: هل يمكننا استخدام عمليّة ضمّ بسيطة بدلاً من استخدام الاستعلامات أعلاه؟ الجواب هو "لا"، إذا استبدلت CROSS / OUTER APPLY في الاستعلامات أعلاه بـعمليّات الضمّ INNER JOIN أو LEFT OUTER JOIN، وحدّدت العبارة <code>ON</code> (مثلًا 1 = 1)، ثمّ نفّذت الاستعلام، فسيُطرح الخطأ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1058_59" style="">
<span class="typ">The</span><span class="pln"> multi</span><span class="pun">-</span><span class="pln">part identifier </span><span class="str">"D.DepartmentID"</span><span class="pln"> could </span><span class="kwd">not</span><span class="pln"> be bound</span><span class="pun">.</span></pre>

<p>
	ذلك أنّه في عمليّات الضمّ، يكون سياق تنفيذ الاستعلام الخارجي مختلفًا عن سياق تنفيذ الدالة (أو الجدول المشتق - derived table)، ولا يمكنك تمرير قيمة أو متغيّر من الاستعلام الخارجي إلى الدالة كمعامل. لهذا يجب استخدام المعامل <code>APPLY</code> في مثل هذه الاستعلامات.
</p>

<p>
	ترجمة -وبتصرّف- للفصول من 23 إلى 28 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AD%D8%B0%D9%81-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%88%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r852/" rel="">حذف الجداول وقواعد البيانات في SQL</a>
	</li>
	<li>
		المقال سابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/" rel="">تحديث الجداول في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">851</guid><pubDate>Sat, 11 Apr 2020 13:00:00 +0000</pubDate></item><item><title>&#x62A;&#x62D;&#x62F;&#x64A;&#x62B; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/7.jpg.44712f1581fbed2f494315a4cf3612c7.jpg" /></p>

<p>
	تستعرض هذه المقالة كيفية تحديث قواعد البيانات، وكيفية إنشاء قواعد بيانات وجداول ودوال جديدة.
</p>

<h2>
	التحديث عبر UPDATE
</h2>

<p>
	تُستخدم الكلمة المفتاحية <code>UPDATE</code> لتحديث بيانات الجداول.
</p>

<h3>
	تحديث جدول من بيانات جدول آخر
</h3>

<p>
	تملأ الأمثلة الموضحة أدناه الحقل <code>‎PhoneNumber‎</code> لأي موظف يكون أيضًا عميلًا <code>‎Customer‎</code>، وليس له حاليًا رقم هاتف في جدول الموظفين <code>‎Employees‎</code>.
</p>

<p>
	(تستخدم الأمثلة التالية جدولي الموظفين Employees والعملاء Customers)
</p>

<ul>
<li>
		SQL القياسية
	</li>
</ul>
<p>
	يحدّث المثال التالي قاعدة البيانات باستخدام استعلام فرعي مربوط (correlated subquery):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_7" style="">
<span class="pln">UPDATE
    </span><span class="typ">Employees</span><span class="pln">
SET </span><span class="typ">PhoneNumber</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
   </span><span class="pun">(</span><span class="pln">SELECT
         c</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pln">
   FROM
         </span><span class="typ">Customers</span><span class="pln"> c
   WHERE
         c</span><span class="pun">.</span><span class="typ">FName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">FName</span><span class="pln">
         AND c</span><span class="pun">.</span><span class="typ">LName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">LName</span><span class="pun">)</span><span class="pln">
WHERE </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pln"> IS NULL</span></pre>

<ul>
<li>
		SQL:2003
	</li>
</ul>
<p>
	تحديث باستخدام <code>‎MERGE‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_9" style="">
<span class="pln">MERGE INTO
    </span><span class="typ">Employees</span><span class="pln"> e
USING
    </span><span class="typ">Customers</span><span class="pln"> c
ON
    e</span><span class="pun">.</span><span class="typ">FName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">Fname</span><span class="pln">
   AND e</span><span class="pun">.</span><span class="typ">LName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">LName</span><span class="pln">
   AND e</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pln"> IS NULL
WHEN MATCHED THEN
  UPDATE
       SET </span><span class="typ">PhoneNumber</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">PhoneNumber</span></pre>

<ul>
<li>
		SQL Server
	</li>
</ul>
<p>
	تحديث باستخدام <code>‎INNER JOIN‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_11" style="">
<span class="pln">UPDATE
    </span><span class="typ">Employees</span><span class="pln">
SET
    </span><span class="typ">PhoneNumber</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pln">
FROM
    </span><span class="typ">Employees</span><span class="pln"> e
INNER JOIN </span><span class="typ">Customers</span><span class="pln"> c
 ON e</span><span class="pun">.</span><span class="typ">FName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">FName</span><span class="pln">
 AND e</span><span class="pun">.</span><span class="typ">LName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">LName</span><span class="pln">
WHERE
    </span><span class="typ">PhoneNumber</span><span class="pln"> IS NULL</span></pre>

<h3>
	تعديل القيم الحالية
</h3>

<p>
	يستخدم هذا المثال "الجدول Car" من <a href="%D8%B1%D8%A7%D8%A8%D8%B7" rel="">الفصل 1</a>.
</p>

<p>
	تتيح لك SQL إمكانية استخدام القيم القديمة في عمليات التحديث. في المثال التالي، تُزاد قيمة <code>‎TotalCost‎</code> بمقدار 100 في الصفين ذوي المعرّفين 3 و4:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_13" style="">
<span class="pln">UPDATE </span><span class="typ">Cars</span><span class="pln">
SET </span><span class="typ">TotalCost</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TotalCost</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">100</span><span class="pln">
WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="kwd">or</span><span class="pln"> </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span></pre>

<ul>
<li>
		زِيدَت قيمة <code>TotalCost</code> الخاصّة بالسيارة 3 من 100 إلى 200.
	</li>
	<li>
		زيدت قيمة <code>TotalCost</code> الخاصّة بالسيارة 4 من 1254 إلى 1354.
	</li>
</ul>
<p>
	يمكن اشتقاق القيمة الجديدة للعمود من قيمته السابقة، أو من قيمة أيّ عمود آخر في الجدول أو من الجدول المضموم (joined table) نفسه.
</p>

<h3>
	تحديث صفوف معيّنة
</h3>

<p>
	تعيّن الشيفرة أدناه قيمة حالة الصف ذي المُعرٍّف 4 إلى <code>READY</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_15" style="">
<span class="pln">UPDATE
    </span><span class="typ">Cars</span><span class="pln">
SET
    </span><span class="typ">Status</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span><span class="pln">
WHERE
    </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span></pre>

<p>
	تقيّم عبارة <code>‎WHERE‎</code> شرطًا منطقيًا في كل صفّ. إذا استوفى الصف ذلك الشرط، فستُحدّث قيمته. خلاف ذلك، يظل الصف دون تغيير.
</p>

<h3>
	تحديث جميع الصفوف
</h3>

<p>
	يعيّن المثال التالي العمود "status" الخاص بجميع صفوف الجدول "Cars" إلى القيمة "READY"، التحديث يشمل جميع الصفوف بسبب غياب العبارة <code>‎WHERE‎</code> (التي تصفّي الصفوف).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_17" style="">
<span class="pln">UPDATE </span><span class="typ">Cars</span><span class="pln">
SET </span><span class="typ">Status</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span></pre>

<h3>
	التقاط السجلات المُحدّثة
</h3>

<p>
	قد ترغب في بعض الأحيان في التقاط السجلات التي حُدِّثت للتو. يمكنك ذلك عبر الصياغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_19" style="">
<span class="pln">CREATE TABLE </span><span class="com">#TempUpdated(ID INT)</span><span class="pln">
</span><span class="typ">Update</span><span class="pln"> </span><span class="typ">TableName</span><span class="pln"> SET </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">42</span><span class="pln">
    OUTPUT inserted</span><span class="pun">.</span><span class="pln">ID INTO </span><span class="com">#TempUpdated</span><span class="pln">
    WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">50</span></pre>

<h2>
	إنشاء قاعدة بيانات عبر CREATE
</h2>

<p>
	يمكن إنشاء قاعدة بيانات باستخدام أمر SQL التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_21" style="">
<span class="pln">CREATE DATABASE myDatabase</span><span class="pun">;</span></pre>

<p>
	سينتج عن الشيفرة أعلاه قاعدة بيانات فارغة باسم <code>myDatabase</code>، والتي يمكن أن تضيف جداول إليها باستخدام العبارة <code>CREATE TABLE</code>.
</p>

<h2>
	إنشاء جدول عبر CREATE TABLE
</h2>

<p>
	تُستخدم العبارة <code>CREATE TABLE</code> لإنشاء جدول جديد في قاعدة البيانات. يتألّف تعريف الجدول من قائمة من الأعمدة وأنواعها، إضافة إلى أيّ قيود تكاملية (integrity constraints).
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				المعامل
			</th>
			<th>
				الشرح
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				tableName
			</td>
			<td>
				اسم الجدول
			</td>
		</tr>
<tr>
<td>
				columns
			</td>
			<td>
				تحتوي راقمة (enumeration) لجميع الأعمدة الموجودة في الجدول
			</td>
		</tr>
</tbody>
</table>
<h3>
	إنشاء جدول عبر Select
</h3>

<p>
	يمكنك إنشاء نسخة مكرّرة من جدول معيّن على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_24" style="">
<span class="pln">CREATE TABLE </span><span class="typ">ClonedEmployees</span><span class="pln"> AS SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pun">;</span></pre>

<p>
	يمكنك استخدام أيّ من الميزات الأخرى لعبارة <code>SELECT</code> لتعديل البيانات قبل نقلها إلى الجدول الجديد.
</p>

<p>
	تُنشأ أعمدة الجدول الجديد تلقائيًا انطلاقًا من الصفوف المُختارة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_26" style="">
<span class="pln">CREATE TABLE </span><span class="typ">ModifiedEmployees</span><span class="pln"> AS
SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> CONCAT</span><span class="pun">(</span><span class="typ">FName</span><span class="pun">,</span><span class="str">" "</span><span class="pun">,</span><span class="typ">LName</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">FullName</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span></pre>

<h3>
	إنشاء جدول جديد
</h3>

<p>
	تنشئ الشيفرة التالية جدولًا بسيطًا باسم (<code>‎Employees‎</code>)، يتألّف من معرّف، واسم الموظف الأول، واسم العائلة، إضافة إلى رقم الهاتف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_28" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> identity</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> primary key </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FName</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PhoneNumber</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	هذا المثال خاص بالإصدار <a href="https://ar.wikipedia.org/wiki/%D8%AA%D9%8A-%D8%B3%D9%83%D9%8A%D9%88%D9%84" rel="external nofollow">Transact-SQL</a>،
</p>

<p>
	تنشئ العبارة <code>CREATE TABLE</code> جدولًا جديدًا وتضيفه إلى قاعدة البيانات، تُتبع هذه العبارة باسم الجدول (Employees). ثم تعقبه قائمة بأسماء الأعمدة وخصائصها، مثل المعرّف ID.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_30" style="">
<span class="typ">Id</span><span class="pln"> </span><span class="kwd">int</span><span class="pln"> identity</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">not</span><span class="pln"> </span><span class="kwd">null</span></pre>

<p>
	<strong>شرح الشيفرة</strong>
</p>

<table>
<thead><tr>
<th>
				القيمة
			</th>
			<th>
				شرح
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Id
			</td>
			<td>
				اسم العمود
			</td>
		</tr>
<tr>
<td>
				int
			</td>
			<td>
				نوع البيانات
			</td>
		</tr>
<tr>
<td>
				identity(1,1)
			</td>
			<td>
				ينصّ على أنّ قيم العمود ستُنشأ تلقائيًا، بداية من 1، ثم تزداد بمقدار 1 في كل صف جديد
			</td>
		</tr>
<tr>
<td>
				primary key
			</td>
			<td>
				تنص على أنّ قيم هذا العمود فريدة وغير مكرّرة
			</td>
		</tr>
<tr>
<td>
				not null
			</td>
			<td>
				تنص على أنّ قيم العمود لا يمكن أن تكون معدومة
			</td>
		</tr>
</tbody>
</table>
<h3>
	إنشاء جدول باستخدام مفتاح خارجي FOREIGN KEY
</h3>

<p>
	ينشئ المثال أدناه جدولًا للموظفين <code>‎Employees‎</code> يحتوي مرجعًا إلى جدول آخر، وهو جدول المدن <code>‎Cities‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_32" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Cities</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">CityID</span><span class="pln"> INT IDENTITY</span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Name</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Zip</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> NOT NULL
</span><span class="pun">);</span><span class="pln">
CREATE TABLE </span><span class="typ">Employees</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">EmployeeID</span><span class="pln"> INT IDENTITY </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">1</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">20</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PhoneNumber</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">CityID</span><span class="pln"> INT FOREIGN KEY REFERENCES </span><span class="typ">Cities</span><span class="pun">(</span><span class="typ">CityID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></pre>

<p>
	يستعرض الرسم التالي مخططًا توضيحيًا للعلاقة بين قاعدتي البيانات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35608" href="https://academy.hsoub.com/uploads/monthly_2020_03/ch7t3.png.4be3da64bda1591f25451e2adc994cf5.png" rel=""><img alt="ch7t3.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35608" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/ch7t3.png.4be3da64bda1591f25451e2adc994cf5.png"></a>
</p>

<p>
	لاحظ أنّه في السطر الأخير من الشيفرة، يشير العمود <code>‎CityID‎</code> من الجدول <code>‎Employees‎</code> إلى العمود <code>‎CityID‎</code> في الجدول <code>‎Cities‎</code>:
</p>

<pre class="ipsCode">
CityID INT FOREIGN KEY REFERENCES Cities(CityID)
</pre>

<p>
	<strong>شرح الشيفرة</strong>
</p>

<table>
<thead><tr>
<th>
				القمة
			</th>
			<th>
				شرح
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				CityID
			</td>
			<td>
				اسم العمود
			</td>
		</tr>
<tr>
<td>
				int
			</td>
			<td>
				نوع العمود
			</td>
		</tr>
<tr>
<td>
				FOREIGN KEY
			</td>
			<td>
				إنشاء المفتاح الخارجي (اختياري)
			</td>
		</tr>
<tr>
<td>
				REFERENCES Cities(CityID)
			</td>
			<td>
				إنشاء مرجع إلى العمود CityID من جدول المدن
			</td>
		</tr>
</tbody>
</table>
<p>
	<strong>تنبيه</strong>: لا يجوز إنشاء مرجع إلى جدول غير موجود في قاعدة البيانات. عليك أن تنشئ الجدول <code>‎Cities‎</code> أولا، ثم تنشئ الجدول <code>‎Employees‎</code> عقب ذلك. إذا فعلت ذلك بترتيب معكوس، فسيُطرَح خطأ.
</p>

<h3>
	تكرار جدول Duplicate a table
</h3>

<p>
	يمكنك تكرار جدول معيّن عبر الصياغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_35" style="">
<span class="pln">CREATE TABLE newtable LIKE oldtable</span><span class="pun">;</span><span class="pln">
INSERT newtable SELECT </span><span class="pun">*</span><span class="pln"> FROM oldtable</span><span class="pun">;</span></pre>

<h3>
	إنشاء جدول مؤقت
</h3>

<p>
	يمكن إنشاء جدول مؤقت خاص بالجلسة (session) الحالية. لكنّ الصياغة تختلف بحسب إصدار SQL:
</p>

<ul>
<li>
		PostgreSQL و SQLite
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_37" style="">
<span class="pln">CREATE TEMP TABLE </span><span class="typ">MyTable</span><span class="pun">(...);</span></pre>

<ul>
<li>
		SQL Server
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_39" style="">
<span class="pln">CREATE TABLE </span><span class="com">#TempPhysical(...);</span></pre>

<p>
	يمكن كذلك إنشاء جدول مؤقت مرئي للجميع، وليس حصرًا على الجلسة الحالية على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_41" style="">
<span class="pln">CREATE TABLE </span><span class="com">##TempPhysicalVisibleToEveryone(...);</span></pre>

<p>
	ويمكن أيضًا إنشاء جدول في الذاكرة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_43" style="">
<span class="pln">DECLARE </span><span class="lit">@TempMemory</span><span class="pln"> TABLE</span><span class="pun">(...);</span></pre>

<h2>
	إنشاء دالة عبر CREATE FUNCTION
</h2>

<p>
	تتيح SQL إنشاء دالة جديدة.
</p>

<p>
	ينشئ المثال التالي دالة باسم <code>FirstWord</code>، والتي تقبل معاملًا من النوع <code>varchar</code>، وتُعيد قيمة من النوع نفسه.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2496_45" style="">
<span class="pln">CREATE FUNCTION </span><span class="typ">FirstWord</span><span class="pln"> </span><span class="pun">(</span><span class="lit">@input</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">1000</span><span class="pun">))</span><span class="pln">
RETURNS varchar</span><span class="pun">(</span><span class="lit">1000</span><span class="pun">)</span><span class="pln">
AS
</span><span class="kwd">BEGIN</span><span class="pln">
     DECLARE </span><span class="lit">@output</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">1000</span><span class="pun">)</span><span class="pln">
     SET </span><span class="lit">@output</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> SUBSTRING</span><span class="pun">(</span><span class="lit">@input</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0</span><span class="pun">,</span><span class="pln"> CASE CHARINDEX</span><span class="pun">(</span><span class="str">' '</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@input</span><span class="pun">)</span><span class="pln">
         WHEN </span><span class="lit">0</span><span class="pln"> THEN LEN</span><span class="pun">(</span><span class="lit">@input</span><span class="pun">)</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
         ELSE CHARINDEX</span><span class="pun">(</span><span class="str">' '</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@input</span><span class="pun">)</span><span class="pln">
     </span><span class="kwd">END</span><span class="pun">)</span><span class="pln">
     RETURN </span><span class="lit">@output</span><span class="pln">
</span><span class="kwd">END</span></pre>

<p>
	<strong>شرح الشيفرة</strong>
</p>

<table>
<thead><tr>
<th>
				الوسيط
			</th>
			<th>
				شرح
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				function_name
			</td>
			<td>
				اسم الدالة
			</td>
		</tr>
<tr>
<td>
				list_of_paramenters
			</td>
			<td>
				معاملات الدالة
			</td>
		</tr>
<tr>
<td>
				return_data_type
			</td>
			<td>
				نوع القيمة المُعادة
			</td>
		</tr>
<tr>
<td>
				function_body
			</td>
			<td>
				متن الدالة
			</td>
		</tr>
<tr>
<td>
				scalar_expression
			</td>
			<td>
				القيمة العددية المُعادة من الدالة
			</td>
		</tr>
</tbody>
</table>
<p>
	ترجمة -وبتصرّف- للفصول من 19 إلى 22 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%B9%D8%A7%D9%84%D8%AC%D8%A9-%D8%A7%D9%84%D8%A3%D8%AE%D8%B7%D8%A7%D8%A1-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D8%B9%D9%84%D9%89-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r851/" rel="">معالجة الأخطاء والتعديل على قواعد البيانات في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">الدمج بين الجداول في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">850</guid><pubDate>Wed, 08 Apr 2020 13:05:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62F;&#x645;&#x62C; &#x628;&#x64A;&#x646; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/6.jpg.4a0b5dcf2d5ede4ae67de56a0f0146a1.jpg" /></p>

<p>
	تدمج العبارة <code>JOIN</code> البيانات من جدولين، وتعيد مجموعة مختلطة من الأعمدة من كلا الجدولين، وذلك حسب نوع الضمّ المُستخدم، ومعاييره (كيفية ربط الصفوف من كلا الجدولين).
</p>

<p>
	يمكن ضمّ جدولٍ إلى نفسه، أو بأيّ جدول آخر. وإذا كانت هناك حاجة للوصول إلى معلومات من أكثر من جدولين، فيمكن استخدام الضمّ عدّة مرّات في عبارة <code>FROM</code>.
</p>

<h3>
	الضمّ الذاتي Self Join
</h3>

<p>
	يمكن ضمّ جدول إلى نفسه، بحيث تتطابق الصفوف مع بعضها البعض وفق شروط معينة. في مثل هذه الحالة، يجب استخدام الكُنى (aliases) للتمييز بين العناصر المكرّرة من الجدول.
</p>

<p>
	في المثال التالي، لكلّ موظّف في جدول الموظّفين <code>Employees</code>، يُعاد سجلّ يحتوي الاسم الأول للموظّف، والاسم الأول لمديره. ولمّا كان المدراء هم أيضًا موظفين، فسنضمّ الجدول إلى نفسه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_7" style="">
<span class="pln">SELECT
    e</span><span class="pun">.</span><span class="typ">FName</span><span class="pln"> AS </span><span class="str">"Employee"</span><span class="pun">,</span><span class="pln">
    m</span><span class="pun">.</span><span class="typ">FName</span><span class="pln"> AS </span><span class="str">"Manager"</span><span class="pln">
FROM 
    </span><span class="typ">Employees</span><span class="pln"> e
JOIN 
    </span><span class="typ">Employees</span><span class="pln"> m
   ON e</span><span class="pun">.</span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> m</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	سيعيد هذا الاستعلام البيانات التالية:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Employee
			</th>
			<th>
				Manager
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				John
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Michael
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Johnathon
			</td>
			<td>
				John
			</td>
		</tr>
</tbody>
</table>
<p>
	<strong>شرح الاستعلام</strong>
</p>

<p>
	يحتوي الجدول الأصلي على هذه السجلات:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				HireDate
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
</tbody>
</table>
<p>
	الخطوة الأولى في تنفيذ الاستعلام هي إجراء <a href="https://ar.wikipedia.org/wiki/%D8%AC%D8%AF%D8%A7%D8%A1_%D8%AF%D9%8A%D9%83%D8%A7%D8%B1%D8%AA%D9%8A" rel="external nofollow">جداء ديكارتي</a> لجميع السجلات في الجداول المستخدمة في عبارة <code>FROM</code>. في حالتنا هذه، استخدمنا جدول الموظفين مرّتين، لذا سيبدو الجدول الوسيط كما يلي (أزلنا الحقول غير المستخدمة في المثال):
</p>

<table>
<thead><tr>
<th>
				e.Id
			</th>
			<th>
				e.FName
			</th>
			<th>
				e.ManagerId
			</th>
			<th>
				m.Id
			</th>
			<th>
				m.FName
			</th>
			<th>
				m.ManagerId
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
		</tr>
</tbody>
</table>
<p>
	الخطوة التالية هي ترشيح السجلات، والإبقاء على السجلات التي تفي بشرط <strong>الضمّ</strong> وحسب، أي سجلات الجدول <code>‎e‎</code> التي يساوي الحقل <code>‎ManagerId‎</code> خاصتها الحقلَ <code>‎Id‎</code> في الجدول <code>‎m‎</code>:
</p>

<table>
<thead><tr>
<th>
				e.Id
			</th>
			<th>
				e.FName
			</th>
			<th>
				e.ManagerId
			</th>
			<th>
				m.Id
			</th>
			<th>
				m.FName
			</th>
			<th>
				m.ManagerId
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				NULL
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				2
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				1
			</td>
		</tr>
</tbody>
</table>
<p>
	بعد ذلك، تُقيّم كل التعبيرات المستخدمة في عبارة <code>SELECT</code> لإعادة الجدول التالي:
</p>

<table>
<thead><tr>
<th>
				e.FName
			</th>
			<th>
				m.FName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				John
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Michael
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Johnathon
			</td>
			<td>
				John
			</td>
		</tr>
</tbody>
</table>
<p>
	أخيرًا، يُستبدل اسما العمودين <code>‎e.FName‎</code> و <code>‎m.FName‎</code> بكُنيتيهما:
</p>

<table>
<thead><tr>
<th>
				Employee
			</th>
			<th>
				Manager
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				John
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Michael
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Johnathon
			</td>
			<td>
				John
			</td>
		</tr>
</tbody>
</table>
<h3>
	الاختلاف بين الضم الداخلي والخارجي
</h3>

<p>
	هناك عدّة أنواع من الضمّ في SQL، وتختلف تلك الأنواع عن بعضها من حيث ما إذا كانت الصفوف التي (لا) تحقّق الشرط ستُضمّ أم لا.
</p>

<p>
	هذه بعض أهمّ أنواع الضمّ: <code>‎INNER JOIN‎</code> و <code>‎LEFT‎ OUTER‎</code>‎JOIN<code>و</code>RIGHT OUTER JOIN‎<code>و</code>‎FULL OUTER ‎JOIN‎<code>(الكلمتان المفتَاحيتان</code>‎INNER‎<code>و</code>‎OUTER‎` اختياريتان).
</p>

<p>
	يوضّح الشكل أدناه الاختلافات بين مختلف أنواع الضمّ: تمثل المنطقة الزرقاء النتائج المُعادة من عملية الضمّ، فيما تمثّل المنطقة البيضاء النتائج التي لن تعيدها عملية الضمّ.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35597" href="https://academy.hsoub.com/uploads/monthly_2020_03/3bs7C.png.76e309b25c7bfc5605f273a281ac95f8.png" rel=""><img alt="3bs7C.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35597" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/3bs7C.thumb.png.452ca484fa2a5bc2c9082609970d4280.png"></a>
</p>

<p>
	وهذه صورة لتمثيل الضمّ المتقاطع (Join SQL)
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35599" href="https://academy.hsoub.com/uploads/monthly_2020_03/cross-join-round.png.7b4893aa1d06ecd4e3cb64672567827d.png" rel=""><img alt="cross-join-round.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35599" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/cross-join-round.png.7b4893aa1d06ecd4e3cb64672567827d.png"></a>
</p>

<p>
	<a href="http://www.w3resource.com/sql/joins/cross-join.php" rel="external nofollow">مصدر الصورة</a>
</p>

<p>
	على سبيل المثال، إليك الجدولين التاليين:
</p>

<pre class="ipsCode" id="ips_uid_2706_9">
A    B
-    -
1    3
2    4
3    5
4    6
</pre>

<p>
	لاحظ أنّ القيمتين (1،2) حصريتان للجدول A، أمّا القيمتان (3،4) فمُشتركتان، و القيمتان (5،6) حصريتان لـ B.
</p>

<p>
	<strong>الضمّ الداخلي</strong>
</p>

<p>
	يعيد الضم الداخلي تقاطع الجدولين، أي الصفوف المشترك بينهما:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_11" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> a INNER JOIN b on a</span><span class="pun">.</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> b</span><span class="pun">.</span><span class="pln">b</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">select</span><span class="pln"> a</span><span class="pun">.*,</span><span class="pln">b</span><span class="pun">.*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> a</span><span class="pun">,</span><span class="pln">b </span><span class="kwd">where</span><span class="pln"> a</span><span class="pun">.</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> b</span><span class="pun">.</span><span class="pln">b</span><span class="pun">;</span><span class="pln">
a </span><span class="pun">|</span><span class="pln"> b
</span><span class="pun">--+--</span><span class="pln">
</span><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="lit">3</span><span class="pln">
</span><span class="lit">4</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="lit">4</span></pre>

<p>
	<strong>الضم الخارجي اليساري Left outer join</strong>
</p>

<p>
	يعيد الضم الخارجي اليساري جميع صفوف A، بالإضافة إلى الصفوف المشتركة مع B:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_13" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> a LEFT OUTER JOIN b on a</span><span class="pun">.</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> b</span><span class="pun">.</span><span class="pln">b</span><span class="pun">;</span><span class="pln">
a </span><span class="pun">|</span><span class="pln">  b
</span><span class="pun">--+-----</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
</span><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
</span><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">3</span><span class="pln">
</span><span class="lit">4</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">4</span></pre>

<p>
	<strong>الضم الخارجي اليميني Right outer join</strong>
</p>

<p>
	وبالمثل، يعيد الضمّ الخارجي اليميني كل صفوف B، بالإضافة إلى الصفوف المشتركة في A:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_15" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> a RIGHT OUTER JOIN b on a</span><span class="pun">.</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> b</span><span class="pun">.</span><span class="pln">b</span><span class="pun">;</span><span class="pln">
a    </span><span class="pun">|</span><span class="pln">  b
</span><span class="pun">-----+----</span><span class="pln">
</span><span class="lit">3</span><span class="pln">    </span><span class="pun">|</span><span class="pln">  </span><span class="lit">3</span><span class="pln">
</span><span class="lit">4</span><span class="pln">    </span><span class="pun">|</span><span class="pln">  </span><span class="lit">4</span><span class="pln">
</span><span class="kwd">null</span><span class="pln"> </span><span class="pun">|</span><span class="pln">  </span><span class="lit">5</span><span class="pln">
</span><span class="kwd">null</span><span class="pln"> </span><span class="pun">|</span><span class="pln">  </span><span class="lit">6</span></pre>

<p>
	<strong>الضمّ الخارجي التام Full outer join</strong>
</p>

<p>
	يعيد الضمّ الخارجي التام اتحاد A و B، أي جميع الصفوف الموجودة في A وجميع الصفوف الموجودة في B. إذا كانت هناك بيانات في A بدون بيانات مقابلة في B، فسيكون الجزء الخاص بـ B معدوما (null). والعكس صحيح.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_17" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> a FULL OUTER JOIN b on a</span><span class="pun">.</span><span class="pln">a </span><span class="pun">=</span><span class="pln"> b</span><span class="pun">.</span><span class="pln">b</span><span class="pun">;</span><span class="pln">
a   </span><span class="pun">|</span><span class="pln">  b
</span><span class="pun">-----+-----</span><span class="pln">
</span><span class="lit">1</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
</span><span class="lit">2</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="kwd">null</span><span class="pln">
</span><span class="lit">3</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">3</span><span class="pln">
</span><span class="lit">4</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">4</span><span class="pln">
</span><span class="kwd">null</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">6</span><span class="pln">
</span><span class="kwd">null</span><span class="pln"> </span><span class="pun">|</span><span class="pln">    </span><span class="lit">5</span></pre>

<h3>
	اصطلاحات الضمّ JOIN Terminology
</h3>

<p>
	لنفترض أنّ لدينا جدولين A و B، وأنّ بعض صفوفِهما متطابقة (وفق شرط JOIN):
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35605" href="https://academy.hsoub.com/uploads/monthly_2020_03/TbHy6.png.142920c9a21c68b2e5867ba0dd7cf8ea.png" rel=""><img alt="TbHy6.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35605" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/TbHy6.thumb.png.88620f73200f8d55b4806bcc33192ed7.png"></a>
</p>

<p>
	هناك عدّة أنواع مختلفة من الضمّ يمكن استخدامها لأجل تضمين أو استبعاد الصفوف التي (لا) تحقق شرط الضمّ في كلا الجانبين.
</p>

<p>
	تستخدم الأمثلة أدناه البيانات التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_19" style="">
<span class="pln">CREATE TABLE A </span><span class="pun">(</span><span class="pln">
    X varchar</span><span class="pun">(</span><span class="lit">255</span><span class="pun">)</span><span class="pln"> PRIMARY KEY
</span><span class="pun">);</span><span class="pln">
CREATE TABLE B </span><span class="pun">(</span><span class="pln">
    Y varchar</span><span class="pun">(</span><span class="lit">255</span><span class="pun">)</span><span class="pln"> PRIMARY KEY
</span><span class="pun">);</span><span class="pln">
INSERT INTO A VALUES
    </span><span class="pun">(</span><span class="str">'Amy'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'John'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Lisa'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Marco'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Phil'</span><span class="pun">);</span><span class="pln">
INSERT INTO B VALUES
    </span><span class="pun">(</span><span class="str">'Lisa'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Marco'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Phil'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Tim'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'Vincent'</span><span class="pun">);</span></pre>

<p>
	<strong>الضمّ الداخلي Inner Join</strong>
</p>

<p>
	يجمع الضمّ الداخلي بين الصفوف اليسرى واليمنى المتطابقة.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35601" href="https://academy.hsoub.com/uploads/monthly_2020_03/j4eti.png.b5239f1d9b12983d9447cf4f1c35d141.png" rel=""><img alt="j4eti.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35601" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/j4eti.png.b5239f1d9b12983d9447cf4f1c35d141.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_21" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A JOIN B ON X </span><span class="pun">=</span><span class="pln"> Y</span><span class="pun">;</span><span class="pln">
X      Y
</span><span class="pun">------</span><span class="pln"> </span><span class="pun">-----</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">   </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">  </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">   </span><span class="typ">Phil</span></pre>

<p>
	<strong>الضم الخارجي اليساري Left outer join</strong>
</p>

<p>
	يُسمّى اختصارًا الضمّ اليساري. ويجمع بين الصفوف اليسرى واليمنى التي تحقّق الشرط، مع تضمين الصفوف اليسرى التي لا تحقّق الشرط.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35598" href="https://academy.hsoub.com/uploads/monthly_2020_03/5UjhU.png.52a59a94e9b3020a4d8ea1211e42163c.png" rel=""><img alt="5UjhU.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35598" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/5UjhU.png.52a59a94e9b3020a4d8ea1211e42163c.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4882_7" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A LEFT JOIN B ON X </span><span class="pun">=</span><span class="pln"> Y</span><span class="pun">;</span><span class="pln">
X         Y
</span><span class="pun">-----</span><span class="pln">     </span><span class="pun">-----</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       NULL
</span><span class="typ">John</span><span class="pln">      NULL
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Phil</span></pre>

<p>
	<strong>الضم الخارجي اليميني Right outer join</strong>
</p>

<p>
	يُسمّى اختصارًا الضمّ الأيمن. ويجمع بين الصفوف اليسرى واليمنى التي تحقّق الشرط، مع تضمين الصفوف اليمنى التي لا تحقّق الشرط.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35602" href="https://academy.hsoub.com/uploads/monthly_2020_03/Lrg4z.png.fb7dbb8187da67dc7167014293d491c9.png" rel=""><img alt="Lrg4z.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35602" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/Lrg4z.png.fb7dbb8187da67dc7167014293d491c9.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_27" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A RIGHT JOIN B ON X </span><span class="pun">=</span><span class="pln"> Y</span><span class="pun">;</span><span class="pln">
X          Y
</span><span class="pun">-----</span><span class="pln">      </span><span class="pun">-------</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">       </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">       </span><span class="typ">Phil</span><span class="pln">
NULL       </span><span class="typ">Tim</span><span class="pln">
NULL       </span><span class="typ">Vincent</span></pre>

<p>
	<strong>الضمّ الخارجي التام Full outer join</strong>
</p>

<p>
	يُسمّى اختصارًا الضمّ التام. وهو اتحاد لعمليتي الضم اليساري واليميني.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35607" href="https://academy.hsoub.com/uploads/monthly_2020_03/XCCMm.png.bf283e68a845f1c595ea8074d04671c3.png" rel=""><img alt="XCCMm.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35607" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/XCCMm.png.bf283e68a845f1c595ea8074d04671c3.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_29" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A FULL JOIN B ON X </span><span class="pun">=</span><span class="pln"> Y</span><span class="pun">;</span><span class="pln">
X          Y
</span><span class="pun">-----</span><span class="pln">      </span><span class="pun">-------</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">        NULL
</span><span class="typ">John</span><span class="pln">       NULL
</span><span class="typ">Lisa</span><span class="pln">       </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">       </span><span class="typ">Phil</span><span class="pln">
NULL       </span><span class="typ">Tim</span><span class="pln">
NULL       </span><span class="typ">Vincent</span></pre>

<p>
	<strong>الضمّ شبه اليساري</strong>
</p>

<p>
	يضمّ هذا النوع الصفوفَ اليُسرى التي تتطابق مع الصفوف اليمنى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35606" href="https://academy.hsoub.com/uploads/monthly_2020_03/UGEsN.png.a6d17d98fc9b2c5fff022a4f185fa292.png" rel=""><img alt="UGEsN.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35606" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/UGEsN.png.a6d17d98fc9b2c5fff022a4f185fa292.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_31" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A WHERE X IN </span><span class="pun">(</span><span class="pln">SELECT Y FROM B</span><span class="pun">);</span><span class="pln">
X
</span><span class="pun">-----</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span></pre>

<p>
	<strong>الضمّ شبه اليميني Right Semi Join</strong>
</p>

<p>
	يضمّ هذا النوع الصفوف اليمنى التي تطابق الصفوف اليسرى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35603" href="https://academy.hsoub.com/uploads/monthly_2020_03/OwH1z.png.530a84337628fde4a02fdde74e99a39a.png" rel=""><img alt="OwH1z.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35603" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/OwH1z.png.530a84337628fde4a02fdde74e99a39a.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_33" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM B WHERE Y IN </span><span class="pun">(</span><span class="pln">SELECT X FROM A</span><span class="pun">);</span><span class="pln">
Y
</span><span class="pun">-----</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span></pre>

<p>
	لا توجد صياغة للعبارة IN مُخصّصة للضمّ شبه اليساري أو شبه اليميني - كلّ ما عليك فعله هو تبديل مواضع الجدول في SQL.
</p>

<p>
	<strong>الضمّ شبه اليساري المعكوس Left Anti Semi Join</strong>
</p>

<p>
	يُضمِّن هذا النوع الصفوفَ اليُسرى التي <strong>لا</strong> تتطابق مع الصفوف اليمنى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35600" href="https://academy.hsoub.com/uploads/monthly_2020_03/I3KVl.png.678bead33f3749424598c7e545667e06.png" rel=""><img alt="I3KVl.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35600" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/I3KVl.png.678bead33f3749424598c7e545667e06.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_35" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A WHERE X NOT IN </span><span class="pun">(</span><span class="pln">SELECT Y FROM B</span><span class="pun">);</span><span class="pln">
X
</span><span class="pun">----</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">
</span><span class="typ">John</span></pre>

<p>
	<strong>تنبيه</strong>: استخدام <code>NOT IN</code> في الأعمدة التي تقبل القيم المعدومة <code>NULL</code> قد يسبّب بعض المشاكل (المزيد من التفاصيل <a href="http://stackoverflow.com/a/132402/533120" rel="external nofollow"> هنا</a>).
</p>

<p>
	<strong>الضمّ شبه اليميني المعكوس Right Anti Semi Join</strong>
</p>

<p>
	يُضمِّن هذا النوع الصفوف اليمنى التي <strong>لا</strong> تطابق الصفوف اليسرى.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="35604" href="https://academy.hsoub.com/uploads/monthly_2020_03/sPY3h.png.bfd4168c32f2c22571571dc09ec497b5.png" rel=""><img alt="sPY3h.png" class="ipsImage ipsImage_thumbnailed" data-fileid="35604" data-unique="data-unique" src="https://academy.hsoub.com/uploads/monthly_2020_03/sPY3h.png.bfd4168c32f2c22571571dc09ec497b5.png"></a>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_37" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM B WHERE Y NOT IN </span><span class="pun">(</span><span class="pln">SELECT X FROM A</span><span class="pun">);</span><span class="pln">
Y
</span><span class="pun">-------</span><span class="pln">
</span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">Vincent</span></pre>

<p>
	لا توجد صياغة للعبارة IN مخصّصة للضمّ شبه اليساري أو شبه اليميني المعكوس - كلّ ما عليك فعله هو تبديل مواضع الجدول في SQL.
</p>

<p>
	<strong>الضم المتقاطع Cross Join</strong>
</p>

<p>
	يُجري هذا النوع من الضمّ جداءً ديكارتيًا (Cartesian product) بين الصوف اليسرى والصفوف اليمنى.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_39" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A CROSS JOIN B</span><span class="pun">;</span><span class="pln">
X         Y
</span><span class="pun">-----</span><span class="pln">     </span><span class="pun">-------</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Phil</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Phil</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Phil</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Phil</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Phil</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Tim</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Vincent</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Vincent</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Vincent</span><span class="pln">
</span><span class="typ">Marco</span><span class="pln">     </span><span class="typ">Vincent</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Vincent</span></pre>

<p>
	يكافئ الضمّ المتقاطع ضمًّا داخليًا ذا شرط يتحقّق دائمًا، لذا سيعيد الاستعلام التالي النتيجة نفسها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_41" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A JOIN B ON </span><span class="lit">1</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	<strong>الضمّ الذاتي Self-Join</strong>
</p>

<p>
	يشير هذا النوع من الضم إلى ضمّ الجدول إلى نفسه. يمكن أن تكون عملية الضمّ الذاتي من أيّ نوع من أنواع الضمّ التي ناقشناها أعلاه. على سبيل المثال، هذا ضمّ ذاتي داخلي ( inner self-join):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4882_11" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM A A1 JOIN A A2 ON LEN</span><span class="pun">(</span><span class="pln">A1</span><span class="pun">.</span><span class="pln">X</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> LEN</span><span class="pun">(</span><span class="pln">A2</span><span class="pun">.</span><span class="pln">X</span><span class="pun">);</span><span class="pln">
X         X
</span><span class="pun">----</span><span class="pln">      </span><span class="pun">-----</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">John</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Lisa</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">John</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Lisa</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Phil</span><span class="pln">      </span><span class="typ">Marco</span><span class="pln">
</span><span class="typ">Amy</span><span class="pln">       </span><span class="typ">Phil</span></pre>

<p>
	<strong>الضمّ الخارجي اليساري Left Outer Join</strong>
</p>

<p>
	يضمن الضمّ الخارجي اليساري (المعروف أيضًا باسم الضمّ اليساري أو الضمّ الخارجي) تمثيل جميع صفوف الجدول الأيسر؛ وفي حال عدم وجود صفّ مطابق في الجدول الأيمن، فسيُعطى الحقل المقابل القيمةَ <code>‎NULL‎</code>.
</p>

<p>
	سيختار المثال التالي جميع الأقسام (departments) والأسماء الأولى للموظّفين الذين يعملون في تلك الأقسام. وستُعاد الأقسام التي لا تحتوي على أيّ موظفين، مع إعطاء اسم الموظف المقابل لها القيمة <code>NULL</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_45" style="">
<span class="pln">SELECT                    </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">FName</span><span class="pln">
FROM                       </span><span class="typ">Departments</span><span class="pln">
LEFT OUTER JOIN  </span><span class="typ">Employees</span><span class="pln">
ON                            </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">DepartmentId</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				Departments.Name
			</th>
			<th>
				Employees.FName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				HR
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				John
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				Johnathon
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				Michael
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				NULL
			</td>
		</tr>
</tbody>
</table>
<p>
	<strong>شرح الاستعلام</strong>
</p>

<p>
	يوجد جدولان في عبارة <code>FROM</code>، وهما:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				HireDate
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
</tbody>
</table>
<p>
	وهذا هو الجدول الثاني:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
		</tr>
</tbody>
</table>
<p>
	في المرحلة الأولى، يُنشأ جداء ديكارتي للجدولين، وينتج عنه جدول وسيط.
</p>

<p>
	<strong>يُغلَّظُ خطّ السجلات</strong> التي تفي بشرط الضمّ (والذي هو في هذه الحالة: <code>Departments.Id = Employees.DepartmentId</code>)؛ وتُمرَّر إلى المرحلة التالية من الاستعلام.
</p>

<p>
	لمّا كان هذا الضّمّ ضمًّا خارجيًا يساريًا (<code>LEFT OUTER JOIN</code>)، فستُعاد جميع السجلّات الموجودة في الجانب الأيسر من الضمّ (أي الأقسام Departments)، في حين تُعطى السجلات الموجودة على الجانب الأيمن القيمة المعدومة <code>(NULL</code>) في حال لم تُطابق شرط الضمّ.
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
			<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				HireDate
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smitd
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
			<td>
				4
			</td>
			<td>
				Johnatdon
			</td>
			<td>
				Smitd
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
			<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
</tbody>
</table>
<p>
	بعد ذلك، تُقيّم كل التعبيرات المستخدَمة في عبارة <code>SELECT</code> لإعادة الجدول التالي:
</p>

<table>
<thead><tr>
<th>
				Departments.Name
			</th>
			<th>
				Employees.FName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				HR
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				John
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				Richard
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				NULL
			</td>
		</tr>
</tbody>
</table>
<h2>
	الضمّ الضمني Implicit Join
</h2>

<p>
	يمكن أيضًا إجراء عملية الضمّ على عدّة جداول، حيث توضع في عبارة <code>‎from‎</code> مفصولة بالفاصلة <code>‎,‎</code>، مع تحديد العلاقة بينها في العبارة <code>‎where‎</code>. تسمى هذه التقنية "الضمّ الضمني" - Implicit Join - (لأنها لا تحتوي فعليًا العبارةَ <code>‎join‎</code>).
</p>

<p>
	تدعم جميع أنظمة معالجة قواعد البيانات (RDBMSs) هذه التقنية، ولكن ينصح بتجنّب استخدامها للأسباب التالية:
</p>

<ul>
<li>
		قد تتداخل صياغة الضمّ الضمني مع صياغة الضمّ المتقاطع (cross join)، وهو ما قد يؤدي إلى إعادة نتائج غير صحيحة، خاصةً إذا كان الاستعلام يحتوي الكثير من عمليات الضمّ.
	</li>
	<li>
		إذا كنت تنوي استخدام الضم المتقاطع، فلن يكون ذلك واضحًا من الصياغة (اكتب <code>CROSS JOIN</code> بدلاً من ذلك)، ومن المحتمل أن يعدّلها شخص ما أثناء صيانة الشيفرة دون أن ينتبه.
	</li>
</ul>
<p>
	سيختار المثال التالي أسماء الموظفين الأولى وكذلك أسماء الأقسام التي يعملون فيها:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_47" style="">
<span class="pln">SELECT e</span><span class="pun">.</span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> d</span><span class="pun">.</span><span class="typ">Name</span><span class="pln">
FROM   </span><span class="typ">Employee</span><span class="pln"> e</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Departments</span><span class="pln"> d
WHERE  e</span><span class="pun">.</span><span class="typ">DeptartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> d</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				e.FName
			</th>
			<th>
				d.Name
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				James
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				John
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Richard
			</td>
			<td>
				Sales
			</td>
		</tr>
</tbody>
</table>
<h3>
	الضم المتقاطع CROSS JOIN
</h3>

<p>
	يُجري الضمّ المتقاطع جداءً ديكارتيًا (Cartesian product) على جدولين (الجداء الديكارتي هو عملية تُجمِّع كلّ صفّ من الجدول الأول مع كل صفّ من الجدول الثاني).
</p>

<p>
	على سبيل المثال، إذا كان كلّ من الجدولين <code>‎TABLEA‎</code> و <code>‎TABLEB‎</code> يحتويان 20 صفًا، فستتألّف النتيجة المُعادة من <code>‎20*20 = 400‎</code> صفًّا.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_49" style="">
<span class="pln">SELECT d</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">FName</span><span class="pln">
FROM   </span><span class="typ">Departments</span><span class="pln"> d
CROSS JOIN </span><span class="typ">Employees</span><span class="pln"> e</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				d.Name
			</th>
			<th>
				e.FName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				HR
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				John
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				Michael
			</td>
		</tr>
<tr>
<td>
				HR
			</td>
			<td>
				Johnathon
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				John
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				Michael
			</td>
		</tr>
<tr>
<td>
				Sales
			</td>
			<td>
				Johnathon
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				James
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				John
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				Michael
			</td>
		</tr>
<tr>
<td>
				Tech
			</td>
			<td>
				Johnathon
			</td>
		</tr>
</tbody>
</table>
<p>
	يوصى بكتابة <code>CROSS JOIN</code> بشكل صريح إن أردت إجراء ضمّ ديكارتي دفعًا للُّبس.
</p>

<h2>
	التطبيق المتقاطع و الضم الحرفي CROSS APPLY &amp; LATERAL JOIN
</h2>

<p>
	هناك نوع خاص من الضمّ يُسمّى الضمّ الحرفي LATERAL JOIN (أضيف حديثًا إلى الإصدار 9.3 وما بعده من PostgreSQL)، والذي يُعرف أيضًا باسم التطبيق المتقاطع CROSS APPLY أو التطبيق الخارجي OUTER APPLY في كلّ من SQL Server و Oracle.
</p>

<p>
	الفكرة الأساسية التي ينبني عليها هذا النوع من الضمّ هي أنه سيتم تطبيق دالة (أو استعلام فرعي مضمّن - inline subquery) على كل الصفوف المضمومة.
</p>

<p>
	يتيح هذا التحكم في عملية الضمّ، مثلًا يمكنك الاكتفاء بضمّ أوّل مُدخل يحقّق شرط الضمّ (matching entry) في الجدول الآخر.
</p>

<p>
	يكمن الاختلاف بين الضمّ العادي والضمّ الحرفي في حقيقة أنّه يمكنك استخدام عمود سبق أن ضممته في الاستعلام الفرعي (subquery) الذي طبّقته تقاطعيًا (CROSS APPLY).
</p>

<p>
	هذه صياغة الضم الحرفي.
</p>

<ul>
<li>
		PostgreSQL 9.3 والإصدارات الأحدث:
	</li>
</ul>
<pre class="ipsCode">
left | right | inner JOIN LATERAL
</pre>

<ul>
<li>
		SQL Server
	</li>
</ul>
<pre class="ipsCode">
CROSS | OUTER APPLY
</pre>

<p>
	<code>‎INNER‎ JOIN‎ LATERAL</code> و <code>‎CROSS‎ APPLY‎</code> متكافئتان، وكذلك <code>‎LEFT JOIN LATERAL‎</code> و <code>‎OUTER APPLY‎</code>
</p>

<p>
	إليك المثال التالي (الإصدار 9.3 وما بعده من PostgreSQL):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_52" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM T_Contacts
</span><span class="pun">--</span><span class="pln">LEFT JOIN T_MAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID </span><span class="pun">=</span><span class="pln"> T_Contacts</span><span class="pun">.</span><span class="pln">CT_UID AND
MAP_CTCOU_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
</span><span class="pun">--</span><span class="pln">WHERE T_MAP_Contacts_Ref_OrganisationalUnit</span><span class="pun">.</span><span class="pln">MAP_CTCOU_UID IS NULL </span><span class="pun">--</span><span class="pln"> </span><span class="lit">989</span><span class="pln">
LEFT JOIN LATERAL
</span><span class="pun">(</span><span class="pln">
 SELECT
              </span><span class="pun">--</span><span class="pln">MAP_CTCOU_UID    
              MAP_CTCOU_CT_UID  
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_COU_UID  
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_DateFrom
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_DateTo  
 FROM T_MAP_Contacts_Ref_OrganisationalUnit
 WHERE MAP_CTCOU_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
 AND MAP_CTCOU_CT_UID </span><span class="pun">=</span><span class="pln"> T_Contacts</span><span class="pun">.</span><span class="pln">CT_UID
 </span><span class="com">/*  
    AND
    (
        (__in_DateFrom &lt;= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateTo)
        AND
        (__in_DateTo &gt;= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateFrom)
    )
    */</span><span class="pln">
 ORDER BY MAP_CTCOU_DateFrom
 LIMIT </span><span class="lit">1</span><span class="pln">
</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">FirstOE</span></pre>

<p>
	وهذا مثال يخصّ SQL-Server:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_54" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM T_Contacts
</span><span class="pun">--</span><span class="pln">LEFT JOIN T_MAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID </span><span class="pun">=</span><span class="pln"> T_Contacts</span><span class="pun">.</span><span class="pln">CT_UID AND
MAP_CTCOU_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
</span><span class="pun">--</span><span class="pln">WHERE T_MAP_Contacts_Ref_OrganisationalUnit</span><span class="pun">.</span><span class="pln">MAP_CTCOU_UID IS NULL </span><span class="pun">--</span><span class="pln"> </span><span class="lit">989</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> CROSS APPLY </span><span class="pun">--</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> INNER JOIN
OUTER APPLY </span><span class="pun">--</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> LEFT JOIN
</span><span class="pun">(</span><span class="pln">
 SELECT TOP </span><span class="lit">1</span><span class="pln">
 </span><span class="pun">--</span><span class="pln">MAP_CTCOU_UID    
                            MAP_CTCOU_CT_UID  
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_COU_UID  
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_DateFrom
 </span><span class="pun">,</span><span class="pln">MAP_CTCOU_DateTo  
 FROM T_MAP_Contacts_Ref_OrganisationalUnit
 WHERE MAP_CTCOU_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
 AND MAP_CTCOU_CT_UID </span><span class="pun">=</span><span class="pln"> T_Contacts</span><span class="pun">.</span><span class="pln">CT_UID
 </span><span class="com">/*  
    AND
    (
        (@in_DateFrom &lt;= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateTo)
        AND
        (@in_DateTo &gt;= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateFrom)
    )
    */</span><span class="pln">
 ORDER BY MAP_CTCOU_DateFrom
</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">FirstOE</span></pre>

<h3>
	الضم التام FULL JOIN
</h3>

<p>
	هناك نوع آخر من الضمّ أقل شهرة من غيره، وهو الضمّ التام FULL JOIN
</p>

<p>
	(<strong>ملاحظة</strong>: لا تدعم MySQL الضمّ التام)
</p>

<p>
	يعيد الضمّ التام الخارجي FULL OUTER JOIN جميع صفوف الجدول الأيسر، وكذلك جميع صفوف الجدول الأيمن.
</p>

<p>
	ستُدرج صفوف الجدول الأيسر التي ليس لها مُطابِقَات مقابلة في الجدول الأيمن، وكذلك في الحالة المعكوسة.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_56" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Table1</span><span class="pln">
FULL JOIN </span><span class="typ">Table2</span><span class="pln">
    ON </span><span class="lit">1</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span></pre>

<p>
	وهذا مثال آخر:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_58" style="">
<span class="pln">SELECT
      COALESCE</span><span class="pun">(</span><span class="pln">T_Budget</span><span class="pun">.</span><span class="typ">Year</span><span class="pun">,</span><span class="pln"> tYear</span><span class="pun">.</span><span class="typ">Year</span><span class="pun">)</span><span class="pln"> AS RPT_BudgetInYear
      </span><span class="pun">,</span><span class="pln">COALESCE</span><span class="pun">(</span><span class="pln">T_Budget</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">,</span><span class="pln"> </span><span class="lit">0.0</span><span class="pun">)</span><span class="pln"> AS RPT_Value
FROM T_Budget
FULL JOIN tfu_RPT_All_CreateYearInterval</span><span class="pun">(</span><span class="lit">@budget_year_from</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@budget_year_to</span><span class="pun">)</span><span class="pln"> AS tYear
      ON tYear</span><span class="pun">.</span><span class="typ">Year</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> T_Budget</span><span class="pun">.</span><span class="typ">Year</span></pre>

<p>
	إن كنت تستخدم عمليات الحذف اللينة soft-deletes (والتي لا تحذف البيانات بشكل نهائي)، فسيتعيّن عليك التحقق من حالة الحذف الليّن مرة أخرى في عبارة <code>WHERE</code> (لأنّ سلوك الضمّ التام - FULL JOIN - يتصرف بشكل يشبه الاتحاد UNION)؛
</p>

<p>
	عند إجراء الضمّ التام، سيتعيّن عليك عادةً السماح بـاستخدام القيمة المعدومة <code>NULL</code> في عبارة <code>WHERE</code>؛ وفي حال نسيت ذلك، فسيتصرّف الضمّ كما لو كان ضمًّا داخليًا (INNER join)، وهو ما لا تريده عند إجراء الضمّ التام.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_60" style="">
<span class="pln">SELECT
  T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_UID
 </span><span class="pun">,</span><span class="pln">T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_Code
 </span><span class="pun">,</span><span class="pln">T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_Lang_EN
 </span><span class="pun">,</span><span class="pln">T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_Budget
 </span><span class="pun">,</span><span class="pln">T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_UID
 </span><span class="pun">,</span><span class="pln">T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_Jahr
FROM T_BudgetPositions    
FULL JOIN T_AccountPlan
 ON T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_UID </span><span class="pun">=</span><span class="pln"> T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_AP_UID
 AND T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
WHERE </span><span class="pun">(</span><span class="lit">1</span><span class="pun">=</span><span class="lit">1</span><span class="pun">)</span><span class="pln">
AND </span><span class="pun">(</span><span class="pln">T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> OR T_BudgetPositions</span><span class="pun">.</span><span class="pln">BUP_SoftDeleteStatus IS NULL</span><span class="pun">)</span><span class="pln">
AND </span><span class="pun">(</span><span class="pln">T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_SoftDeleteStatus </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> OR T_AccountPlan</span><span class="pun">.</span><span class="pln">AP_SoftDeleteStatus IS NULL</span><span class="pun">)</span></pre>

<h2>
	الضم العودي Recursive JOIN
</h2>

<p>
	يُستخدم الضمّ العودي عادة للحصول على بيانات من نوع أب-ابن (parent-child data). في SQL، تُقدّم عمليات الضمّ العودية باستخدام تعبيرات الجدول العادية كما يوضّح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_62" style="">
<span class="pln">WITH RECURSIVE </span><span class="typ">MyDescendants</span><span class="pln"> AS </span><span class="pun">(</span><span class="pln">
 SELECT </span><span class="typ">Name</span><span class="pln">
 FROM </span><span class="typ">People</span><span class="pln">
 WHERE </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'John Doe'</span><span class="pln">
 UNION ALL
 SELECT </span><span class="typ">People</span><span class="pun">.</span><span class="typ">Name</span><span class="pln">
 FROM </span><span class="typ">People</span><span class="pln">
 JOIN </span><span class="typ">MyDescendants</span><span class="pln"> ON </span><span class="typ">People</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">MyDescendants</span><span class="pun">.</span><span class="typ">Parent</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">MyDescendants</span><span class="pun">;</span></pre>

<h2>
	الضم الداخلي الصريح
</h2>

<p>
	يستعلم الضمّ الأولي - basic join (يُسمّى أيضًا الضمّ الداخلي - inner join) عن البيانات من جدولين، حيث تُحدَّد العلاقة بينهما في عبارة <code>‎join‎</code>.
</p>

<p>
	يستعلم المثال التالي عن أسماء الموظفين (<code>FName</code>) من جدول الموظفين <code>Employees</code>، وأسماء الأقسام التي يعملون فيها (<code>Name</code>) من جدول الأقسام <code>Departments</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_64" style="">
<span class="pln">SELECT </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Name</span><span class="pln">
FROM   </span><span class="typ">Employees</span><span class="pln">
JOIN   </span><span class="typ">Departments</span><span class="pln">
ON </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				Employees.FName
			</th>
			<th>
				Departments.Name
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				James
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				John
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Richard
			</td>
			<td>
				Sales
			</td>
		</tr>
</tbody>
</table>
<h2>
	الضم في استعلام فرعي Joining on a Subquery
</h2>

<p>
	غالبًا ما يُستخدم الضمّ في الاستعلامات الفرعية (subquery) للحصول على بيانات مُجمّعة (aggregate data) من جدول يحتوي التفاصيل (الجدول الإبن) وعرضها جنبًا إلى جنب مع السجلات من الجدول الأصلي (الجدول الأب).
</p>

<p>
	على سبيل المثال، قد ترغب في الحصول على عدد السجلات الفرعية (child records)، أو متوسط قيم عمود معيّن في السجلات الفرعية، أو الصف ذو القيمة الأكبر أو الأصغر.
</p>

<p>
	يستخدم هذا المثال الكُنى (لتسهيل قراءة الاستعلامات التي تشمل عدّة جداول)، يعطي المثال فكرة عامّة عن كيفية صياغة عمليات ضمّ الاستعلامات الفرعية. إذ يعيد جميع صفوف الجدول الأصلي "Purchase Orders"، مع إعادة الصف الأول وحسب لكل سجلّ أصلي (parent record) من الجدول الفرعي PurchaseOrderLineItems.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2706_66" style="">
<span class="pln">SELECT po</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> po</span><span class="pun">.</span><span class="typ">PODate</span><span class="pun">,</span><span class="pln"> po</span><span class="pun">.</span><span class="typ">VendorName</span><span class="pun">,</span><span class="pln"> po</span><span class="pun">.</span><span class="typ">Status</span><span class="pun">,</span><span class="pln"> item</span><span class="pun">.</span><span class="typ">ItemNo</span><span class="pun">,</span><span class="pln">
      item</span><span class="pun">.</span><span class="typ">Description</span><span class="pun">,</span><span class="pln"> item</span><span class="pun">.</span><span class="typ">Cost</span><span class="pun">,</span><span class="pln"> item</span><span class="pun">.</span><span class="typ">Price</span><span class="pln">
FROM </span><span class="typ">PurchaseOrders</span><span class="pln"> po
LEFT JOIN
 </span><span class="pun">(</span><span class="pln">
 SELECT l</span><span class="pun">.</span><span class="typ">PurchaseOrderId</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">ItemNo</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Description</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Cost</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Price</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Min</span><span class="pun">(</span><span class="pln">l</span><span class="pun">.</span><span class="pln">id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">Id</span><span class="pln">
 FROM </span><span class="typ">PurchaseOrderLineItems</span><span class="pln"> l
 GROUP BY l</span><span class="pun">.</span><span class="typ">PurchaseOrderId</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">ItemNo</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Description</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Cost</span><span class="pun">,</span><span class="pln"> l</span><span class="pun">.</span><span class="typ">Price</span><span class="pln">
 </span><span class="pun">)</span><span class="pln"> AS item ON item</span><span class="pun">.</span><span class="typ">PurchaseOrderId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> po</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	ترجمة -وبتصرّف- للفصل Chapter 18: JOIN من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D8%AD%D8%AF%D9%8A%D8%AB-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r850/" rel="">تحديث الجداول في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D9%88%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%8A%D8%A8-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%B4%D9%8A%D8%AD-%D9%81%D9%8A-sql-r848/" rel="">البحث والتنقيب والترشيح في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">849</guid><pubDate>Sat, 04 Apr 2020 13:04:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x628;&#x62D;&#x62B; &#x648;&#x627;&#x644;&#x62A;&#x646;&#x642;&#x64A;&#x628; &#x648;&#x627;&#x644;&#x62A;&#x631;&#x634;&#x64A;&#x62D; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D9%88%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%8A%D8%A8-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%B4%D9%8A%D8%AD-%D9%81%D9%8A-sql-r848/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/5.jpg.0faa5b411da2131a706cca80c46d7c8f.jpg" /></p>

<p>
	تستعرض هذه المقالة بعض معاملات SQL المتخصصة في البحث والتنقيب وترشيح النتائج.
</p>

<h2>
	المعامل LIKE
</h2>

<h3>
	مطابقة الأنماط المفتوحة Match open-ended pattern
</h3>

<p>
	يطابق حرف البدل <code>‎%‎</code> الموضوع في بداية أو نهاية السلسلة النصية (أو كليهما) 0 حرف أو أكثر قبل بداية أو بعد نهاية النمط المراد مطابقته.
</p>

<p>
	يسمح استخدام "%' في الوسط بوجود 0 حرف أو أكثر بين جزأي النمط المُراد مُطابقته.
</p>

<p>
	سنستخدم جدول الموظفين <code>Employees</code> التالي:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sophie
			</td>
			<td>
				Amudsen
			</td>
			<td>
				2479100211
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				11-01-2010
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Ronny
			</td>
			<td>
				Smith
			</td>
			<td>
				2462544026
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				600
			</td>
			<td>
				06-08-2015
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Jon
			</td>
			<td>
				Sanchez
			</td>
			<td>
				2454124602
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				Hilde
			</td>
			<td>
				Knag
			</td>
			<td>
				2468021911
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				800
			</td>
			<td>
				01-01-2000
			</td>
		</tr>
</tbody>
</table>
<p>
	تطابق العبارة التالية جميع السجلات التي يحتوي حقل <code>FName</code> خاصتها على السلسلة النصية 'on':
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_6" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'%on%'</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				3
			</td>
			<td>
				Ronny
			</td>
			<td>
				Smith
			</td>
			<td>
				2462544026
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				600
			</td>
			<td>
				06-08-2015
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Jon
			</td>
			<td>
				Sanchez
			</td>
			<td>
				2454124602
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
</tbody>
</table>
<p>
	يطابق التعبير التالي جميع السجلات التي يبدأ الحقل <code>PhoneNumber</code> خاصتها بالسلسلة النصية "246" في جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_8" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">PhoneNumber</span><span class="pln"> LIKE </span><span class="str">'246%'</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Ronny
			</td>
			<td>
				Smith
			</td>
			<td>
				2462544026
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				600
			</td>
			<td>
				06-08-2015
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				Hilde
			</td>
			<td>
				Knag
			</td>
			<td>
				2468021911
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				800
			</td>
			<td>
				01-01-2000
			</td>
		</tr>
</tbody>
</table>
<p>
	تطابق العبارة التالية جميع السجلات التي ينتهي الحقل <code>PhoneNumber</code> خاصتها بالسلسلة النصية "11" في جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_10" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">PhoneNumber</span><span class="pln"> LIKE </span><span class="str">'%11'</span></pre>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				2
			</td>
			<td>
				Sophie
			</td>
			<td>
				Amudsen
			</td>
			<td>
				2479100211
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				11-01-2010
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				Hilde
			</td>
			<td>
				Knag
			</td>
			<td>
				2468021911
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				800
			</td>
			<td>
				01-01-2000
			</td>
		</tr>
</tbody>
</table>
<p>
	يطابق التعبير التالي جميع السجلات التي يساوي الحرف الثالث من حقل <code>Fname</code> خاصتها 'n' في جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_12" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'__n%'</span><span class="pun">;</span></pre>

<p>
	(استخدمنا شرطتين سفليتين قبل 'n' لتخطي أول حرفين)
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				Hire_date
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				3
			</td>
			<td>
				Ronny
			</td>
			<td>
				Smith
			</td>
			<td>
				2462544026
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				600
			</td>
			<td>
				06-08-2015
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Jon
			</td>
			<td>
				Sanchez
			</td>
			<td>
				2454124602
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
</tbody>
</table>
<h3>
	مطابقة محرف واحد
</h3>

<p>
	يمكن استخدام أحرف البدل وعلامة النسبة المئوية (<code>%</code>) والشرطة السفلية (<code>_</code>) لتوسيع أنماط الاختيار في SQL.
</p>

<p>
	يمكن استخدام المحرف <code>‎_‎</code> (الشرطة السفلية) كحرف بدل يمثل حرفًا منفردًا.
</p>

<p>
	يبحث النمط التالي عن جميع الموظفين الذين يتألف الحقل <code>Fname</code> خاصتهم من 3 حروف، ويبدأ بالحرف "j" وينتهي بـ "n".
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_14" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'j_n'</span></pre>

<p>
	يمكن استخدام المحرف <code>‎_‎</code> أكثر من مرة بحيث يتصرف كبطاقة بدل (wild card) لمطابقة أنماط معينة.
</p>

<p>
	على سبيل المثال، يُطابق النمط أعلاه السلاسل النصية التالية: <code>jon</code> و <code>jan</code> و <code>jen</code>. بيْد أنّه لا يُطابق الأسماء التالية: <code>jn</code> و <code>john</code> و <code>jordan</code> و <code>justin</code> و <code>jason</code> و <code>julian</code> و <code>jillian</code> و <code>joann</code>، لأنّ الشرطة السفلية التي استخدمناها في الاستعلام تتخطى حرفًا واحدًا فقط، لذلك لن تُقبل إلا الحقول المؤلفة من 3 أحرف.
</p>

<p>
	يُطابق النمط التالي السلاسل النصية التالية: <code>LaSt</code> و <code>LoSt</code> و <code>HaLt</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_16" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'_A_T'</span></pre>

<h3>
	العبارة ESCAPE في الاستعلام LIKE
</h3>

<p>
	يمكن إجراء بحث نصي في العبارة <code>‎LIKE‎</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_18" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM T_Whatever
WHERE </span><span class="typ">SomeField</span><span class="pln"> LIKE CONCAT</span><span class="pun">(</span><span class="str">'%'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@in_SearchText</span><span class="pun">,</span><span class="pln"> </span><span class="str">'%'</span><span class="pun">)</span></pre>

<p>
	ستحدث مشكلة إذا أدخل شخص ما نصُّا من قبيل "50%" أو "a_b" (بصرف النظر عن حقيقة أنه يُفضل البحث عن النص الكامل بدل استخدام <code>‎LIKE‎</code>). يمكن حل هذه المشكلة باستخدام عبارة <code>‎LIKE‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_20" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM T_Whatever
WHERE </span><span class="typ">SomeField</span><span class="pln"> LIKE CONCAT</span><span class="pun">(</span><span class="str">'%'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@in_SearchText</span><span class="pun">,</span><span class="pln"> </span><span class="str">'%'</span><span class="pun">)</span><span class="pln"> ESCAPE </span><span class="str">'\'</span></pre>

<p>
	هذا يعني أنّ <code>‎\‎</code> ستُعامل كحرف التهريب <code>ESCAPE</code>. أي أنّه يمكنك الآن إضافة <code>‎\‎</code> إلى كل حرف في السلسلة النصية التي تبحث عنها، وستكون النتائج صحيحة، حتى لو أدخل المستخدم محارف خاصة مثل <code>‎%‎</code> أو <code>‎_‎</code>.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_22" style="">
<span class="kwd">string</span><span class="pln"> stringToSearch </span><span class="pun">=</span><span class="pln"> </span><span class="str">"abc_def 50%"</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">string</span><span class="pln"> newString </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">foreach</span><span class="pun">(</span><span class="kwd">char</span><span class="pln"> c </span><span class="kwd">in</span><span class="pln"> stringToSearch</span><span class="pun">)</span><span class="pln">
     newString </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">@</span><span class="str">"\" + c;

sqlCmd.Parameters.Add("</span><span class="lit">@in_SearchText</span><span class="str">", newString);
// sqlCmd.Parameters.Add("</span><span class="lit">@in_SearchText</span><span class="str">", stringToSearch); بدلا من</span></pre>

<p>
	<strong>ملاحظة</strong>: وضعنا الخوارزمية أعلاه للتوضيح وحسب، ولن تعمل في حال احتوت السلسلة النصية على رسمة (grapheme) مؤلفة من عدّة أحرف (مثل رموز utf-8). مثلًا، في السلسلة النصية <code>‎string stringToSearch = "Les Mise\u0301rables";‎</code>، ستحتاج إلى فعل ذلك لكل رسمة، وليس لكل حرف. عليك ألا تستخدم الخوارزمية أعلاه إذا كنت تتعامل مع لغات آسيوية أو شرق آسيوية أو جنوب آسيوية.
</p>

<h3>
	البحث عن مجموعة من المحارف
</h3>

<p>
	تطابق العبارة التالية جميع السجلات التي يبدأ حقل <code>FName</code> خاصتها بحرف محصور (أبجديا) بين <code>A</code> و <code>F</code> في جدول الموظفين.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_24" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'[A-F]%'</span></pre>

<h3>
	مطابقة نطاق أو مجموعة
</h3>

<p>
	يمكن مطابقة حرف واحد داخل نطاق محدد (على سبيل المثال: <code>‎[a-f]‎</code>) أو مجموعة (على سبيل المثال: <code>‎[abcdef]‎</code>).
</p>

<p>
	يطابق نمط النطاق التالي السلسلة النصية <code>gary</code>، ولكن ليس <code>mary</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_26" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'[a-g]ary'</span></pre>

<p>
	يُطابق نمط المجموعة التالي <code>mary</code> ولكن ليس <code>gary</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_28" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">Fname</span><span class="pln"> LIKE </span><span class="str">'[lmnop]ary'</span></pre>

<p>
	يمكن أيضًا عكس أو نفي النطاق أو المجموعة بوضع العلامة <code>‎^‎</code> قبل النطاق أو المجموعة، فلن يتطابق نمط النطاق التالي مع <code>gary</code>، ولكنه سيتطابق مع <code>mary</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_30" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'[^a-g]ary'</span></pre>

<p>
	لن يتطابق نمط المجموعة التالي مع <code>mary</code> ولكن سيتطابق مع <code>gary</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_32" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">Fname</span><span class="pln"> LIKE </span><span class="str">'[^lmnop]ary'</span></pre>

<h3>
	أحرف البدل Wildcard characters
</h3>

<p>
	يمكن استخدام أحرف البدل مع المعامل <code>LIKE</code>. تُستخدم أحرف البدل في SQL للبحث عن البيانات داخل جدول معيّن. وهناك أربعة منها، وهي كالتالي:
</p>

<ul>
<li>
		<strong>%</strong> - بديل عن صفر حرف أو أكثر
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_34" style="">
<span class="pun">--</span><span class="pln">   </span><span class="str">"Lo"</span><span class="pln"> </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">تبدأ</span><span class="pln"> </span><span class="pun">بـ</span><span class="pln"> 
 SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
 WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'Lo%'</span><span class="pun">;</span><span class="pln">

</span><span class="pun">--</span><span class="pln"> </span><span class="str">"es"</span><span class="pln"> </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">تحتوي</span><span class="pln"> 
 SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
 WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'%es%'</span><span class="pun">;</span></pre>

<ul>
<li>
		<strong>_</strong> - بديل عن حرف واحد
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_38" style="">
<span class="pun">--</span><span class="pln"> erlin  </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">تبدأ</span><span class="pln"> </span><span class="pun">بحرف</span><span class="pln"> </span><span class="pun">معين،</span><span class="pln"> </span><span class="pun">متبوعا</span><span class="pln"> </span><span class="pun">بـ</span><span class="pln"> 
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'_erlin'</span><span class="pun">;</span></pre>

<ul>
<li>
		<strong>[charlist]</strong> - مجموعات ونطاقات مؤلفة من الحروف المُراد مُطابقتها
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_42" style="">
<span class="pun">--</span><span class="pln"> </span><span class="str">"a"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"l"</span><span class="pln"> </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">تبدأ</span><span class="pln"> </span><span class="pun">بـ</span><span class="pln"> 
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'[adl]%'</span><span class="pun">;</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="str">"a"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"l"</span><span class="pln"> </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">تبدأ</span><span class="pln"> </span><span class="pun">بـ</span><span class="pln"> 
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'[a-c]%'</span><span class="pun">;</span></pre>

<ul>
<li>
		<strong>[‎^ charlist]</strong> - تطابق الحروف غير الموجودة داخل القوسين المربعين
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_44" style="">
<span class="pun">--</span><span class="pln"> </span><span class="str">"a"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"d"</span><span class="pln"> </span><span class="pun">أو</span><span class="pln"> </span><span class="str">"l"</span><span class="pln"> </span><span class="pun">اختيار</span><span class="pln"> </span><span class="pun">جميع</span><span class="pln"> </span><span class="pun">العملاء</span><span class="pln"> </span><span class="pun">الذين</span><span class="pln"> </span><span class="pun">يقطنون</span><span class="pln"> </span><span class="pun">مدينة</span><span class="pln"> </span><span class="pun">لا</span><span class="pln"> </span><span class="pun">تبدأ</span><span class="pln"> </span><span class="pun">بـ</span><span class="pln"> 
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">City</span><span class="pln"> LIKE </span><span class="str">'[^apl]%'</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">or</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">City</span><span class="pln"> NOT LIKE </span><span class="str">'[apl]%'</span><span class="pln"> </span><span class="kwd">and</span><span class="pln"> city like </span><span class="str">'_%'</span><span class="pun">;</span></pre>

<h2>
	التحقق من الانتماء عبر IN
</h2>

<p>
	يمكن استخدام العبارة IN للتحقق من إنتماء قيمة إلى مجموعة معينة.
</p>

<p>
	تعيد الشيفرة التالية السجلات التي ينتمي مُعرّفها <code>‎id‎</code> إلى مجموعة معينة من القيم ((1,8,3)):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_46" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> products
</span><span class="kwd">where</span><span class="pln"> id </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="lit">8</span><span class="pun">,</span><span class="lit">3</span><span class="pun">)</span></pre>

<p>
	يكافئ الاستعلام أعلاه:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_48" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> products
</span><span class="kwd">where</span><span class="pln"> id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln">
 </span><span class="kwd">or</span><span class="pln"> id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">8</span><span class="pln">
 </span><span class="kwd">or</span><span class="pln"> id </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span></pre>

<p>
	يمكن استخدام IN مع استعلام فرعي على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_50" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM customers
WHERE id IN </span><span class="pun">(</span><span class="pln">
 SELECT DISTINCT customer_id
 FROM orders
</span><span class="pun">);</span></pre>

<p>
	ستعيد الشيفرة أعلاه جميع العملاء الذين لديهم طلبات في النظام.
</p>

<h2>
	ترشيح النتائج باستخدام WHERE و HAVING
</h2>

<h3>
	استخدم BETWEEN لترشيح النتائج
</h3>

<p>
	تستخدم الأمثلة التالية قاعدتي البيانات <code>Sales</code> و <code>Customers</code>.
</p>

<p>
	تذكر أنّ المعامل BETWEEN تضميني (inclusive):
</p>

<h4>
	استخدام المعامل BETWEEN مع الأعداد
</h4>

<p>
	يعيد الاستعلام التالي جميع سجلات <code>‎ItemSales‎</code> التي ينحصر حقل الكمية <code>quantity</code> خاصتها بين 10 و 17.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_52" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> </span><span class="typ">From</span><span class="pln"> </span><span class="typ">ItemSales</span><span class="pln">
WHERE </span><span class="typ">Quantity</span><span class="pln"> BETWEEN </span><span class="lit">10</span><span class="pln"> AND </span><span class="lit">17</span></pre>

<p>
	سنحصل على النتائج التالية:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				SaleDate
			</th>
			<th>
				ItemId
			</th>
			<th>
				Quantity
			</th>
			<th>
				Price
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				2013-07-01
			</td>
			<td>
				100
			</td>
			<td>
				10
			</td>
			<td>
				34.5
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				2013-07-23
			</td>
			<td>
				100
			</td>
			<td>
				15
			</td>
			<td>
				34.5
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				2013-07-24
			</td>
			<td>
				145
			</td>
			<td>
				10
			</td>
			<td>
				34.5
			</td>
		</tr>
</tbody>
</table>
<h4>
	استخدام المعامل BETWEEN مع قيم التاريخ
</h4>

<p>
	يعيد الاستعلام التالي كافة سجلات <code>‎ItemSales‎</code> التي ينحصر حقل <code>‎SaleDate‎</code> خاصتها بين التاريخين 11 يوليو 2013 و 24 مايو 2013.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_54" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> </span><span class="typ">From</span><span class="pln"> </span><span class="typ">ItemSales</span><span class="pln">
WHERE </span><span class="typ">SaleDate</span><span class="pln"> BETWEEN </span><span class="str">'2013-07-11'</span><span class="pln"> AND </span><span class="str">'2013-05-24'</span></pre>

<p>
	هذا هو الخرج المتوقع:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				SaleDate
			</th>
			<th>
				ItemId
			</th>
			<th>
				Quantity
			</th>
			<th>
				Price
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				3
			</td>
			<td>
				2013-07-11
			</td>
			<td>
				100
			</td>
			<td>
				20
			</td>
			<td>
				34.5
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				2013-07-23
			</td>
			<td>
				100
			</td>
			<td>
				15
			</td>
			<td>
				34.5
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				2013-07-24
			</td>
			<td>
				145
			</td>
			<td>
				10
			</td>
			<td>
				34.5
			</td>
		</tr>
</tbody>
</table>
<p>
	عند موازنة قيم الوقت (datetime) بدلًا من قيم التاريخ (dates)، قد تحتاج إلى تحويل قيم الوقت إلى قيم التاريخ، أو إضافة أو طرح 24 ساعة للحصول على النتيجة المتوقعة.
</p>

<h4>
	استخدام المعامل BETWEEN مع القيم النصية
</h4>

<p>
	يعيد الاستعلام التالي كافة العملاء الذين تنحصر أسماؤهم (أبجديًا) بين الحرفين 'D' و 'L'. في هذه الحالة، سيُعاد العميلان ذوي الرقمين 1 و 3. أما العميل رقم 2 ، الذي يبدأ اسمه بـالحرف "M"، فلن يُعاد:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_56" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln">
WHERE </span><span class="typ">LName</span><span class="pln"> BETWEEN </span><span class="str">'D'</span><span class="pln"> AND </span><span class="str">'L'</span><span class="pun">;</span></pre>

<p>
	هذا <a href="http://sqlfiddle.com/#!9/76b9b/2" rel="external nofollow">مثال حي</a>
</p>

<p>
	الخرج:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				William
			</td>
			<td>
				Jones
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Richard
			</td>
			<td>
				Davis
			</td>
		</tr>
</tbody>
</table>
<h3>
	استخدم HAVING مع الدوال التجميعية
</h3>

<p>
	على خلاف العبارة <code>‎WHERE‎</code> ، يمكن استخدام <code>‎HAVING‎</code> مع الدوال التجميعية.
</p>

<p>
	الدوال التجميعية (aggregate functions) هي دوال تأخذ القيم الموجودة في في عدة صفوف كمُدخلات (بناء على شروط محددة) وتعيد قيمة معينة. هذه بعض الدوال التجميعية: <code>‎COUNT()‎</code> و <code>‎SUM()‎</code> و <code>‎MIN()‎</code> و <code>‎MAX()‎</code>.
</p>

<p>
	يستخدم هذا المثال الجدول <code>Car</code> من <a href="%D8%B1%D8%A7%D8%A8%D8%B7" rel="">الفصل الأول</a>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_58" style="">
<span class="pln">SELECT </span><span class="typ">CustomerId</span><span class="pun">,</span><span class="pln"> COUNT</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> AS </span><span class="pun">[</span><span class="typ">Number</span><span class="pln"> of </span><span class="typ">Cars</span><span class="pun">]</span><span class="pln">
FROM </span><span class="typ">Cars</span><span class="pln">
GROUP BY </span><span class="typ">CustomerId</span><span class="pln">
HAVING COUNT</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span></pre>

<p>
	يعيد الاستعلام أعلاه <code>‎CustomerId‎</code> وعدد السيارات <code>‎Number of Cars‎</code> لأيّ عميل لديه أكثر من سيارة واحدة. في هذا المثال، العميل الوحيد الذي لديه أكثر من سيارة واحدة هو العميل رقم 1.
</p>

<p>
	هذا هو الخرج:
</p>

<table>
<thead><tr>
<th>
				CustomerId
			</th>
			<th>
				Number of Cars
			</th>
		</tr></thead>
<tbody><tr>
<td>
				1
			</td>
			<td>
				2
			</td>
		</tr></tbody>
</table>
<h3>
	استخدام WHERE مع القيم NULL / NOT NULL
</h3>

<p>
	يعيد المثال التالي جميع سجلات الموظفين (Employee) التي تتساوى قيمة العمود <code>‎ManagerId‎</code> خاصتهم مع القيمة المعدومة <code>‎NULL‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_60" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">ManagerId</span><span class="pln"> IS NULL</span></pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode">
Id    FName    LName    PhoneNumber    ManagerId    DepartmentId
1     James     Smith      1234567890        NULL           1
</pre>

<p>
	يعيد المثال التالي جميع سجلات الموظفين التي لا تساوي قيمة العمود <code>‎ManagerId‎</code> خاصتهم القيمة <code>‎NULL‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_63" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">ManagerId</span><span class="pln"> IS NOT NULL</span></pre>

<p>
	ستكون النتيجة كما يلي:
</p>

<pre class="ipsCode">
Id    FName       LName     PhoneNumber    ManagerId    DepartmentId
2     John           Johnson    2468101214      1                    1
3     Michael       Williams   1357911131       1                    2
4     Johnathon   Smith       1212121212       2                   1
</pre>

<p>
	<strong>ملاحظة</strong>: لن يعيد الاستعلام أعلاه أيّ نتائج في حال غيّرت صياغة العبارة WHERE إلى <code>‎WHERE ManagerId = NULL‎</code> أو <code>‎WHERE‎ ‎ManagerId‎ &lt;&gt; NULL</code>.
</p>

<h3>
	معامل التساوي
</h3>

<p>
	تعيد الشيفرة التالية كل صفوف الجدول <code>‎Employees‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_65" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<p>
	الخرج:
</p>

<pre class="ipsCode">
Id   FName     LName    PhoneNumber   ManagerId   DepartmentId    Salary  Hire_date CreatedDate   ModifiedDate
1    James     Smith        1234567890      NULL          1                        1000     01-01-2002  01-01-2002  01-01-2002
2    John       Johnson     2468101214      1                1                        400       23-03-2005   23-03-2005  01-01-2002
3    Michael   Williams    1357911131      1                  2                        600      12-05-2009   12-05-2009  NULL
4    Johnathon Smith      1212121212      2                 1                        500       24-07-2016   24-07-2016  01-01-2002
</pre>

<p>
	يتيح لك استخدام <code>‎WHERE‎</code> في نهاية العبارة <code>‎SELECT‎</code> ترشيح الصفوف المُعادة وفق شرط معين. إن أردت مثلًا اشتراط التطابق التام مع قيمة معينة، فاستخدم علامة التساوي <code>‎=‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_67" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span></pre>

<p>
	لن يعيد الاستعلام أعلاه إلا الصفوف التي يساوي الحقل <code>‎DepartmentId‎</code> خاصتها القيمة <code>‎1‎</code>:
</p>

<pre class="ipsCode">
Id   FName     LName    PhoneNumber   ManagerId   DepartmentId    Salary  Hire_date       CreatedDate   ModifiedDate
1    James       Smith      1234567890       NULL          1                       1000      01-01-2002    01-01-2002    01-01-2002
2    John          Johnson  2468101214       1                 1                       400        23-03-2005    23-03-2005    01-01-2002
4    Johnathon Smith       1212121212       2                 1                       500        24-07-2016    24-07-2016     01-01-2002
</pre>

<p>
	لنفترض أنّ متجرًا للألعاب لديه فئة من الألعاب يقل سعرها عن 10 دولارات. يعيد الاستعلام التالي هذه الفئة من الألعاب:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_69" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Items</span><span class="pln">
WHERE </span><span class="typ">Price</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">10</span></pre>

<h3>
	المعاملان المنطقيان AND و OR
</h3>

<p>
	يمكنك الجمع بين عدة معاملات معًا لإنشاء شروط <code>‎WHERE‎</code> أكثر تعقيدًا.
</p>

<p>
	تستخدم الأمثلة التالية الجدول <code>‎Employees‎</code> التالي:
</p>

<pre class="ipsCode">
Id   FName     LName    PhoneNumber   ManagerId   DepartmentId    Salary    Hire_date       CreatedDate   ModifiedDate
1    James       Smith      1234567890      NULL           1                       1000        01-01-2002    01-01-2002    01-01-2002
2    John         Johnson   2468101214      1                  1                       400         23-03-2005    23-03-2005     01-01-2002
3    Michael     Williams  1357911131       1                   2                       600         12-05-2009    12-05-2009    NULL
4    Johnathon  Smith     1212121212       2                   1                       500         24-07-2016    24-07-2016    01-01-2002
</pre>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_71" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> AND </span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span></pre>

<p>
	سينتج الخرج التالي:
</p>

<pre class="ipsCode">
Id   FName     LName    PhoneNumber   ManagerId   DepartmentId    Salary  Hire_date        CreatedDate   ModifiedDate
2    John        Johnson   2468101214      1                   1                       400         23-03-2005    23-03-2005    01-01-2002
</pre>

<p>
	وهذا استعلام آخر يستخدم المعامل المنطقي OR:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_73" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> OR </span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span></pre>

<p>
	سينتج الخرج التالي:
</p>

<pre class="ipsCode">
Id   FName     LName    PhoneNumber   ManagerId   DepartmentId    Salary  Hire_date       CreatedDate   ModifiedDate
3    Michael     Williams   1357911131      1                  2                       600         12-05-2009    12-05-2009   NULL
4    Johnathon Smith      1212121212      2                  1                       500         24-07-2016     24-07-2016   01-01-2002
</pre>

<h3>
	استخدم IN لإعادة الصفوف التي تنتمي قيمها إلى قائمة معينة
</h3>

<p>
	يستخدم هذا المثال الجدول "Car".
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_75" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Cars</span><span class="pln">
WHERE </span><span class="typ">TotalCost</span><span class="pln"> IN </span><span class="pun">(</span><span class="lit">100</span><span class="pun">,</span><span class="pln"> </span><span class="lit">200</span><span class="pun">,</span><span class="pln"> </span><span class="lit">300</span><span class="pun">)</span></pre>

<p>
	سيعيد هذا الاستعلام السيارة رقم 2، والتي تبلغ تكلفتها 200، والسيّارة رقم 3، والتي تساوي تكلفتها 100. لاحظ أنّ الاستعلام أعلاه يكافئ استخدام <code>‎OR‎</code> عدة مرّات كما هو موضّح في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_77" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Cars</span><span class="pln">
WHERE </span><span class="typ">TotalCost</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">100</span><span class="pln"> OR </span><span class="typ">TotalCost</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">200</span><span class="pln"> OR </span><span class="typ">TotalCost</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">300</span></pre>

<h3>
	استخدم LIKE للبحث عن السلاسل النصية
</h3>

<p>
	يستخدم المثال التالي الجدول Car:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_79" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">FName</span><span class="pln"> LIKE </span><span class="str">'John'</span></pre>

<p>
	لن يعيد هذا الاستعلام إلا الموظف رقم 1، والذي يتطابق اسمه الأول مع السلسلة النصية "John".
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_81" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
WHERE </span><span class="typ">FName</span><span class="pln"> like </span><span class="str">'John%'</span></pre>

<p>
	يمكنك البحث عن سلسلة نصية فرعية عبر إضافة الرمز <code>‎%‎</code>:
</p>

<ul>
<li>
		<code>John%‎‎</code> - تعيد أيّ موظف يبدأ اسمه بـ "John" ، متبوعًا بأي عدد من الأحرف
	</li>
	<li>
		<code>‎‎%John‎‎</code> - تعيد أيّ موظف ينتهي اسمه بـ "John" ، يعقبه أي عدد من الأحرف
	</li>
	<li>
		<code>‎%‎John‎%‎</code> - تعيد أيّ موظف يتضمّن اسمه السلسلة النصية "John"
	</li>
</ul>
<p>
	في المثال أعلاه، سيعيد الاستعلام الموظفَ رقم 2، والذي يحمل الاسم "John"، وكذلك الموظف رقم 4، والذي يحمل الاسم "Johnathon".
</p>

<h3>
	Where EXISTS
</h3>

<p>
	في المثال التالي، تختار العبارة <code>WHERE EXISTS</code> سجلّات <code>‎TableName‎</code> التي تطابق سجلاتٍ في الجدول <code>‎TableName1‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_83" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> t WHERE EXISTS </span><span class="pun">(</span><span class="pln">
 SELECT </span><span class="lit">1</span><span class="pln"> FROM </span><span class="typ">TableName1</span><span class="pln"> t1 </span><span class="kwd">where</span><span class="pln"> t</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> t1</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">)</span></pre>

<h3>
	استخدام HAVING للتحقق من عدة شروط
</h3>

<p>
	إليك جدول الطلبات التالي:
</p>

<table>
<thead><tr>
<th>
				CustomerId
			</th>
			<th>
				ProductId
			</th>
			<th>
				Quantity
			</th>
			<th>
				Price
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				5
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				3
			</td>
			<td>
				2
			</td>
			<td>
				200
			</td>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				4
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				4
			</td>
			<td>
				50
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				5
			</td>
			<td>
				6
			</td>
			<td>
				700
			</td>
		</tr>
</tbody>
</table>
<p>
	للحصول على العملاء الذين طلبوا المنتَجَين ذوي المُعرّف 2 و 3، يمكن استخدام العبارة HAVING:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_85" style="">
<span class="pln"> </span><span class="kwd">select</span><span class="pln"> customerId
 </span><span class="kwd">from</span><span class="pln"> orders
 </span><span class="kwd">where</span><span class="pln"> productID </span><span class="kwd">in</span><span class="pln"> </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="lit">3</span><span class="pun">)</span><span class="pln">
 </span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> customerId
 having count</span><span class="pun">(</span><span class="pln">distinct productID</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				customerId
			</th>
		</tr></thead>
<tbody><tr>
<td>
				1
			</td>
		</tr></tbody>
</table>
<p>
	لن يختار الاستعلام إلا السجلات ذات معرّفات المنتجات المحددة، والتي تحقق شرط <code>HAVING</code>، أي وجود معرّفين اثنين للمنتجات (productIds)، وليس معرّفًا واحدًا فقط.
</p>

<p>
	هذه صياغة أخرى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_87" style="">
<span class="pln"> </span><span class="kwd">select</span><span class="pln"> customerId
 </span><span class="kwd">from</span><span class="pln"> orders
 </span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> customerId
 having sum</span><span class="pun">(</span><span class="kwd">case</span><span class="pln"> </span><span class="kwd">when</span><span class="pln"> productID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="kwd">then</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
     </span><span class="kwd">and</span><span class="pln"> sum</span><span class="pun">(</span><span class="kwd">case</span><span class="pln"> </span><span class="kwd">when</span><span class="pln"> productID </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="kwd">then</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> </span><span class="kwd">else</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> </span><span class="kwd">end</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span></pre>

<p>
	لن يختار هذا الاستعلام إلا المجموعات التي لها سجل واحد على الأقل يساوي معرّف منتجه (productID) القيمة 2، وسجل واحد على الأقل يساوي معرّف منتجه 3.
</p>

<h2>
	ترقيم الصفحات Pagination
</h2>

<p>
	يمكن وضع حدّ لعدد النتائج المُعادة في استعلام معين، لكنّ الصياغة تختلف بحسب النظام المُستخدم:
</p>

<ul>
<li>
		في إصدار SQL القياسي ISO / ANSI:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_89" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> FETCH FIRST </span><span class="lit">20</span><span class="pln"> ROWS ONLY</span><span class="pun">;</span></pre>

<ul>
<li>
		MySQL و PostgreSQL و SQLite:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_91" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> LIMIT </span><span class="lit">20</span><span class="pun">;</span></pre>

<ul>
<li>
		Oracle :
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_93" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">Col1</span><span class="pln">
FROM </span><span class="pun">(</span><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Col1</span><span class="pun">,</span><span class="pln">
 row_number</span><span class="pun">()</span><span class="pln"> over </span><span class="pun">(</span><span class="pln">order </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> </span><span class="typ">RowNumber</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pun">)</span><span class="pln">
WHERE </span><span class="typ">RowNumber</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">20</span></pre>

<ul>
<li>
		SQL Server:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_95" style="">
<span class="pln">SELECT TOP </span><span class="lit">20</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
FROM dbo</span><span class="pun">.[</span><span class="typ">Sale</span><span class="pun">]</span></pre>

<p>
	قد ترغب أحيانًا في تخطّي عدد من نتائج الاستعلام وتأخذ النتائج الموالية لها، يمكنك ذلك عبر الصياغة التالية:
</p>

<ul>
<li>
		ISO / ANSI SQL:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_97" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Col1</span><span class="pln">
FROM </span><span class="typ">TableName</span><span class="pln">
ORDER BY </span><span class="typ">Id</span><span class="pln">
OFFSET </span><span class="lit">20</span><span class="pln"> ROWS FETCH NEXT </span><span class="lit">20</span><span class="pln"> ROWS ONLY</span><span class="pun">;</span></pre>

<ul>
<li>
		MySQL:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_99" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> LIMIT </span><span class="lit">20</span><span class="pun">,</span><span class="pln"> </span><span class="lit">20</span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> offset</span><span class="pun">,</span><span class="pln"> limit</span></pre>

<ul>
<li>
		Oracle و SQL Server:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_102" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">Col1</span><span class="pln">
 FROM </span><span class="pun">(</span><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Col1</span><span class="pun">,</span><span class="pln">
 row_number</span><span class="pun">()</span><span class="pln"> over </span><span class="pun">(</span><span class="pln">order </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> </span><span class="typ">RowNumber</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pun">)</span><span class="pln">
WHERE </span><span class="typ">RowNumber</span><span class="pln"> BETWEEN </span><span class="lit">21</span><span class="pln"> AND </span><span class="lit">40</span></pre>

<ul>
<li>
		PostgreSQL و SQLite:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_104" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> LIMIT </span><span class="lit">20</span><span class="pln"> OFFSET </span><span class="lit">20</span><span class="pun">;</span></pre>

<p>
	يمكنك كذلك تخطي بعض الصفوف من نتائج الاستعلام على النحو التالي:
</p>

<ul>
<li>
		ISO / ANSI SQL:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_106" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Col1</span><span class="pln">
FROM </span><span class="typ">TableName</span><span class="pln">
ORDER BY </span><span class="typ">Id</span><span class="pln">
OFFSET </span><span class="lit">20</span><span class="pln"> ROWS</span></pre>

<ul>
<li>
		MySQL:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_108" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> LIMIT </span><span class="lit">20</span><span class="pun">,</span><span class="pln"> </span><span class="lit">42424242424242</span><span class="pun">;</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="pun">تخطي</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> </span><span class="pun">صفا،</span><span class="pln"> </span><span class="pun">بالنسبة</span><span class="pln"> </span><span class="pun">لعدد</span><span class="pln"> </span><span class="pun">الصفوف</span><span class="pln"> </span><span class="pun">المأخوذة،</span><span class="pln"> </span><span class="pun">استخدم</span><span class="pln"> </span><span class="pun">عددا</span><span class="pln"> </span><span class="pun">كبيرا</span><span class="pln"> </span><span class="pun">يتجاوز</span><span class="pln"> </span><span class="pun">عدد</span><span class="pln"> </span><span class="pun">الصفوف</span><span class="pln"> </span><span class="pun">في</span><span class="pln"> </span><span class="pun">الجدول</span></pre>

<ul>
<li>
		Oracle:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_110" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">Col1</span><span class="pln">
FROM </span><span class="pun">(</span><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
           </span><span class="typ">Col1</span><span class="pun">,</span><span class="pln">
 row_number</span><span class="pun">()</span><span class="pln"> over </span><span class="pun">(</span><span class="pln">order </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> </span><span class="typ">RowNumber</span><span class="pln">
 FROM </span><span class="typ">TableName</span><span class="pun">)</span><span class="pln">
WHERE </span><span class="typ">RowNumber</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">20</span></pre>

<ul>
<li>
		PostgreSQL:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_112" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> OFFSET </span><span class="lit">20</span><span class="pun">;</span></pre>

<ul>
<li>
		SQLite:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_114" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> LIMIT </span><span class="pun">-</span><span class="lit">1</span><span class="pln"> OFFSET </span><span class="lit">20</span><span class="pun">;</span></pre>

<h2>
	EXCEPT
</h2>

<p>
	يمكنك استثناء مجموعة من البيانات عبر استخدام الكلمة المفتاحية <code>EXCEPT</code>.
</p>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_116" style="">
<span class="pun">--</span><span class="pln"> </span><span class="pun">ينبغي</span><span class="pln"> </span><span class="pun">أن</span><span class="pln"> </span><span class="pun">تكون</span><span class="pln"> </span><span class="pun">مجموعات</span><span class="pln"> </span><span class="pun">البيانات</span><span class="pln"> </span><span class="pun">متماثلة</span><span class="pln">
SELECT </span><span class="str">'Data1'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln"> UNION ALL
SELECT </span><span class="str">'Data2'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln"> UNION ALL
SELECT </span><span class="str">'Data3'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln"> UNION ALL
SELECT </span><span class="str">'Data4'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln"> UNION ALL
SELECT </span><span class="str">'Data5'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln">
EXCEPT
SELECT </span><span class="str">'Data3'</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">'Column'</span><span class="pln">
</span><span class="pun">--</span><span class="pln"> </span><span class="pun">==&gt;</span><span class="pln">  </span><span class="typ">Data1</span><span class="pln"> </span><span class="pun">و</span><span class="pln"> </span><span class="typ">Data2</span><span class="pln"> </span><span class="pun">و</span><span class="pln"> </span><span class="typ">Data4</span><span class="pln"> </span><span class="pun">و</span><span class="pln"> </span><span class="typ">Data5</span></pre>

<h2>
	EXPLAIN و DESCRIBE
</h2>

<h3>
	استعمال EXPLAIN في استعلامات الاختيار
</h3>

<p>
	عند وضع <code>‎Explain‎</code> قُبالة استعلام <code>‎select‎</code>، سيعرض محرّك قاعدة البيانات بعض البيانات التي توضّح كيفية تنفيذ الاستعلام. يمكنك استخدام هذه البيانات لفهم الشيفرة ومن ثَمَّ تحسينها، مثلًا، لو لاحظت أنّ الاستعلام لا يستخدم فهرسًا، فيمكنك تحسين استعلامك عن طريق إضافة فهرس.
</p>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_118" style="">
<span class="pln">explain </span><span class="kwd">select</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> user join data on user</span><span class="pun">.</span><span class="pln">test </span><span class="pun">=</span><span class="pln"> data</span><span class="pun">.</span><span class="pln">fk_user</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<pre class="ipsCode">
id  select_type  table   type     possible_keys  key       key_len ref          rows  Extra
1   SIMPLE       user    index   test                   test      5            (null)       1      Using where; Using index
1   SIMPLE       data    ref       fk_user             fk_user 5           user.tes t 1     (null)
</pre>

<p>
	يحدد العمود <code>‎type‎</code> ما إذا كان الاستعلام يستخدم الفهرس أم لا. وفي العمود <code>‎possible_keys‎</code>، سترى ما إذا كان بالإمكان تنفيذ الاستعلام بواسطة فهارس أخرى إن لم يتوافر الفهرس. يعرض <code>‎key‎</code> الفهرس المستخدم، فيما يعرض العمود <code>‎key_len‎</code> حجم عنصر من الفهرس (بالبايتات bytes)، وكلما انخفضت هذه القيمة، زاد عدد عناصر الفهرس التي يمكن تخزينها في مساحة معينة من الذاكرة، وهو ما يسرّع معالجتها. يعرض العمود <code>‎rows‎</code> العدد المتوقع للصفوف التي يحتاج الاستعلام إلى جردها، كلما كان هذا العدد أصغر، كان الأداء أفضل.
</p>

<h3>
	DESCRIBE tablename
</h3>

<p>
	<code>‎DESCRIBE‎</code> و EXPLAIN متماثلتان، بيد أنّ <code>‎DESCRIBE‎</code> تعيد معلومات تعريفية لأعمدة الجدول tablename:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_120" style="">
<span class="pln">DESCRIBE tablename</span><span class="pun">;</span></pre>

<p>
	النتيجة:
</p>

<pre class="ipsCode">
COLUMN_NAME     COLUMN_TYPE     IS_NULLABLE     COLUMN_KEY     COLUMN_DEFAULT    EXTRA
id                              int(11)                       NO                      PRI                         0                                 auto_increment
test                           varchar(255)            YES                                                     (null) 
</pre>

<p>
	عُرِضت أسماء الأعمدة متبوعة بنوعها، إضافة إلى توضيح ما إذا كان من الممكن استخدام <code>‎null‎</code> في العمود، وما إذا كان العمود يستخدم فهرسًا. تُعرض أيضًا القيمة الافتراضية للعمود، وما إذا كان الجدول ينطوي على أّي سلوك خاص، مثل <code>‎auto_increment‎</code>.
</p>

<h2>
	العبارة EXISTS
</h2>

<p>
	إليك جدول العملاء التالي:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FirstName
			</th>
			<th>
				LastName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				Ozgur
			</td>
			<td>
				Ozturk
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Youssef
			</td>
			<td>
				Medi
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Henry
			</td>
			<td>
				Tai
			</td>
		</tr>
</tbody>
</table>
<p>
	وهذا جدول آخر للطلبيّات:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				CustomerId
			</th>
			<th>
				Amount
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				123.50
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				3
			</td>
			<td>
				14.80
			</td>
		</tr>
</tbody>
</table>
<p>
	تعيد هذه الشيفرة جميع العملاء الذين قدموا طلبية واحدة على الأقل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_122" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customer</span><span class="pln"> WHERE EXISTS </span><span class="pun">(</span><span class="pln">
 SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Order</span><span class="pln"> WHERE </span><span class="typ">Order</span><span class="pun">.</span><span class="typ">CustomerId</span><span class="pun">=</span><span class="typ">Customer</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
</span><span class="pun">)</span></pre>

<p>
	النتيجة المتوقعة:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FirstName
			</th>
			<th>
				LastName
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				2
			</td>
			<td>
				Youssef
			</td>
			<td>
				Medi
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Henry
			</td>
			<td>
				Tai
			</td>
		</tr>
</tbody>
</table>
<p>
	يعيد الاستعلام التالي جميع العملاء الذين لم يقدّمو أيّ طلبية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4305_124" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Customer</span><span class="pln"> WHERE NOT EXISTS </span><span class="pun">(</span><span class="pln">
 SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Order</span><span class="pln"> WHERE </span><span class="typ">Order</span><span class="pun">.</span><span class="typ">CustomerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Customer</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
</span><span class="pun">)</span></pre>

<p>
	النتيجة المتوقّعة:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				FirstName
			</th>
			<th>
				LastName
			</th>
		</tr></thead>
<tbody><tr>
<td>
				1
			</td>
			<td>
				Ozgur
			</td>
			<td>
				Ozturk
			</td>
		</tr></tbody>
</table>
<p>
	تُستخدم <code>‎EXISTS‎</code> و <code>IN</code> و <code>‎JOIN‎</code> أحيانًا للحصول على النتائج نفسها، بيْد أنّ هناك اختلافات في كيفية عملها:
</p>

<ul>
<li>
		تُستخدم <code>‎EXISTS‎</code> للتحقق من وجود قيمة في جدول آخر.
	</li>
	<li>
		تُستخدم <code>‎IN‎</code> للحصول على قائمة ثابتة.
	</li>
	<li>
		تُستخدم <code>‎JOIN‎</code> لاسترجاع البيانات من جداول أخرى.
	</li>
</ul>
<p>
	ترجمة -وبتصرّف- للفصول من 11 إلى 17 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AF%D9%85%D8%AC-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r849/" rel="">الدمج بين الجداول في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%AA%D8%B9%D9%84%D9%8A%D9%85%D8%A7%D8%AA-%D8%B4%D8%B1%D8%B7%D9%8A%D8%A9-%D8%B9%D8%A8%D8%B1-case-%D9%81%D9%8A-sql-r847/" rel="">تنفيذ تعليمات شرطية عبر CASE في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">848</guid><pubDate>Wed, 01 Apr 2020 13:02:00 +0000</pubDate></item><item><title>&#x62A;&#x646;&#x641;&#x64A;&#x630; &#x62A;&#x639;&#x644;&#x64A;&#x645;&#x627;&#x62A; &#x634;&#x631;&#x637;&#x64A;&#x629; &#x639;&#x628;&#x631; CASE &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%AA%D8%B9%D9%84%D9%8A%D9%85%D8%A7%D8%AA-%D8%B4%D8%B1%D8%B7%D9%8A%D8%A9-%D8%B9%D8%A8%D8%B1-case-%D9%81%D9%8A-sql-r847/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/4.jpg.8c5a001c1290339543b59951479a4e4a.jpg" /></p>

<p>
	تستعرض هذه المقالة العبارة <code>CASE</code>، والتي تُستخدم لكتابة الشيفرات الشرطية (if-then).
</p>

<h2>
	استخدام CASE لحساب عدد الصفوف في العمود الذي يلبي شرطا معينًا
</h2>

<p>
	يمكن استخدام <code>‎CASE‎</code> مع <code>SUM</code> لحساب عدد العناصر المطابقة لشرط محدد (تشبه العبارة <code>‎COUNTIF‎</code> في Excel.)
</p>

<p>
	الحيلة التي سنعتمدها هي أنّنا سنعيد نتائج ثنائية (binary) للدلالة على مطابقة الشرط، حيث يشير 1 إلى أنّ المدخل يطابق الشرط، فيما يشير 0 إلى عدم المطابقة، بعد ذلك سنجمع الوحدات التي حصلنا عليها للحصول على عدد المطابقات.
</p>

<p>
	في الجدول <code>‎ItemSales‎</code> التالي، سنحاول عدّ العناصر الثمينة (EXPENSIVE):
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				ItemId
			</th>
			<th>
				Price
			</th>
			<th>
				PriceRating
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				145
			</td>
			<td>
				2.3
			</td>
			<td>
				CHEAP
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				145
			</td>
			<td>
				10
			</td>
			<td>
				AFFORDABLE
			</td>
		</tr>
</tbody>
</table>
<p>
	سنستخدم الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_7" style="">
<span class="pln">SELECT
 COUNT</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ItemsCount</span><span class="pun">,</span><span class="pln">
 SUM </span><span class="pun">(</span><span class="pln"> CASE
 WHEN </span><span class="typ">PriceRating</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Expensive'</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln">
 ELSE </span><span class="lit">0</span><span class="pln">
         </span><span class="kwd">END</span><span class="pln">
       </span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ExpensiveItemsCount</span><span class="pln">
FROM </span><span class="typ">ItemSales</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				ItemsCount
			</th>
			<th>
				ExpensiveItemsCount
			</th>
		</tr></thead>
<tbody><tr>
<td>
				5
			</td>
			<td>
				3
			</td>
		</tr></tbody>
</table>
<p>
	هذا استعلام آخر بديل:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_9" style="">
<span class="pln">SELECT
 COUNT</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">ItemsCount</span><span class="pun">,</span><span class="pln">
 SUM </span><span class="pun">(</span><span class="pln">
 CASE </span><span class="typ">PriceRating</span><span class="pln">
 WHEN </span><span class="str">'Expensive'</span><span class="pln"> THEN </span><span class="lit">1</span><span class="pln">
 ELSE </span><span class="lit">0</span><span class="pln">
 </span><span class="kwd">END</span><span class="pln">
 </span><span class="pun">)</span><span class="pln"> AS </span><span class="typ">ExpensiveItemsCount</span><span class="pln">
FROM </span><span class="typ">ItemSales</span></pre>

<h2>
	البحث الشرطي
</h2>

<p>
	يمكن استخدام <code>CASE</code> مع العبارة <code>SELECT</code> لتصفية النتائج حسب شرط معيّن، بحيث لا تُعاد إلا النتائج التي تعيد القيمة المنطقية <code>TRUE</code> (هذا يختلف عن استخدام case العادي، والذي يتحقق من التكافؤ مع المُدخل وحسب).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_11" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Price</span><span class="pun">,</span><span class="pln">
     CASE WHEN </span><span class="typ">Price</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> THEN </span><span class="str">'CHEAP'</span><span class="pln">
 WHEN </span><span class="typ">Price</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">20</span><span class="pln"> THEN </span><span class="str">'AFFORDABLE'</span><span class="pln">
 ELSE </span><span class="str">'EXPENSIVE'</span><span class="pln">
     </span><span class="kwd">END</span><span class="pln"> AS </span><span class="typ">PriceRating</span><span class="pln">
FROM </span><span class="typ">ItemSales</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				ItemId
			</th>
			<th>
				Price
			</th>
			<th>
				PriceRating
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				145
			</td>
			<td>
				2.3
			</td>
			<td>
				CHEAP
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				100
			</td>
			<td>
				34.5
			</td>
			<td>
				EXPENSIVE
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				145
			</td>
			<td>
				10
			</td>
			<td>
				AFFORDABLE
			</td>
		</tr>
</tbody>
</table>
<h3>
	الشكل المُختزل لـ CASE
</h3>

<p>
	يقيّم الشكل المختزل لـ <code>‎CASE‎</code> تعبيرًا ما (عادةً ما يكون عمودًا)، ويقارنه بعدة قيم. هذا الشكل أقصر قليلاً من الشكل العادي، ويُعفيك من تكرار التعبير المقيَّم.
</p>

<p>
	يمكن استخدام صياغة <code>‎ELSE‎</code> في الشكل على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_13" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Price</span><span class="pun">,</span><span class="pln">
 CASE </span><span class="typ">Price</span><span class="pln"> WHEN </span><span class="lit">5</span><span class="pln">  THEN </span><span class="str">'CHEAP'</span><span class="pln">
 WHEN </span><span class="lit">15</span><span class="pln"> THEN </span><span class="str">'AFFORDABLE'</span><span class="pln">
 ELSE </span><span class="str">'EXPENSIVE'</span><span class="pln">
 </span><span class="kwd">END</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="typ">PriceRating</span><span class="pln">
FROM </span><span class="typ">ItemSales</span></pre>

<p>
	من المهم أن تدرك أنه عند استخدام الشكل المختصر، فسيُقيَّم التعبير بالكامل في كل عبارة <code>‎WHEN‎</code>. لذلك، فإنّ الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_15" style="">
<span class="pln">SELECT
 CASE ABS</span><span class="pun">(</span><span class="pln">CHECKSUM</span><span class="pun">(</span><span class="pln">NEWID</span><span class="pun">()))</span><span class="pln"> </span><span class="pun">%</span><span class="pln"> </span><span class="lit">4</span><span class="pln">
 WHEN </span><span class="lit">0</span><span class="pln"> THEN </span><span class="str">'Dr'</span><span class="pln">
 WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="str">'Master'</span><span class="pln">
 WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="str">'Mr'</span><span class="pln">
 WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="str">'Mrs'</span><span class="pln">
 </span><span class="kwd">END</span></pre>

<p>
	قد تعيد القيمة المعدومة <code>‎NULL‎</code>. لأنّه في كل عبارة <code>‎WHEN‎</code>، تُستدعى <code>‎NEWID()‎</code> مع نتيجة جديدة. هذا يكافئ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_17" style="">
<span class="pln">SELECT
 CASE
 WHEN ABS</span><span class="pun">(</span><span class="pln">CHECKSUM</span><span class="pun">(</span><span class="pln">NEWID</span><span class="pun">()))</span><span class="pln"> </span><span class="pun">%</span><span class="pln"> </span><span class="lit">4</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln"> THEN </span><span class="str">'Dr'</span><span class="pln">
 WHEN ABS</span><span class="pun">(</span><span class="pln">CHECKSUM</span><span class="pun">(</span><span class="pln">NEWID</span><span class="pun">()))</span><span class="pln"> </span><span class="pun">%</span><span class="pln"> </span><span class="lit">4</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span><span class="pln"> THEN </span><span class="str">'Master'</span><span class="pln">
 WHEN ABS</span><span class="pun">(</span><span class="pln">CHECKSUM</span><span class="pun">(</span><span class="pln">NEWID</span><span class="pun">()))</span><span class="pln"> </span><span class="pun">%</span><span class="pln"> </span><span class="lit">4</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> THEN </span><span class="str">'Mr'</span><span class="pln">
 WHEN ABS</span><span class="pun">(</span><span class="pln">CHECKSUM</span><span class="pun">(</span><span class="pln">NEWID</span><span class="pun">()))</span><span class="pln"> </span><span class="pun">%</span><span class="pln"> </span><span class="lit">4</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> THEN </span><span class="str">'Mrs'</span><span class="pln">
 </span><span class="kwd">END</span></pre>

<p>
	لذلك يمكن أن تُفوِّت جميع عبارات <code>‎WHEN‎</code>، لتُنتج القيمة <code>‎NULL‎</code>.
</p>

<h3>
	استخدام CASE في عبارة ORDER BY
</h3>

<p>
	في الشيفرة، أدناه سنستخدم الأرقام 1،2،3 .. لتصنيف الطلب إلى أنواع:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_19" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM DEPT
ORDER BY
CASE DEPARTMENT
 WHEN </span><span class="str">'MARKETING'</span><span class="pln"> THEN  </span><span class="lit">1</span><span class="pln">
 WHEN </span><span class="str">'SALES'</span><span class="pln"> THEN </span><span class="lit">2</span><span class="pln">
 WHEN </span><span class="str">'RESEARCH'</span><span class="pln"> THEN </span><span class="lit">3</span><span class="pln">
 WHEN </span><span class="str">'INNOVATION'</span><span class="pln"> THEN </span><span class="lit">4</span><span class="pln">
 ELSE        </span><span class="lit">5</span><span class="pln">
 </span><span class="kwd">END</span><span class="pun">,</span><span class="pln">
          CITY</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				ID
			</th>
			<th>
				REGION
			</th>
			<th>
				CITY
			</th>
			<th>
				DEPARTMENT
			</th>
			<th>
				EMPLOYEES_NUMBER
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				12
			</td>
			<td>
				New England
			</td>
			<td>
				Boston
			</td>
			<td>
				MARKETING
			</td>
			<td>
				9
			</td>
		</tr>
<tr>
<td>
				15
			</td>
			<td>
				West
			</td>
			<td>
				San Francisco
			</td>
			<td>
				MARKETING
			</td>
			<td>
				12
			</td>
		</tr>
<tr>
<td>
				9
			</td>
			<td>
				Midwest
			</td>
			<td>
				Chicago
			</td>
			<td>
				SALES
			</td>
			<td>
				8
			</td>
		</tr>
<tr>
<td>
				14
			</td>
			<td>
				Mid-Atlantic
			</td>
			<td>
				New York
			</td>
			<td>
				SALES
			</td>
			<td>
				12
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				West
			</td>
			<td>
				Los Angeles
			</td>
			<td>
				RESEARCH
			</td>
			<td>
				11
			</td>
		</tr>
<tr>
<td>
				10
			</td>
			<td>
				Mid-Atlantic
			</td>
			<td>
				Philadelphia
			</td>
			<td>
				RESEARCH
			</td>
			<td>
				13
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Midwest
			</td>
			<td>
				Chicago
			</td>
			<td>
				INNOVATION
			</td>
			<td>
				11
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Midwest
			</td>
			<td>
				Detroit
			</td>
			<td>
				HUMAN RESOURCES
			</td>
			<td>
				9
			</td>
		</tr>
</tbody>
</table>
<h3>
	استخدام CASE في UPDATE
</h3>

<p>
	يزيد المثال التالي الأسعار في قاعدة البيانات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_21" style="">
<span class="pln">UPDATE </span><span class="typ">ItemPrice</span><span class="pln">
SET </span><span class="typ">Price</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Price</span><span class="pln"> </span><span class="pun">*</span><span class="pln">
   CASE </span><span class="typ">ItemId</span><span class="pln">
 WHEN </span><span class="lit">1</span><span class="pln"> THEN </span><span class="lit">1.05</span><span class="pln">
 WHEN </span><span class="lit">2</span><span class="pln"> THEN </span><span class="lit">1.10</span><span class="pln">
 WHEN </span><span class="lit">3</span><span class="pln"> THEN </span><span class="lit">1.15</span><span class="pln">
 ELSE </span><span class="lit">1.00</span><span class="pln">
    </span><span class="kwd">END</span></pre>

<h2>
	استخدام CASE مع القيم المعدومة NULL
</h2>

<p>
	في هذا المثال، يمثل الرقم "0" االقيم المعروفة، والتي توضوع في البداية، فيما يمثل "1" القيم <code>NULL</code>، و هي موضوعة في آخر الترتيب:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_23" style="">
<span class="pln">SELECT ID
 </span><span class="pun">,</span><span class="pln">REGION
 </span><span class="pun">,</span><span class="pln">CITY
 </span><span class="pun">,</span><span class="pln">DEPARTMENT
 </span><span class="pun">,</span><span class="pln">EMPLOYEES_NUMBER
   FROM DEPT
   ORDER BY
   CASE WHEN REGION IS NULL THEN </span><span class="lit">1</span><span class="pln">
   ELSE </span><span class="lit">0</span><span class="pln">
   </span><span class="kwd">END</span><span class="pun">,</span><span class="pln">
   REGION</span></pre>

<p>
	سنحصل على الخرج التالي:
</p>

<table>
<thead><tr>
<th>
				ID
			</th>
			<th>
				REGION
			</th>
			<th>
				CITY
			</th>
			<th>
				DEPARTMENT
			</th>
			<th>
				EMPLOYEES_NUMBER
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				10
			</td>
			<td>
				Mid-Atlantic
			</td>
			<td>
				Philadelphia
			</td>
			<td>
				RESEARCH
			</td>
			<td>
				13
			</td>
		</tr>
<tr>
<td>
				14
			</td>
			<td>
				Mid-Atlantic
			</td>
			<td>
				New York
			</td>
			<td>
				SALES
			</td>
			<td>
				12
			</td>
		</tr>
<tr>
<td>
				9
			</td>
			<td>
				Midwest
			</td>
			<td>
				Chicago
			</td>
			<td>
				SALES
			</td>
			<td>
				8
			</td>
		</tr>
<tr>
<td>
				12
			</td>
			<td>
				New England
			</td>
			<td>
				Boston
			</td>
			<td>
				MARKETING
			</td>
			<td>
				9
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				West
			</td>
			<td>
				Los Angeles
			</td>
			<td>
				RESEARCH
			</td>
			<td>
				11
			</td>
		</tr>
<tr>
<td>
				15
			</td>
			<td>
				NULL
			</td>
			<td>
				San Francisco
			</td>
			<td>
				MARKETING
			</td>
			<td>
				12
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				NULL
			</td>
			<td>
				Chicago
			</td>
			<td>
				INNOVATION
			</td>
			<td>
				11
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				NULL
			</td>
			<td>
				Detroit
			</td>
			<td>
				HUMAN RESOURCES
			</td>
			<td>
				9
			</td>
		</tr>
</tbody>
</table>
<h2>
	استخدام CASE في عبارة ORDER BY لترتيب السجلات حسب القيمة الدنيا لعمودين
</h2>

<p>
	لنفترض أنك بحاجة إلى ترتيب السجلات حسب القيمة الدنيا في عمودين. قد تستخدم بعض قواعد البيانات الدالتين غير التجميعيتين <code>‎MIN()‎</code> أو <code>‎LEAST()‎</code> (مثلا: <code>‎... ORDER BY MIN(Date1, Date2)‎</code>)، ولكن في SQL القياسية، يجب استخدام التعبير <code>‎CASE‎</code>.
</p>

<p>
	يبحث التعبير <code>‎CASE‎</code> في الاستعلام أدناه في العمودين <code>‎Date1‎</code> و <code>‎Date2‎</code> ، ويبحث عن العمود الذي له أدنى قيمة، ثم يرتب السجلات وفقًا لتلك القيمة.
</p>

<p>
	إليك الجدول التالي:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Date1
			</th>
			<th>
				Date2
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				2017-01-01
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-03
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-02
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				2017-01-06
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-05
			</td>
		</tr>
<tr>
<td>
				6
			</td>
			<td>
				2017-01-04
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
</tbody>
</table>
<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_9991_25" style="">
<span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Date1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Date2</span><span class="pln">
FROM </span><span class="typ">YourTable</span><span class="pln">
ORDER BY CASE
       WHEN COALESCE</span><span class="pun">(</span><span class="typ">Date1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1753-01-01'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> COALESCE</span><span class="pun">(</span><span class="typ">Date2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1753-01-01'</span><span class="pun">)</span><span class="pln"> THEN </span><span class="typ">Date1</span><span class="pln">
       ELSE </span><span class="typ">Date2</span><span class="pln">
   </span><span class="kwd">END</span></pre>

<p>
	الخرج النتائج:
</p>

<table>
<thead><tr>
<th>
				Id
			</th>
			<th>
				Date1
			</th>
			<th>
				Date2
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				1
			</td>
			<td>
				2017-01-01
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-02
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-03
			</td>
		</tr>
<tr>
<td>
				6
			</td>
			<td>
				2017-01-04
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				2017-01-31
			</td>
			<td>
				2017-01-05
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				2017-01-06
			</td>
			<td>
				2017-01-31
			</td>
		</tr>
</tbody>
</table>
<p>
	كما ترى ، الصف ذو المعّرف <code>‎Id = 1‎</code> جاء أولًا، وذلك لأنّ العمود <code>‎Date1‎</code> يحتوي أدنى سجل في الجدول، وهو <code>‎2017-01-01‎</code>، الصف ذو المعرّف <code>‎Id‎</code> = <code>‎3‎</code> جاء ثانيًا، لأنّ العمود <code>‎Date2‎</code> يحتوي القيمة<code>‎2017-01-02‎‎</code>، وهي ثاني أقل قيمة في الجدول، وهكذا دواليك.
</p>

<p>
	لقد رتّبنا السجلات من <code>‎2017-01-01‎</code> إلى <code>‎2017-01-06‎</code> تصاعديًا، بغض النظر عن العمود <code>‎Date1‎</code> أو <code>‎Date2‎</code> الذي جاءت منه تلك القيم.
</p>

<p>
	ترجمة -وبتصرّف- للفصول 7 و8 و9 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D8%AD%D8%AB-%D9%88%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%8A%D8%A8-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%B4%D9%8A%D8%AD-%D9%81%D9%8A-sql-r848/" rel="">البحث والتنقيب والترشيح في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D9%81%D9%8A-sql-r846/" rel="">التجميع والترتيب في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة من كتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">847</guid><pubDate>Sat, 28 Mar 2020 13:09:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x62C;&#x645;&#x64A;&#x639; &#x648;&#x627;&#x644;&#x62A;&#x631;&#x62A;&#x64A;&#x628; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D9%81%D9%8A-sql-r846/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/3.jpg.9d5c646c04a9e6e8d860a974fa9f6065.jpg" /></p>

<p>
	سنتحدث في هذه المقالة عن كيفية استخدام العبارتين <code>GROUP BY</code> و <code>ORDER BY</code> لأجل تجميع نتائج الاستعلامات في SQL وترتيبها.
</p>

<h2>
	التجميع عبر GROUP BY
</h2>

<p>
	يمكن تجميع نتائج استعلام <code>SELECT</code> حسب عمود واحد أو أكثر باستخدام عبارة <code>‎GROUP BY‎</code> والتي تُجمّع كل النتائج التي لها نفس القيمة في الأعمدة المُجمَّعة (grouped columns). وينتج عنها جدول من النتائج الجزئية، بدلًا من إرجاع نتيجة واحدة.
</p>

<p>
	يمكن استخدام <code>GROUP BY</code> مع دوال التجميع (aggregation functions) لتحديد كيفية تجميع الأعمدة باستخدام العبارة <code>‎HAVING‎</code>.
</p>

<h3>
	مثال على استخدام GROUP BY
</h3>

<p>
	تشبه <code>GROUP BY</code> عبارة <code>for each</code> المُستخدمة في الكثير من لغات البرمجة.
</p>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_7" style="">
<span class="pln">SELECT </span><span class="typ">EmpID</span><span class="pun">,</span><span class="pln"> SUM </span><span class="pun">(</span><span class="typ">MonthlySalary</span><span class="pun">)</span><span class="pln">
FROM </span><span class="typ">Employee</span><span class="pln">
GROUP BY </span><span class="typ">EmpID</span></pre>

<p>
	في الشيفرة أعلاه، نريد الحصول على مجموع الحقل <code>MonthlySalary</code> لكل قيم <code>EmpID</code>، مثلًا، في الجدول التالي:
</p>

<pre class="ipsCode">
+-----+----------------------+
|EmpID|MonthlySalary|
+-----+----------------------+
|1      |200               |
+-----+----------------------+
|2      |300               |
+-----+----------------------+
</pre>

<p>
	سنحصل على النتيجة التالية:
</p>

<pre class="ipsCode">
+-+---+
|1|200|
+-+---+
|2|300|
+-+---+
</pre>

<p>
	لا يبدو أنّ <code>Sum</code> تفعل أيّ شيء، وذلك لأنّ مجموع عدد ما يساوي العدد نفسه.
</p>

<p>
	إليك الآن الجدول التالي:
</p>

<pre class="ipsCode">
+-----+---------------------+
|EmpID|MonthlySalary|
+-----+---------------------+
|1    |200                |
+-----+---------------------+
|1    |300               |
+-----+---------------------+
|2    |300              |
+-----+---------------------+
</pre>

<p>
	سنحصل بتطبيق الاستعلام نفسه على النتيجة التالية:
</p>

<pre class="ipsCode">
+-+---+
|1|500|
+-+---+
|2|300|
+-+---+
</pre>

<h3>
	ترشيح نتائج GROUP BY باستخدام عبارة HAVING
</h3>

<p>
	ترشِّح عبارة <code>HAVING</code> نتائج <code>GROUP BY</code>.
</p>

<p>
	سنستخدم في الأمثلة التالية قاعدة البيانات <code>Library</code> المُعرّفة في <a href="%D8%B1%D8%A7%D8%A8%D8%B7" rel="">الفصل الأول</a>.
</p>

<h4>
	<strong>أمثلة</strong>
</h4>

<p>
	إعادة جميع المؤلفين الذين كتبوا أكثر من كتاب (<a href="http://sqlfiddle.com/#!9/7c06f/7" rel="external nofollow">مثال حي</a>).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_9" style="">
<span class="pln">SELECT
  a</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
  a</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">,</span><span class="pln">
 COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">BooksWritten</span><span class="pln">
FROM </span><span class="typ">BooksAuthors</span><span class="pln"> ba
 INNER JOIN </span><span class="typ">Authors</span><span class="pln"> a ON a</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> ba</span><span class="pun">.</span><span class="pln">authorid
GROUP BY
  a</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
  a</span><span class="pun">.</span><span class="typ">Name</span><span class="pln">
HAVING COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pln">    </span><span class="pun">--</span><span class="pln">  HAVING </span><span class="typ">BooksWritten</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1</span><span class="pln">  </span><span class="pun">يكافئ</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	إعادة جميع الكتب التي أُلِّفت من قبل ثلاثة مؤلفين أو أكثر (<a href="http://sqlfiddle.com/#!9/7c06f/9" rel="external nofollow">مثال حي</a>).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_11" style="">
<span class="pln">SELECT
  b</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
  b</span><span class="pun">.</span><span class="typ">Title</span><span class="pun">,</span><span class="pln">
 COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">NumberOfAuthors</span><span class="pln">
FROM </span><span class="typ">BooksAuthors</span><span class="pln"> ba
 INNER JOIN </span><span class="typ">Books</span><span class="pln"> b ON b</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> ba</span><span class="pun">.</span><span class="pln">bookid
GROUP BY
  b</span><span class="pun">.</span><span class="typ">Id</span><span class="pun">,</span><span class="pln">
  b</span><span class="pun">.</span><span class="typ">Title</span><span class="pln">
HAVING COUNT</span><span class="pun">(*)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">3</span><span class="pln">    </span><span class="pun">--</span><span class="pln"> HAVING </span><span class="typ">NumberOfAuthors</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">3</span><span class="pln">  </span><span class="pun">يكافئ</span><span class="pln">
</span><span class="pun">;</span></pre>

<h3>
	استخدام GROUP BY لحساب عدد الصفوف لكل مدخل فريد في عمود معيّن
</h3>

<p>
	لنفترض أننا نريد عدّ أو حساب مجاميع فرعية لقيمة معينة في عمود.
</p>

<p>
	إليك الجدول التالي:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
<thead><tr>
<th>
				Name
			</th>
			<th>
				GreatHouseAllegience
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Arya
			</td>
			<td>
				Stark
			</td>
		</tr>
<tr>
<td>
				Cercei
			</td>
			<td>
				Lannister
			</td>
		</tr>
<tr>
<td>
				Myrcella
			</td>
			<td>
				Lannister
			</td>
		</tr>
<tr>
<td>
				Yara
			</td>
			<td>
				Greyjoy
			</td>
		</tr>
<tr>
<td>
				Catelyn
			</td>
			<td>
				Stark
			</td>
		</tr>
<tr>
<td>
				Sansa
			</td>
			<td>
				Stark
			</td>
		</tr>
</tbody>
</table>
<p>
	في حال عدم استخدام العبارة <code>GROUP BY</code>، ستعيد <code>COUNT</code> إجمالي عدد الصفوف:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_13" style="">
<span class="pln">SELECT </span><span class="typ">Count</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">Number_of_Westerosians</span><span class="pln">
FROM </span><span class="typ">Westerosians</span></pre>

<p>
	سنحصل على الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				Number_of_Westerosians
			</th>
		</tr></thead>
<tbody><tr>
<td>
				6
			</td>
		</tr></tbody>
</table>
<p>
	في حال استخدام GROUP BY، يمكن عدّ المستخدمين لكل قيمة في عمود معين كما يوضح المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_15" style="">
<span class="pln">SELECT </span><span class="typ">GreatHouseAllegience</span><span class="pln"> </span><span class="typ">House</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Count</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">Number_of_Westerosians</span><span class="pln">
FROM </span><span class="typ">Westerosians</span><span class="pln">
GROUP BY </span><span class="typ">GreatHouseAllegience</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				House
			</th>
			<th>
				Number_of_Westerosians
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Stark
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				Greyjoy
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				Lannister
			</td>
			<td>
				2
			</td>
		</tr>
</tbody>
</table>
<p>
	من الشائع الجمع بين العبارتين <code>GROUP BY</code> و <code>ORDER BY</code> لترتيب النتائج تصاعديا أو تنازليًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_17" style="">
<span class="pln">SELECT </span><span class="typ">GreatHouseAllegience</span><span class="pln"> </span><span class="typ">House</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Count</span><span class="pun">(*)</span><span class="pln"> </span><span class="typ">Number_of_Westerosians</span><span class="pln">
FROM </span><span class="typ">Westerosians</span><span class="pln">
GROUP BY </span><span class="typ">GreatHouseAllegience</span><span class="pln">
ORDER BY </span><span class="typ">Number_of_Westerosians</span><span class="pln"> </span><span class="typ">Desc</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				House
			</th>
			<th>
				Number_of_Westerosians
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Stark
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				Lannister
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				Greyjoy
			</td>
			<td>
				1
			</td>
		</tr>
</tbody>
</table>
<h3>
	تجميع ROLAP (استخراج البيانات) - ROLAP aggregation
</h3>

<p>
	يوفر معيار SQL معاملين تجميعيَين (aggregate operators) إضافيين. تُستخدم القيمة <code>ALL</code> للكناية عن جميع القيم التي يمكن أن تأخذها السمة (attribute).
</p>

<p>
	المُعاملان هما:
</p>

<ul>
<li>
		<code>with data cube</code>: يوفّر كل التوليفات الممكنة لسمات وسيط العبارة (argument attributes of the clause).
	</li>
	<li>
		<code>with roll up</code>: يوفر المجموع الناتج عن اعتبار السمات مُرتّبة من اليسار إلى اليمين مع مقارنتها بكيفية إدراجها في وسيط العبارة (argument of the clause).
	</li>
</ul>
<p>
	تدعم إصدارات SQL القياسية التالية هذه الميزات: 1999 - 2003 - 2006 - 2008 - 2011.
</p>

<h4>
	أمثلة
</h4>

<p>
	إليك الجدول التالي:
</p>

<table>
<thead><tr>
<th>
				Food
			</th>
			<th>
				Brand
			</th>
			<th>
				Total_amount
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand1
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand2
			</td>
			<td>
				250
			</td>
		</tr>
<tr>
<td>
				Pizza
			</td>
			<td>
				Brand2
			</td>
			<td>
				300
			</td>
		</tr>
</tbody>
</table>
<p>
	<strong>استخدام عبارة cube</strong>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_19" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="typ">Food</span><span class="pun">,</span><span class="typ">Brand</span><span class="pun">,</span><span class="typ">Total_amount</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> </span><span class="typ">Table</span><span class="pln">
</span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">Food</span><span class="pun">,</span><span class="typ">Brand</span><span class="pun">,</span><span class="typ">Total_amount</span><span class="pln"> </span><span class="kwd">with</span><span class="pln"> cube</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				Food
			</th>
			<th>
				Brand
			</th>
			<th>
				Total_amount
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand1
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand2
			</td>
			<td>
				250
			</td>
		</tr>
<tr>
<td>
				Pasta
			</td>
			<td>
				ALL
			</td>
			<td>
				350
			</td>
		</tr>
<tr>
<td>
				Pizza
			</td>
			<td>
				Brand2
			</td>
			<td>
				300
			</td>
		</tr>
<tr>
<td>
				Pizza
			</td>
			<td>
				ALL
			</td>
			<td>
				300
			</td>
		</tr>
<tr>
<td>
				ALL
			</td>
			<td>
				Brand1
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				ALL
			</td>
			<td>
				Brand2
			</td>
			<td>
				550
			</td>
		</tr>
<tr>
<td>
				ALL
			</td>
			<td>
				ALL
			</td>
			<td>
				650
			</td>
		</tr>
</tbody>
</table>
<p>
	<strong>استخدام roll up</strong>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_21" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="typ">Food</span><span class="pun">,</span><span class="typ">Brand</span><span class="pun">,</span><span class="typ">Total_amount</span><span class="pln">
</span><span class="kwd">from</span><span class="pln"> </span><span class="typ">Table</span><span class="pln">
</span><span class="kwd">group</span><span class="pln"> </span><span class="kwd">by</span><span class="pln"> </span><span class="typ">Food</span><span class="pun">,</span><span class="typ">Brand</span><span class="pun">,</span><span class="typ">Total_amount</span><span class="pln"> </span><span class="kwd">with</span><span class="pln"> roll up</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				Food
			</th>
			<th>
				Brand
			</th>
			<th>
				Total_amount
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand1
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				Pasta
			</td>
			<td>
				Brand2
			</td>
			<td>
				250
			</td>
		</tr>
<tr>
<td>
				Pizza
			</td>
			<td>
				Brand2
			</td>
			<td>
				300
			</td>
		</tr>
<tr>
<td>
				Pasta
			</td>
			<td>
				ALL
			</td>
			<td>
				350
			</td>
		</tr>
<tr>
<td>
				Pizza
			</td>
			<td>
				ALL
			</td>
			<td>
				300
			</td>
		</tr>
<tr>
<td>
				ALL
			</td>
			<td>
				ALL
			</td>
			<td>
				650
			</td>
		</tr>
</tbody>
</table>
<h2>
	الترتيب عبر ORDER BY
</h2>

<h3>
	الترتيب حسب رقم العمود (بدلاً من اسمه)
</h3>

<p>
	يمكنك استخدام رقم العمود (يبدأ العمود الموجود في أقصى اليسار من الرقم "1") للإشارة إلى العمود الذي يستند الترتيب إليه.
</p>

<ul>
<li>
		<strong>إيجابيات</strong>: هذا الخيار مناسب في حال كانت هناك إمكانية لتغيير أسماء الأعمدة لاحقًا، لأنّه سيجنّبك كسر الشيفرة.
	</li>
	<li>
		<strong>سلبيات</strong>: سيُضعف استخدام رقم العمود بدل اسمه مقروئية الاستعلام (وازن مثلا بين <code>ORDER BY Reputation</code> و 'ORDER BY 14'.).
	</li>
</ul>
<p>
	يرتب الاستعلام التالي النتيجة حسب المعلومات الموجودة في العمود رقم <code>‎3‎</code> بدلاً من الاعتماد اسم العمود <code>‎Reputation‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_23" style="">
<span class="pln">SELECT </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JoinDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln"> FROM </span><span class="typ">Users</span><span class="pln"> ORDER BY </span><span class="lit">3</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				DisplayName
			</th>
			<th>
				JoinDate
			</th>
			<th>
				Reputation
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Community
			</td>
			<td>
				2008-09-15
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				Jarrod Dixon
			</td>
			<td>
				2008-10-03
			</td>
			<td>
				11739
			</td>
		</tr>
<tr>
<td>
				Geoﬀ Dalgas
			</td>
			<td>
				2008-10-03
			</td>
			<td>
				12567
			</td>
		</tr>
<tr>
<td>
				Joel Spolsky
			</td>
			<td>
				2008-09-16
			</td>
			<td>
				25784
			</td>
		</tr>
<tr>
<td>
				Jeﬀ Atwood
			</td>
			<td>
				2008-09-16
			</td>
			<td>
				37628
			</td>
		</tr>
</tbody>
</table>
<h3>
	استخدام ORDER BY مع TOP لإعادة أعلى س صفًّا بناءً على قيمة العمود
</h3>

<p>
	في هذا المثال، يمكنك استخدام <code>GROUP BY</code> و <code>TOP</code> لتحديد الصفوف المُعادة وترتيبها. لنفترض أنّك تريد الحصول على أفضل 5 مستخدمين من حيث السمعة في موقع متخصص في الأسئلة والأجوبة.
</p>

<h4>
	بدون ORDER BY
</h4>

<p>
	يعيد هذا الاستعلام أعلى 5 صفوف مرتبة حسب الإعداد الافتراضي، والذي هو <code>Id</code> في هذه الحالة، أي العمود الأول في الجدول (رغم أنّه لن يظهر في النتائج).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_25" style="">
<span class="pln">SELECT TOP </span><span class="lit">5</span><span class="pln"> </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln">
FROM </span><span class="typ">Users</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				DisplayName
			</th>
			<th>
				Reputation
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Community
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				Geoﬀ Dalgas
			</td>
			<td>
				12567
			</td>
		</tr>
<tr>
<td>
				Jarrod Dixon
			</td>
			<td>
				11739
			</td>
		</tr>
<tr>
<td>
				Jeﬀ Atwood
			</td>
			<td>
				37628
			</td>
		</tr>
<tr>
<td>
				Joel Spolsky
			</td>
			<td>
				25784
			</td>
		</tr>
</tbody>
</table>
<h4>
	استخدام ORDER BY
</h4>

<p>
	سنستخدم ORDER BY في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_27" style="">
<span class="pln">SELECT TOP </span><span class="lit">5</span><span class="pln"> </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln">
FROM </span><span class="typ">Users</span><span class="pln">
ORDER BY </span><span class="typ">Reputation</span><span class="pln"> desc</span></pre>

<p>
	الخرج الناتج:
</p>

<table>
<thead><tr>
<th>
				DisplayName
			</th>
			<th>
				Reputation
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				JonSkeet
			</td>
			<td>
				865023
			</td>
		</tr>
<tr>
<td>
				Darin Dimitrov
			</td>
			<td>
				661741
			</td>
		</tr>
<tr>
<td>
				BalusC
			</td>
			<td>
				650237
			</td>
		</tr>
<tr>
<td>
				Hans Passant
			</td>
			<td>
				625870
			</td>
		</tr>
<tr>
<td>
				Marc Gravell
			</td>
			<td>
				601636
			</td>
		</tr>
</tbody>
</table>
<h4>
	ملاحظات
</h4>

<p>
	تستخدم بعض إصدارات SQL (مثل MySQL) العبارة <code>‎LIMIT‎</code> في نهاية <code>‎SELECT‎</code> ، بدلًا من استخدام <code>‎TOP‎</code> في البداية كما هو موضّح في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_29" style="">
<span class="pln">SELECT </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln">
FROM </span><span class="typ">Users</span><span class="pln">
ORDER BY </span><span class="typ">Reputation</span><span class="pln"> DESC
LIMIT </span><span class="lit">5</span></pre>

<h3>
	الترتيب المخصص
</h3>

<p>
	لترتيب الجدول <code>‎Employee‎</code> حسب القسم <code>department</code>، يمكنك استخدام التعليمة <code>‎ORDER BY Department‎</code>. أمّا إن أردت ترتيبه ترتيبًا غير أبجدي، فيجب عليك تحويل قيم <code>‎Department‎</code> إلى قيم أخرى قابلة للترتيب؛ يمكن فعل ذلك باستخدام عبارة <code>CASE</code>:
</p>

<table>
<thead><tr>
<th>
				Name
			</th>
			<th>
				Department
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Hasan
			</td>
			<td>
				IT
			</td>
		</tr>
<tr>
<td>
				Yusuf
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Hillary
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Joe
			</td>
			<td>
				IT
			</td>
		</tr>
<tr>
<td>
				Merry
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Ken
			</td>
			<td>
				Accountant
			</td>
		</tr>
</tbody>
</table>
<p>
	في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_31" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Employee</span><span class="pln">
ORDER BY CASE </span><span class="typ">Department</span><span class="pln">
 WHEN </span><span class="str">'HR'</span><span class="pln">            THEN </span><span class="lit">1</span><span class="pln">
 WHEN </span><span class="str">'Accountant'</span><span class="pln">  THEN </span><span class="lit">2</span><span class="pln">
 ELSE                        </span><span class="lit">3</span><span class="pln">
 </span><span class="kwd">END</span><span class="pun">;</span></pre>

<p>
	سنحصل على الخرج:
</p>

<table>
<thead><tr>
<th>
				Name
			</th>
			<th>
				Department
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Yusuf
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Hillary
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Merry
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				Ken
			</td>
			<td>
				Accountant
			</td>
		</tr>
<tr>
<td>
				Hasan
			</td>
			<td>
				IT
			</td>
		</tr>
<tr>
<td>
				Joe
			</td>
			<td>
				IT
			</td>
		</tr>
</tbody>
</table>
<h3>
	الترتيب بالكنى
</h3>

<p>
	بسبب طريقة معالجة الاستعلامات المنطقية، يمكن ترتيب نتائج الاستعلامات حسب الكُنى (Order by Alias).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_33" style="">
<span class="pln">SELECT </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JoinDate</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> jd</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> rep
FROM </span><span class="typ">Users</span><span class="pln">
ORDER BY jd</span><span class="pun">,</span><span class="pln"> rep</span></pre>

<p>
	كما يمكن استخدام الترتيب النسبي (relative order) للأعمدة -أي الترتيب حسب رقم العمود- في عبارة الاختيار <code>select</code>. سنعود إلى المثال أعلاه، ولكن بدلاً من استخدام الكُنية، سنستخدم الترتيب النسبي.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_35" style="">
<span class="pln">SELECT </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JoinDate</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> jd</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> rep
FROM </span><span class="typ">Users</span><span class="pln">
ORDER BY </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span></pre>

<h3>
	الترتيب حسب عدة أعمدة
</h3>

<p>
	في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_37" style="">
<span class="pln">SELECT </span><span class="typ">DisplayName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">JoinDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span><span class="pln"> FROM </span><span class="typ">Users</span><span class="pln"> ORDER BY </span><span class="typ">JoinDate</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Reputation</span></pre>

<p>
	سيكون الخرج:
</p>

<table>
<thead><tr>
<th>
				DisplayName
			</th>
			<th>
				JoinDate
			</th>
			<th>
				Reputation
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Community
			</td>
			<td>
				2008-09-15
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				Jeﬀ Atwood
			</td>
			<td>
				2008-09-16
			</td>
			<td>
				25784
			</td>
		</tr>
<tr>
<td>
				Joel Spolsky
			</td>
			<td>
				2008-09-16
			</td>
			<td>
				37628
			</td>
		</tr>
<tr>
<td>
				Jarrod Dixon
			</td>
			<td>
				2008-10-03
			</td>
			<td>
				11739
			</td>
		</tr>
<tr>
<td>
				Geoﬀ Dalgas
			</td>
			<td>
				2008-10-03
			</td>
			<td>
				12567
			</td>
		</tr>
</tbody>
</table>
<h2>
	المُعاملان المنطِقيان AND و OR
</h2>

<p>
	<code>AND</code> و <code>OR</code> معاملان منطقيان يُستخدمان لبناء الشروط المنطقية.
</p>

<p>
	إليك الجدول التالي:
</p>

<table>
<thead><tr>
<th>
				Name
			</th>
			<th>
				Age
			</th>
			<th>
				City
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Bob
			</td>
			<td>
				10
			</td>
			<td>
				Paris
			</td>
		</tr>
<tr>
<td>
				Mat
			</td>
			<td>
				20
			</td>
			<td>
				Berlin
			</td>
		</tr>
<tr>
<td>
				Mary
			</td>
			<td>
				24
			</td>
			<td>
				Prague
			</td>
		</tr>
</tbody>
</table>
<p>
	في المثال التالي:
</p>

<pre class="ipsCode">
select Name from table where Age&gt;10 AND City='Prague'
</pre>

<p>
	سنحصل على الخرج:
</p>

<table>
<thead><tr>
<th>
				Name
			</th>
		</tr></thead>
<tbody><tr>
<td>
				Mary
			</td>
		</tr></tbody>
</table>
<p>
	وفي هذا المثال:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_4424_39" style="">
<span class="kwd">select</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> table </span><span class="kwd">where</span><span class="pln"> </span><span class="typ">Age</span><span class="pun">=</span><span class="lit">10</span><span class="pln"> OR </span><span class="typ">City</span><span class="pun">=</span><span class="str">'Prague'</span></pre>

<p>
	سنحصل على الخرج:
</p>

<table>
<thead><tr>
<th>
				Name
			</th>
		</tr></thead>
<tbody>
<tr>
<td>
				Bob
			</td>
		</tr>
<tr>
<td>
				Mary
			</td>
		</tr>
</tbody>
</table>
<p>
	ترجمة -وبتصرّف- للفصول 7 و8 و9 من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AA%D9%86%D9%81%D9%8A%D8%B0-%D8%AA%D8%B9%D9%84%D9%8A%D9%85%D8%A7%D8%AA-%D8%B4%D8%B1%D8%B7%D9%8A%D8%A9-%D8%B9%D8%A8%D8%B1-case-%D9%81%D9%8A-sql-r847/" rel="">تنفيذ تعليمات شرطية عبر CASE في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">جلب الاستعلامات عبر SELECT في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب<a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel=""> ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">846</guid><pubDate>Wed, 25 Mar 2020 13:05:00 +0000</pubDate></item><item><title>&#x62C;&#x644;&#x628; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645;&#x627;&#x62A; &#x639;&#x628;&#x631; SELECT &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/2.jpg.cd367449f4e524b07329dfcb37a64c42.jpg" /></p>
<p>
	تُستخدَم العبارة <code>SELECT</code> في معظم استعلامات SQL. وتتحكم في تحديد النتائج التي يجب أن يعيدها الاستعلام، وتُستخدم في العادة مع العبارة <code>FROM</code>، والتي تحدد الجزء (أو الأجزاء) من قاعدة البيانات المُستعلَم عنها.
</p>

<h2>
	استخدام حرف البدل * لاختيار جميع الأعمدة
</h2>

<p>
	إليك قاعدة البيانات التالية المؤلفة من الجدولين التاليين:
</p>

<p>
	<strong>جدول الموظفين Employees</strong>:
</p>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<table>
	<thead>
		<tr>
			<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				DeptId
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				3
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				4
			</td>
		</tr>
	</tbody>
</table>

<p>
	<strong>جدول الأقسام Departments</strong>:
</p>

<table>
	<thead>
		<tr>
			<th>
				Id
			</th>
			<th>
				Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				Sales
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				Marketing
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				Finance
			</td>
		</tr>
		<tr>
			<td>
				4
			</td>
			<td>
				IT
			</td>
		</tr>
	</tbody>
</table>

<h3>
	عبارة select بسيطة
</h3>

<p>
	يمثل الرمز <code>‎*‎</code> حرفَ البدل، ويُستخدم لاختيار جميع الأعمدة المتاحة في الجدول. عند استخدامه بديلًا عن الأسماء الصريحة للأعمدة، فإنه يعيد جميع الأعمدة في جميع الجداول التي يحددها الاستعلام <code>‎FROM‎</code>. ينطبق هذا الأمر على جميع الجداول التي يصل إليها الاستعلام عبر عبارات <code>JOIN</code>.
</p>

<p>
	إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_14" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<p>
	سيعيد الاستعلام أعلاه جميع الحقول من جميع صفوف جدول <code>‎Employees‎</code>:
</p>

<table>
	<thead>
		<tr>
			<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				DeptId
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				3
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				4
			</td>
		</tr>
	</tbody>
</table>

<h3>
	الصياغة النقطية Dot notation
</h3>

<p>
	لاختيار كل القيم من جدول محدّد، يمكن تطبيق حرف البدل على الجدول باستخدام الصياغة النقطية. إليك الاستعلام التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_16" style=""><span class="pln">SELECT
    </span><span class="typ">Employees</span><span class="pun">.*,</span><span class="pln">
    </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Name</span><span class="pln">
FROM
    </span><span class="typ">Employees</span><span class="pln">
JOIN
    </span><span class="typ">Departments</span><span class="pln">
 ON </span><span class="typ">Departments</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">DeptId</span></pre>

<p>
	سيعيد هذا المثال مجموعة بيانات تحتوي كافة الحقول الموجودة في الجدول <code>‎Employee‎</code>، متبوعةً بـالحقل <code>‎Name‎</code> من الجدول <code>‎Departments‎</code>:
</p>

<table>
	<thead>
		<tr>
			<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				DeptId
			</th>
			<th>
				Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				3
			</td>
			<td>
				Finance
			</td>
		</tr>
		<tr>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				4
			</td>
			<td>
				IT
			</td>
		</tr>
	</tbody>
</table>

<h3>
	تنبيهات
</h3>

<p>
	يوصى عمومًا بتجنّب استخدام <code>‎*‎</code> في شيفرة الإنتاج، إذ يمكن أن تتسبّب في مجموعة من المشاكل، منها:
</p>

<ol>
	<li>
		حمل الدخل والخرج الزائد (Excess IO)، والحمل الزائد على الشبكة، واستنزاف الذاكرة، وغيرها، وذلك بسبب أنّ محرك قاعدة البيانات سيقرأ بيانات غير مطلوبة. وينقلها إلى شيفرة الواجهة الأمامية. وقد يصبح الأمر أسوأ إن كانت هناك حقول كبيرة، مثل تلك المستخدمة لتخزين الملاحظات الطويلة أو الملفات المرفقة.
	</li>
	<li>
		زيادة الضغط على الدخل والخرج إذا احتاجت قاعدة البيانات إلى تخزين النتائج الداخلية على القرص كجزء من عملية معالجة استعلامات أكثر تعقيدًا من العبارة البسيطة <code>‎SELECT &lt;columns&gt; FROM &lt;table&gt;‎</code>
	</li>
	<li>
		معالجة زائدة (و / أو مزيد من عمليات الدخل والخرج IO) إذا كانت هناك أعمدة غير ضرورية من نوع:
		<ul>
			<li>
				الأعمدة المحسوبة (computed columns) في قواعد البيانات التي تدعم هذا النوع من الأعمدة
			</li>
			<li>
				في حالة الاختيار من معرض (view)، فيشمل ذلك الأعمدة من جدول / معرض معيّن، والتي كان من الممكن أن يُحسّنها "مُحسِّن الاستعلام" (query optimiser)
			</li>
		</ul>
	</li>
	<li>
		احتمال حدوث أخطاء غير متوقعة عند إضافة أعمدة إلى الجداول والمعارض لاحقًا، مما قد يؤدي إلى أسماء أعمدة غير واضحة. على سبيل المثال:
	</li>
</ol>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_18" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM orders JOIN people ON people</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> orders</span><span class="pun">.</span><span class="pln">personid ORDER BY displayname</span><span class="pun">‎</span></pre>

<p>
	في حال إضافة عمود يُسمى <code>displayname</code> إلى جدول الطلبات - orders - قصد السماح للمستخدمين بتقديم طلباتهم تحت أسماء من اختيارهم ليسهل عليهم الرجوع إليها مستقبلًا، فسيظهر اسم العمود مرتين في المخرجات، ونتيجة لذلك قد لا تكون عبارة <code>‎ORDER BY‎</code> واضحة، وهو ما قد يتسبب في خطأ ("ambiguous column name" في إصدارات MS SQL Server الحديثة). في المثال أعلاه، قد يعرض التطبيق اسم الطلب مكان اسم الشخص بالخطأ، نتيجة أنّ العمود الجديد سيُعاد أولًا.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h3>
	متى يمكنك استخدام حرف البدل *؟
</h3>

<p>
	يُفضل عمومًا تجنّب استخدام <code>‎*‎</code> في شيفرة الإنتاج، لكن لا مشكلة في استخدامها كاختصار عند تنفيذ الاستعلامات اليدوية في قاعدة البيانات عند العمل على النماذج الأولية.
</p>

<p>
	كما قد يفرض عليك تصميم التطبيق أحيانًا استخدام حرف البدل (في مثل هذه الظروف، يُفضل استخدام <code>‎tablealias.*‎</code> بدلًا من <code>‎*‎</code> حيثما أمكن ذلك).
</p>

<p>
	عند استخدام <code>‎EXISTS‎</code>، كما في:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_20" style=""><span class="pun">‎</span><span class="pln">SELECT A</span><span class="pun">.</span><span class="pln">col1</span><span class="pun">,</span><span class="pln"> A</span><span class="pun">.</span><span class="typ">Col2</span><span class="pln"> FROM A WHERE EXISTS </span><span class="pun">(</span><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM B </span><span class="kwd">where</span><span class="pln"> A</span><span class="pun">.</span><span class="pln">ID </span><span class="pun">=</span><span class="pln"> B</span><span class="pun">.</span><span class="pln">A_ID</span><span class="pun">)</span></pre>

<p>
	فذلك لن يعيد أيّ بيانات من B. وبالتالي لن يكون الضمّ (join) ضروريًا، كما أنّ محرّك (engine) قاعدة البيانات يعلم أنه لن تُعاد أيّ قيمة من B، وبالتالي لن يتأثّر الأداء جرّاء استخدام <code>‎*‎</code>. من جهة أخرى، لا بأس في استخدام <code>‎COUNT(*)‎</code>، لأنها لا تُعيد أيًا من الأعمدة فعليًا، إذ تحتاج فقط إلى قراءة ومعالجة الأعمدة المستخدمة في التصفية.
</p>

<h2>
	استخدام SELECT مع كُنى الأعمدة
</h2>

<p>
	تُستخدم الأسماء المستعارة أو الكُنى - aliases - لاختصار أسماء الأعمدة أو جعلها ذات معنى. ويساعد ذلك على اختزال الشيفرة وجعلها أكثر مقروئية جرّاء تجنّب أسماء الجداول الطويلة وتمييز الأعمدة (على سبيل المثال، قد يكون هناك مُعرِّفان في الجدول، بيْد أنّ واحدًا منهما فقط سيستخدم في العبارة)، بالإضافة إلى تسهيل استخدام أسماء وصفية أطول في قاعدة بياناتك مع إبقاء الاستعلامات الجارية عليها مختصرة.
</p>

<p>
	علاوة على ذلك، قد تكون الكنى إجبارية في بعض الأحيان (على سبيل المثال في المعارض) من أجل تسمية المخرجات المحسوبة (computed outputs).
</p>

<p>
	<strong>جميع إصدارات SQL</strong>
</p>

<p>
	يمكن إنشاء الكنى في جميع إصدارات SQL باستخدام علامات الاقتباس المزدوجة (<code>‎"‎</code>).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_22" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS </span><span class="str">"First Name"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">MName</span><span class="pln"> AS </span><span class="str">"Middle Name"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS </span><span class="str">"Last Name"</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">  </span></pre>

<p>
	<strong>إصدارات خاصة من SQL</strong>
</p>

<p>
	يمكنك استخدام علامات الاقتباس المفردة (<code>‎'‎</code>)، وعلامات الاقتباس المزدوجة (<code>‎"‎</code>) والأقواس المربّعة (<code>‎[]‎</code>) لإنشاء كُنية في Microsoft SQL Server.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_24" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS </span><span class="str">"First Name"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">MName</span><span class="pln"> AS </span><span class="str">'Middle Name'</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS </span><span class="pun">[</span><span class="typ">Last</span><span class="pln"> </span><span class="typ">Name</span><span class="pun">]</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">  </span></pre>

<p>
	سينتج عن الشيفرة أعلاه الخرج:
</p>

<table>
	<thead>
		<tr>
			<th>
				First Name
			</th>
			<th>
				Middle Name
			</th>
			<th>
				Last Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				James
			</td>
			<td>
				John
			</td>
			<td>
				Smith
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				James
			</td>
			<td>
				Johnson
			</td>
		</tr>
		<tr>
			<td>
				Michael
			</td>
			<td>
				Marcus
			</td>
			<td>
				Williams
			</td>
		</tr>
	</tbody>
</table>

<p>
	ستعيد هذه العبارة عمودين <code>‎FName‎</code> و <code>‎LName‎</code> يحملان الاسم المحدّد (الكنية). وقد تمّ ذلك باستخدام العامل <code>‎AS‎</code> متبوعًا بالكنية، أو بكتابة الكنية مباشرةً بعد اسم العمود.
</p>

<p>
	ستكون للاستعلام التالي نفس النتيجة الواردة أعلاه.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_26" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> </span><span class="str">"First Name"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">MName</span><span class="pln"> </span><span class="str">"Middle Name"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> </span><span class="str">"Last Name"</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<table>
	<thead>
		<tr>
			<th>
				First Name
			</th>
			<th>
				Middle Name
			</th>
			<th>
				Last Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				James
			</td>
			<td>
				John
			</td>
			<td>
				Smith
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				James
			</td>
			<td>
				Johnson
			</td>
		</tr>
		<tr>
			<td>
				Michael
			</td>
			<td>
				Marcus
			</td>
			<td>
				Williams
			</td>
		</tr>
	</tbody>
</table>

<p>
	كما تلاحظ، فإنّ النسخة الصريحة (أي استخدام العامل <code>‎AS‎</code>) أفضل، لأنّها أكثر مقروئية.
</p>

<p>
	إذا كانت الكنية مؤلفة من كلمة واحدة، ولم تكن كلمة محجوزة، فيمكن كتابتها بدون علامات الاقتباس المفردة أو المزدوجة أو الأقواس المربعة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_28" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS </span><span class="typ">LastName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">  </span></pre>

<table>
	<thead>
		<tr>
			<th>
				FirstName
			</th>
			<th>
				LastName
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
		</tr>
		<tr>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
		</tr>
	</tbody>
</table>

<p>
	هناك شكل إضافي متاح في MS SQL Server، وهو <code>‎&lt;alias&gt; = &lt;column-or-calculation&gt;‎</code>، إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_30" style=""><span class="pln">SELECT </span><span class="typ">FullName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' '</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">LastName</span><span class="pun">,</span><span class="pln">
       </span><span class="typ">Addr1</span><span class="pln">    </span><span class="pun">=</span><span class="pln"> </span><span class="typ">FullStreetAddress</span><span class="pun">,</span><span class="pln">
       </span><span class="typ">Addr2</span><span class="pln">    </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TownName</span><span class="pln">
FROM </span><span class="typ">CustomerDetails</span><span class="pln">  </span></pre>

<p>
	والذي يكافئ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_32" style=""><span class="pln">SELECT </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="str">' '</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="typ">LastName</span><span class="pln"> </span><span class="typ">As</span><span class="pln"> </span><span class="typ">FullName</span><span class="pln">
       </span><span class="typ">FullStreetAddress</span><span class="pln">          </span><span class="typ">As</span><span class="pln"> </span><span class="typ">Addr1</span><span class="pun">,</span><span class="pln">
       </span><span class="typ">TownName</span><span class="pln">                   </span><span class="typ">As</span><span class="pln"> </span><span class="typ">Addr2</span><span class="pln">
FROM </span><span class="typ">CustomerDetails</span><span class="pln">  </span></pre>

<p>
	وسيؤدي كلاهما إلى النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				FullName
			</th>
			<th>
				Addr1
			</th>
			<th>
				Addr2
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				James Smith
			</td>
			<td>
				123 AnyStreet
			</td>
			<td>
				TownVille
			</td>
		</tr>
		<tr>
			<td>
				John Johnson
			</td>
			<td>
				668 MyRoad
			</td>
			<td>
				Anytown
			</td>
		</tr>
		<tr>
			<td>
				Michael Williams
			</td>
			<td>
				999 High End Dr
			</td>
			<td>
				Williamsburgh
			</td>
		</tr>
	</tbody>
</table>

<p>
	يرى البعض أنّ استخدام <code>‎=‎</code> بدلاً من <code>‎As‎</code> أفضل من ناحية المقروئية، فيما يوصي آخرون بتجنّب استخدامها لأنّها ليست قياسية، وبالتالي لا تدعمها جميع قواعد البيانات، كما قد يتداخل استخدامها مع الاستخدامات الأخرى للمحرف <code>‎=‎</code>.
</p>

<p>
	<strong>جميع إصدارات SQL</strong> إن كنت بحاجة إلى استخدام الكلمات المحجوزة، فيمكنك استخدام الأقواس المربعة أو علامات الاقتباس لتهريب الكُنية (escape):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_34" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">"SELECT"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">MName</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">"FROM"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> </span><span class="kwd">as</span><span class="pln"> </span><span class="str">"WHERE"</span><span class="pln">
FROM </span><span class="typ">Employees</span></pre>

<p>
	<strong>إصدارات خاصة من SQL</strong> بالمثل، يمكنك تهريب الكلمات المفتاحية في MSSQL عبر عدة مقاربات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_36" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS </span><span class="str">"SELECT"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">MName</span><span class="pln"> AS </span><span class="str">'FROM'</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS </span><span class="pun">[</span><span class="pln">WHERE</span><span class="pun">]</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">  </span></pre>

<table>
	<thead>
		<tr>
			<th>
				SELECT
			</th>
			<th>
				FROM
			</th>
			<th>
				WHERE
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				James
			</td>
			<td>
				John
			</td>
			<td>
				Smith
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				James
			</td>
			<td>
				Johnson
			</td>
		</tr>
		<tr>
			<td>
				Michael
			</td>
			<td>
				Marcus
			</td>
			<td>
				Williams
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكن أيضًا استخدام كنى الأعمدة في أيّ من العبارات النهائية في نفس الاستعلام، من قبيل العبارة <code>‎ORDER BY‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_38" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS </span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS </span><span class="typ">LastName</span><span class="pln">
FROM
    </span><span class="typ">Employees</span><span class="pln">
ORDER BY
    </span><span class="typ">LastName</span><span class="pln"> DESC</span></pre>

<p>
	بالمقابل، لا يجوز استخدام الشيفرة التالية لإنشاء كنية تساوي الكلمات المحجوزة (<code>‎SELECT‎</code> و <code>‎FROM‎</code>)، لأنّ ذلك سيتسبّب في العديد من الأخطاء في مرحلة التنفيذ.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_40" style=""><span class="pln">SELECT
    </span><span class="typ">FName</span><span class="pln"> AS SELECT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> AS FROM
FROM
    </span><span class="typ">Employees</span><span class="pln">
ORDER BY
    </span><span class="typ">LastName</span><span class="pln"> DESC</span></pre>

<h3>
	اختيار أعمدة فردية
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_42" style=""><span class="pln">SELECT
    </span><span class="typ">PhoneNumber</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Email</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PreferredContact</span><span class="pln">
FROM </span><span class="typ">Customers</span></pre>

<p>
	ستعيد العبارة أعلاه الأعمدة ‎PhoneNumber‎ و ‎Email‎ و ‎PreferredContact‎ من جميع صفوف الجدول ‎Customers‎. كا ستُعاد الأعمدة بالتسلسل الذي تظهر به في عبارة <code>‎SELECT‎</code>. وها هي النتيجة:
</p>

<table>
	<thead>
		<tr>
			<th>
				PhoneNumber
			</th>
			<th>
				Email
			</th>
			<th>
				PreferredContact
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				3347927472
			</td>
			<td>
				william.jones@example.com
			</td>
			<td>
				PHONE
			</td>
		</tr>
		<tr>
			<td>
				2137921892
			</td>
			<td>
				dmiller@example.net
			</td>
			<td>
				EMAIL
			</td>
		</tr>
		<tr>
			<td>
				NULL
			</td>
			<td>
				richard0123@example.com
			</td>
			<td>
				EMAIL
			</td>
		</tr>
	</tbody>
</table>

<p>
	إذا تمّ ربط عدة جداول معًا، فيمكنك اختيار الأعمدة من جداول معيّنة عن طريق وضع اسم الجدول قبل اسم العمود على النحو <code>‎[table_name].[column_name]‎</code> التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_44" style=""><span class="pln">SELECT
    </span><span class="typ">Customers</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Customers</span><span class="pun">.</span><span class="typ">Email</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Customers</span><span class="pun">.</span><span class="typ">PreferredContact</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Orders</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> AS </span><span class="typ">OrderId</span><span class="pln">
FROM
    </span><span class="typ">Customers</span><span class="pln">
LEFT JOIN
    </span><span class="typ">Orders</span><span class="pln"> ON </span><span class="typ">Orders</span><span class="pun">.</span><span class="typ">CustomerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Customers</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	تعني العبارة * <code>‎AS OrderId‎</code> أنّ الحقل <code>‎Id‎</code> من الجدول <code>‎Orders‎</code> سيُعاد كعمود يُسمى <code>‎OrderId‎</code>. راجع قسم الاختيار عبر الكنى أسفله لمزيد من المعلومات.
</p>

<p>
	لتجنب استخدام أسماء الجداول الطويلة، يمكنك تكنية الجدول، فهذا سيخفف من صعوبات كتابة أسماء الجداول الطويلة مع كل حقل تختاره في عمليات الضمّ (joins). وعند استخدام الضمّ الذاتي - self join - (أي ضم نسختين من الجدول نفسه)، فعليك تكنِية الجداول لتمييزها عن بعضها.
</p>

<p>
	يمكن كتابة كنية الجدول على النحو التالي: <code>‎Customers c‎</code> أو <code>‎Customers AS ‎c‎</code>، إذ تتصرّف <code>‎c‎</code> هنا ككُنية لـ <code>‎Customers‎</code>، يمكننا الآن أن نختار مثلا الحقل <code>‎Email‎</code> عبر الصيغة: <code>‎c.Email</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_46" style=""><span class="pln">SELECT
    c</span><span class="pun">.</span><span class="typ">PhoneNumber</span><span class="pun">,</span><span class="pln">
    c</span><span class="pun">.</span><span class="typ">Email</span><span class="pun">,</span><span class="pln">
    c</span><span class="pun">.</span><span class="typ">PreferredContact</span><span class="pun">,</span><span class="pln">
    o</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> AS </span><span class="typ">OrderId</span><span class="pln">
FROM
    </span><span class="typ">Customers</span><span class="pln"> c
LEFT JOIN
    </span><span class="typ">Orders</span><span class="pln"> o ON o</span><span class="pun">.</span><span class="typ">CustomerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> c</span><span class="pun">.</span><span class="typ">Id</span></pre>

<h2>
	اختيار عدد معيّن من السجلات
</h2>

<p>
	عرّف معيار SQL 2008 العبارة <code>‎FETCH FIRST‎</code> كطريقة لاختيار عدد السجلات المُعادة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_48" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ProductName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">UnitPrice</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Package</span><span class="pln">
FROM </span><span class="typ">Product</span><span class="pln">
ORDER BY </span><span class="typ">UnitPrice</span><span class="pln"> DESC
FETCH FIRST </span><span class="lit">10</span><span class="pln"> ROWS ONLY</span></pre>

<p>
	لم يُدعم هذا المعيار إلا في الإصدارات الأخيرة من بعض أنظمة إدارة قواعد البيانات (RDMSs). فيما توفّر الأنظمة الأخرى صياغة غير قياسية. أيضًا يدعم Progress OpenEdge 11.x الصياغة <code>‎FETCH FIRST &lt;n&gt; ROWS ONLY‎</code>.
</p>

<p>
	بالإضافة إلى ذلك، تسمح إضافة العبارة <code>‎OFFSET &lt;m&gt; ROWS‎</code> قبل <code>‎FETCH FIRST &lt;n&gt; ROWS ONLY‎</code> بتخطي عدد من الصفوف قبل جلب الصفوف.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_50" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ProductName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">UnitPrice</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Package</span><span class="pln">
FROM </span><span class="typ">Product</span><span class="pln">
ORDER BY </span><span class="typ">UnitPrice</span><span class="pln"> DESC
OFFSET </span><span class="lit">5</span><span class="pln"> ROWS
FETCH FIRST </span><span class="lit">10</span><span class="pln"> ROWS ONLY</span></pre>

<p>
	الاستعلام التالي مدعوم في SQL Server و MS Access:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_52" style=""><span class="pln">SELECT TOP </span><span class="lit">10</span><span class="pln"> </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ProductName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">UnitPrice</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Package</span><span class="pln">
FROM </span><span class="typ">Product</span><span class="pln">
ORDER BY </span><span class="typ">UnitPrice</span><span class="pln"> DESC</span></pre>

<p>
	لفعل الشيء نفسه في MySQL أو PostgreSQL، يجب استخدام الكلمة المفتاحية <code>‎LIMIT‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_54" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ProductName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">UnitPrice</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Package</span><span class="pln">
FROM </span><span class="typ">Product</span><span class="pln">
ORDER BY </span><span class="typ">UnitPrice</span><span class="pln"> DESC
LIMIT </span><span class="lit">10</span></pre>

<p>
	وفي Oracle، ينبغي استخدام <code>‎ROWNUM‎</code>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_56" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ProductName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">UnitPrice</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Package</span><span class="pln">
FROM </span><span class="typ">Product</span><span class="pln">
WHERE ROWNUM </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">10</span><span class="pln">
ORDER BY </span><span class="typ">UnitPrice</span><span class="pln"> DESC </span></pre>

<p>
	وينتج عن هذا 10 سجلات.
</p>

<pre class="ipsCode">Id    ProductName                   UnitPrice             Package
38    Côte de Blaye                263.50                12 - 75 cl bottles
29    Thüringer Rostbratwurst     123.79                50 bags x 30 sausgs.
9    Mishi Kobe Niku                97.00                 18 - 500 g pkgs.
20    Sir Rodney's Marmalade     81.00                 30 gift boxes
18    Carnarvon Tigers                  62.50                 16 kg pkg.
59    Raclette Courdavault            55.00                 5 kg pkg.
51    Manjimup Dried Apples      53.00                 50 - 300 g pkgs.
62    Tarte au sucre                 49.30                 48 pies
43    Ipoh Coffee                    46.00                 16 - 500 g tins
28    Rössle Sauerkraut            45.60                 25 - 825 g cans
</pre>

<h4>
	الفروق بين الأنظمة
</h4>

<p>
	جدير بالذكر أنّ الكلمة المفتاحية <code>‎TOP‎</code> في نظام Microsoft SQL تعمل بعد عبارة <code>‎WHERE‎</code>، وتعيد عددًا محددًا من النتائج في حال كانت تلك النتائج متوافرة في أيّ مكان من الجدول، بينما تعمل <code>‎ROWNUM‎</code> كجزء من عبارة <code>‎WHERE‎</code>، لذا إذا لم تتحقّق الشروط الأخرى في العدد المحدد من الصفوف في بداية الجدول، فلن تحصل على أيّ نتيجة، حتى لو كان من الممكن العثور على نتائج أخرى.
</p>

<h2>
	الاختيار الشرطي
</h2>

<p>
	يمكن استخدام العبارتين <code>SELECT</code> و <code>WHERE</code> معًا على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_59" style=""><span class="pln">SELECT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> columnN
FROM table_name
WHERE </span><span class="pun">[</span><span class="pln">condition</span><span class="pun">]</span></pre>

<p>
	يمكن أن يكون الشرط [condition] أيّ تعبير صالح في SQL يستخدم المعاملات المنطقية: <code>&gt;</code> و <code>&lt;</code> و <code>=</code> و <code>‎‎&gt;=‎‎</code> و <code>‎‎&lt;=‎‎‎‎</code> و <code>LIKE</code> و <code>NOT</code> و <code>IN</code> و <code>BETWEEN</code> وغيرها.
</p>

<p>
	تُعيد العبارة التالية جميع الأعمدة من الجدول "Cars" ذات الحالة "READY":
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_61" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln"> WHERE status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'READY'</span></pre>

<h2>
	الاختيار باستخدام CASE
</h2>

<p>
	تُستخدم عبارة <code>CASE</code> لتطبيق عملية معينة على النتائج مباشرة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_63" style=""><span class="pln">SELECT CASE WHEN </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">50</span><span class="pln"> THEN </span><span class="str">'under'</span><span class="pln"> ELSE </span><span class="str">'over'</span><span class="pln"> </span><span class="kwd">END</span><span class="pln"> threshold
FROM </span><span class="typ">TableName</span></pre>

<p>
	يمكن أيضًا سلسَلَة CASE على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_65" style=""><span class="pln">SELECT
   CASE WHEN </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">50</span><span class="pln"> THEN </span><span class="str">'under'</span><span class="pln">
 WHEN </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">50</span><span class="pln"> AND </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&lt;</span><span class="lit">100</span><span class="pln"> THEN </span><span class="str">'between'</span><span class="pln">
 ELSE </span><span class="str">'over'</span><span class="pln">
   </span><span class="kwd">END</span><span class="pln"> threshold
FROM </span><span class="typ">TableName</span></pre>

<p>
	يمكن أيضا استخدام عبارة <code>‎CASE‎</code> داخل أخرى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_67" style=""><span class="pln">SELECT
    CASE WHEN </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">50</span><span class="pln"> THEN </span><span class="str">'under'</span><span class="pln">
               ELSE
 CASE WHEN </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">50</span><span class="pln"> AND </span><span class="typ">Col1</span><span class="pln"> </span><span class="pun">&lt;</span><span class="lit">100</span><span class="pln"> THEN </span><span class="typ">Col1</span><span class="pln">
 ELSE </span><span class="str">'over'</span><span class="pln"> </span><span class="kwd">END</span><span class="pln">
     </span><span class="kwd">END</span><span class="pln"> threshold
FROM </span><span class="typ">TableName</span></pre>

<h2>
	اختيار الأعمدة التي تحمل أسماء لكلمات مفتاحية محجوزة
</h2>

<p>
	عندما يتطابق اسم العمود مع كلمة مفتاحية محجوزة، ينص معيار SQL على ضرورة أن تحُاط بعلامات اقتباس مزدوجة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_69" style=""><span class="pln">SELECT
    </span><span class="str">"ORDER"</span><span class="pun">,</span><span class="pln">
    ID
FROM ORDERS</span></pre>

<p>
	لاحظ أنّ هذا يجعل اسم العمود حساسًا لحالة الأحرف. بعض نظم إدارة قواعد البيانات لديها طرق خاصة لاقتباس الأسماء. على سبيل المثال، يستخدم SQL Server أقواس مربعة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_71" style=""><span class="pln">SELECT
 </span><span class="pun">[</span><span class="typ">Order</span><span class="pun">],</span><span class="pln">
    ID
FROM ORDERS</span></pre>

<p>
	بينما تستخدم MySQL (و MariaDB) افتراضيا علامة اقتباس مائلة (backtick):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_73" style=""><span class="pln">SELECT
    </span><span class="str">`Order`</span><span class="pun">,</span><span class="pln">
    id
FROM orders</span></pre>

<h2>
	الاختيار باستخدام كُنى الجداول
</h2>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_75" style=""><span class="pln">SELECT e</span><span class="pun">.</span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">LName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> e</span></pre>

<p>
	أُعطِي جدول الموظفين Employees الكنية "e" مباشرةً بعد اسمه. يساعد ذلك في إزالة الغموض في حال احتوت العديد من الجداول حقولًا تحمل نفس الاسم، وكنت تحتاج إلى تحديد الجدول الذي تريد استخلاص البيانات منه.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_77" style=""><span class="pln">SELECT e</span><span class="pun">.</span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> m</span><span class="pun">.</span><span class="typ">Fname</span><span class="pln"> AS </span><span class="typ">ManagerFirstName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> e
 JOIN </span><span class="typ">Managers</span><span class="pln"> m ON e</span><span class="pun">.</span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> m</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	لاحظ أنه بمجرد تعريف الكنية، فلن يكون بمقدورك استخدام اسم الجدول الأساسي بعد الآن، لهذا ستطرح الشيفرة التالية خطأً:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_79" style=""><span class="pln">SELECT e</span><span class="pun">.</span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Employees</span><span class="pun">.</span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> m</span><span class="pun">.</span><span class="typ">Fname</span><span class="pln"> AS </span><span class="typ">ManagerFirstName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln"> e
JOIN </span><span class="typ">Managers</span><span class="pln"> m ON e</span><span class="pun">.</span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> m</span><span class="pun">.</span><span class="typ">Id</span></pre>

<p>
	تجدر الإشارة إلى أنّ كنى الجداول - أو "متغيرات النطاق" (range variables) إن أردنا التقيد بالتسميات الرسمية - قُدِّمت في لغة SQL لحل مشكلة الأعمدة المكرّرة التي تنجم عن استخدام <code>‎INNER JOIN‎</code>. وقد صحّح معيار SQL 1992 هذه الثغرة من خلال إدخال <code>‎NATURAL JOIN‎</code> (مطبّقة حاليًا في mySQL و PostgreSQL و Oracle ولكن ليس في SQL Server بعدُ)، وقد ضمن ذلك ألا تحدث مشكلة الأسماء المكررة للأعمدة.
</p>

<p>
	في المثال أعلاه، تُضمّ الجداول في الأعمدة ذات الأسماء المختلفة (<code>‎Id‎</code> و <code>‎ManagerId‎</code>) ولكن ليس في الأعمدة التي تحمل الاسم نفسه (<code>‎LName‎</code>، <code>‎FName‎</code>)، هذا الأمر يتطلّب إعادة تسمية الأعمدة قبل عملية الضمّ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_81" style=""><span class="pln">SELECT </span><span class="typ">Fname</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ManagerFirstName</span><span class="pln">
FROM </span><span class="typ">Employees</span><span class="pln">
NATURAL JOIN
</span><span class="pun">(</span><span class="pln"> SELECT </span><span class="typ">Id</span><span class="pln"> AS </span><span class="typ">ManagerId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Fname</span><span class="pln"> AS </span><span class="typ">ManagerFirstName</span><span class="pln">
FROM </span><span class="typ">Managers</span><span class="pln"> </span><span class="pun">)</span><span class="pln"> m</span><span class="pun">;</span></pre>

<p>
	رغم أنّه يجب الإعلان عن متغير الكنية / النطاق الخاص بالجدول المُعدَّل (أو ستطرح SQL خطأً)، إلا أنّه من غير المنطقي أبدًا استخدامه فعليًا في الاستعلامات.
</p>

<h3>
	الاختيار بناءً على عدة شروط
</h3>

<p>
	تُستخدم الكلمة المفتاحية <code>‎AND‎</code> لإضافة المزيد من الشروط إلى الاستعلام.
</p>

<table>
	<thead>
		<tr>
			<th>
				Name
			</th>
			<th>
				Age
			</th>
			<th>
				Gender
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Sam
			</td>
			<td>
				18
			</td>
			<td>
				M
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
			<td>
				21
			</td>
			<td>
				M
			</td>
		</tr>
		<tr>
			<td>
				Bob
			</td>
			<td>
				22
			</td>
			<td>
				M
			</td>
		</tr>
		<tr>
			<td>
				Mary
			</td>
			<td>
				23
			</td>
			<td>
				F
			</td>
		</tr>
	</tbody>
</table>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_83" style=""><span class="pln">SELECT name FROM persons WHERE gender </span><span class="pun">=</span><span class="pln"> </span><span class="str">'M'</span><span class="pln"> AND age </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">;</span></pre>

<p>
	سينتج عن هذا:
</p>

<table>
	<thead>
		<tr>
			<th>
				Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				John
			</td>
		</tr>
		<tr>
			<td>
				Bob
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكن أيضًا استخدام المعامل المنطقي <code>‎OR‎</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_85" style=""><span class="pln">SELECT name FROM persons WHERE gender </span><span class="pun">=</span><span class="pln"> </span><span class="str">'M'</span><span class="pln"> OR age </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">;</span></pre>

<p>
	سينتج عن هذا:
</p>

<table>
	<thead>
		<tr>
			<th>
				Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Sam
			</td>
		</tr>
		<tr>
			<td>
				John
			</td>
		</tr>
		<tr>
			<td>
				Bob
			</td>
		</tr>
	</tbody>
</table>

<p>
	يمكن دمج هذه الكلمات المفتاحية لبناء شروط أكثر تعقيدًا:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_87" style=""><span class="pln">SELECT name
FROM persons
WHERE </span><span class="pun">(</span><span class="pln">gender </span><span class="pun">=</span><span class="pln"> </span><span class="str">'M'</span><span class="pln"> AND age </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">)</span><span class="pln">
    OR </span><span class="pun">(</span><span class="pln">gender </span><span class="pun">=</span><span class="pln"> </span><span class="str">'F'</span><span class="pln"> AND age </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">20</span><span class="pun">);</span></pre>

<p>
	سينتج عن هذا:
</p>

<table>
	<thead>
		<tr>
			<th>
				Name
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				Sam
			</td>
		</tr>
		<tr>
			<td>
				Mary
			</td>
		</tr>
	</tbody>
</table>

<h2>
	الاختيار دون قفل الجدول
</h2>

<p>
	في بعض الأحيان، عندما تُستخدم الجداول لأجل القراءة أساسًا (أو حصرًا)، فإنّ الفهرسة (indexing) لا تكون ضرورية، لذا لن تكون هناك حاجة إلى قفل (LOCK) الجدول أثناء الاختيار.
</p>

<p>
	هذه بعض الأمثلة على ذلك:
</p>

<p>
	<strong>SQL Server</strong>:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_89" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> WITH </span><span class="pun">(</span><span class="pln">nolock</span><span class="pun">)</span></pre>

<p>
	<strong>MySQL</strong>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_91" style=""><span class="pln">SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED</span><span class="pun">;</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pun">;</span><span class="pln">
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ</span><span class="pun">;</span></pre>

<p>
	<strong>Oracle</strong>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_93" style=""><span class="pln">SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED</span><span class="pun">;</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pun">;</span></pre>

<p>
	<strong>DB2</strong>
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_95" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">TableName</span><span class="pln"> WITH UR</span><span class="pun">;</span></pre>

<p>
	العبارة <code>‎UR‎</code> كناية عن "قراءة غير ملتزم بها" (uncommitted read). في حال استخدامها على جدول أثناء تعديل أحد حقوله، فقد تحدث نتائج غير متوقعة.
</p>

<h2>
	الاختيار باستخدام الدوال التجميعية aggregate functions
</h2>

<h3>
	حساب المتوسط
</h3>

<p>
	تعيد الدالة التجميعية <code>‎AVG()‎</code> متوسط القيم المحددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_97" style=""><span class="pln">SELECT AVG</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<p>
	يمكن أيضًا استخدام الدوال مع عبارة <code>where</code> على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_99" style=""><span class="pln">SELECT AVG</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> </span><span class="typ">DepartmentId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">1</span></pre>

<p>
	ويمكن أيضًا استخدام الدوال مع العبارة <code>GROUP BY</code>. مثلًا، إذا تم تصنيف الموظف في عدة أقسام، وأردنا أن نحدّد متوسط الراتب في كل قسم، فيمكننا استخدام الاستعلام التالي.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_101" style=""><span class="pln">SELECT AVG</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> GROUP BY </span><span class="typ">DepartmentId</span></pre>

<h3>
	القيمة الصغرى
</h3>

<p>
	تعيد الدالة التجميعية <code>‎MIN()‎</code> الحد الأدنى من القيم المحددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_103" style=""><span class="pln">SELECT MIN</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<h3>
	القيمة الكبرى
</h3>

<p>
	تعيد الدالة التجميعية <code>‎MAX()‎</code> الحد الأقصى للقيم المحددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_105" style=""><span class="pln">SELECT MAX</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<h3>
	التعداد
</h3>

<p>
	تعيد الدالة التجميعية <code>‎COUNT()‎</code> عدد القيم المحددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_107" style=""><span class="pln">SELECT </span><span class="typ">Count</span><span class="pun">(*)</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<p>
	يمكن أيضًا دمجها مع العبارة <code>where</code> للحصول على عدد الصفوف التي تفي بشروط محددة.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_109" style=""><span class="pln">SELECT </span><span class="typ">Count</span><span class="pun">(*)</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> </span><span class="kwd">where</span><span class="pln"> </span><span class="typ">ManagerId</span><span class="pln"> IS NOT NULL</span></pre>

<p>
	يمكن أيضًا اختيار عمود معيّن للحصول على عدد القيم في ذلك العمود. لاحظ أنّ القيم المعدومة <code>‎NULL‎</code> لا تُحتسب.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_111" style=""><span class="typ">Select</span><span class="pln"> </span><span class="typ">Count</span><span class="pun">(</span><span class="typ">ManagerId</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">Employees</span></pre>

<p>
	يمكن أيضًا دمج <code>Count</code> مع الكلمة المفتاحية <code>DISTINCT</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_113" style=""><span class="typ">Select</span><span class="pln"> </span><span class="typ">Count</span><span class="pun">(</span><span class="pln">DISTINCT </span><span class="typ">DepartmentId</span><span class="pun">)</span><span class="pln"> </span><span class="kwd">from</span><span class="pln"> </span><span class="typ">Employees</span></pre>

<h3>
	التجميع
</h3>

<p>
	تعيد الدالة التجميعية <code>‎SUM()‎</code> مجموع القيم المُختارة في جميع الصفوف.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_115" style=""><span class="pln">SELECT SUM</span><span class="pun">(</span><span class="typ">Salary</span><span class="pun">)</span><span class="pln"> FROM </span><span class="typ">Employees</span></pre>

<h2>
	الاختيار من بين قيم معيّنة من عمود
</h2>

<p>
	المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_117" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln">  WHERE status IN </span><span class="pun">(</span><span class="pln"> </span><span class="str">'Waiting'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Working'</span><span class="pln"> </span><span class="pun">)</span></pre>

<p>
	يكافئ:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_119" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Cars</span><span class="pln">  WHERE </span><span class="pun">(</span><span class="pln"> status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Waiting'</span><span class="pln"> OR status </span><span class="pun">=</span><span class="pln"> </span><span class="str">'Working'</span><span class="pln"> </span><span class="pun">)</span></pre>

<p>
	إذ أنّ <code>‎value IN ( &lt;value list&gt; )‎</code> هي مجرّد اختصار لمعامل <code>OR</code> المنطقي.
</p>

<h2>
	تطبيق الدوال التجميعية على مجموعات من الصفوف
</h2>

<p>
	يحسب المثال التالي عدد الصفوف بناءً على قيمة محددة من العمود:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_121" style=""><span class="pln">SELECT category</span><span class="pun">,</span><span class="pln"> COUNT</span><span class="pun">(*)</span><span class="pln"> AS item_count
FROM item
GROUP BY category</span><span class="pun">;</span></pre>

<p>
	ويحسب المثال التالي متوسط الدخل حسب القسم:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_124" style=""><span class="pln">SELECT department</span><span class="pun">,</span><span class="pln"> AVG</span><span class="pun">(</span><span class="pln">income</span><span class="pun">)</span><span class="pln">
FROM employees
GROUP BY department</span><span class="pun">;</span></pre>

<p>
	الشيء الأساسي هنا هو اختيار الأعمدة المحددة في عبارة <code>‎GROUP BY‎</code> حصرًا، أو استخدامها مع الدوال التجميعية. يمكن أيضًا استخدام العبارة <code>‎WHERE‎</code> مع <code>‎GROUP BY‎</code>، إلّا أنّ <code>‎WHERE‎</code> ستصفّي السجلات قبل تجميعها (grouping):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_127" style=""><span class="pln">SELECT department</span><span class="pun">,</span><span class="pln"> AVG</span><span class="pun">(</span><span class="pln">income</span><span class="pun">)</span><span class="pln">
FROM employees
WHERE department </span><span class="pun">&lt;&gt;</span><span class="pln"> </span><span class="str">'ACCOUNTING'</span><span class="pln">
GROUP BY department</span><span class="pun">;</span></pre>

<p>
	إن أردت تصفية النتائج بعد الانتهاء من التجميع، مثلًا إن أردت ألّا تعرض إلا الأقسام التي يتجاوز معدل دخلها 1000، سيكون عليك استخدام العبارة <code>‎HAVING‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_129" style=""><span class="pln">SELECT department</span><span class="pun">,</span><span class="pln"> AVG</span><span class="pun">(</span><span class="pln">income</span><span class="pun">)</span><span class="pln">
FROM employees
WHERE department </span><span class="pun">&lt;&gt;</span><span class="pln"> </span><span class="str">'ACCOUNTING'</span><span class="pln">
GROUP BY department
HAVING avg</span><span class="pun">(</span><span class="pln">income</span><span class="pun">)</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">;</span></pre>

<h2>
	الاختيار مع ترتيب النتائج
</h2>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_131" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY </span><span class="typ">LName</span></pre>

<p>
	ستعيد هذه العبارة جميع الأعمدة من الجدول <code>‎Employees‎</code>.
</p>

<table>
	<thead>
		<tr>
			<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
		</tr>
		<tr>
			<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
		</tr>
		<tr>
			<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
		</tr>
	</tbody>
</table>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_133" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY </span><span class="typ">LName</span><span class="pln"> DESC</span></pre>

<p>
	أو
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_135" style=""><span class="pln"> SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY </span><span class="typ">LName</span><span class="pln"> ASC</span></pre>

<p>
	تغيّر عبارة <code>ASC</code> اتجَاه الترتيب. يمكن أيضا إجراء الترتيب وفق عدّة أعمدة على النحو التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_137" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY </span><span class="typ">LName</span><span class="pln"> ASC</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pln"> ASC</span></pre>

<p>
	سيرتِّب هذا المثال النتائج حسب الحقل <code>‎LName‎</code> أولّا، أمّا بالنسبة للسجلات التي لها نفس قيمة الحقل <code>‎LName‎</code>، فسيرتِّبها حسب <code>‎FName‎</code>. سينتج عن هذا قوائم مشابهة للقوائم التي تجدها في دفتر الهاتف. إن أردت تجنّب إعادة كتابة اسم العمود في عبارة <code>‎ORDER BY‎</code>، يمكنك استخدام رقم العمود بدلاً من اسمه. انتبه إلى أنّ أرقام الأعمدة تبدأ من 1.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_139" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY </span><span class="lit">3</span></pre>

<p>
	يمكن أيضًا تضمين عبارة <code>‎CASE‎</code> في عبارة <code>‎ORDER BY‎</code>.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_141" style=""><span class="pln">SELECT </span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> ORDER BY CASE WHEN </span><span class="typ">LName</span><span class="pun">=</span><span class="str">'Jones'</span><span class="pln"> THEN </span><span class="lit">0</span><span class="pln"> ELSE </span><span class="lit">1</span><span class="pln">
</span><span class="kwd">END</span><span class="pln"> ASC</span></pre>

<p>
	سترتّب هذه الشيفرة النتائج بحيث تكون السجلات التي يساوي حقل <code>‎LName‎</code> خاصتها القيمة "Jones" في الأعلى.
</p>

<h2>
	استخدام null لأجل الاختيار
</h2>

<p>
	إليك المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_143" style=""><span class="pln">SELECT </span><span class="typ">Name</span><span class="pln"> FROM </span><span class="typ">Customers</span><span class="pln"> WHERE </span><span class="typ">PhoneNumber</span><span class="pln"> IS NULL</span></pre>

<p>
	تختلف صياغة الاختيار باستخدام القيم المعدومة null عن الصياغة العادية، إذ أنّها لا تستخدم معامل التساوي <code>‎=‎</code>، وإنّما تستخدم <code>‎IS NULL‎</code> أو <code>‎IS NOT NULL‎</code>.
</p>

<h3>
	اختيار قيم غير مكرّرة
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_145" style=""><span class="pln">SELECT DISTINCT </span><span class="typ">ContinentCode</span><span class="pln">
FROM </span><span class="typ">Countries</span><span class="pun">;</span></pre>

<p>
	سيعيد هذا الاستعلام جميع القيم الفريدة والمختلفة عن بعضها من العمود <code>‎ContinentCode‎</code> في الجدول <code>‎Countries‎</code>
</p>

<table>
	<thead>
		<tr>
			<td>
				<strong>ContinentCode</strong>
			</td>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td>
				OC
			</td>
		</tr>
		<tr>
			<td>
				EU
			</td>
		</tr>
		<tr>
			<td>
				AS
			</td>
		</tr>
		<tr>
			<td>
				NA
			</td>
		</tr>
		<tr>
			<td>
				AF
			</td>
		</tr>
	</tbody>
</table>

<p>
	هذا <a href="http://sqlfiddle.com/#!9/14cfc6/2/0" rel="external nofollow">مثال حي</a>.
</p>

<h3>
	اختيار الصفوف من عدة جداول
</h3>

<p>
	إليك الشيفرة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_1487_147" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM
    table1</span><span class="pun">,</span><span class="pln">
    table2
SELECT
    table1</span><span class="pun">.</span><span class="pln">column1</span><span class="pun">,</span><span class="pln">
    table1</span><span class="pun">.</span><span class="pln">column2</span><span class="pun">,</span><span class="pln">
    table2</span><span class="pun">.</span><span class="pln">column1
FROM
    table1</span><span class="pun">,</span><span class="pln">
    table2</span></pre>

<p>
	تُسمّى هذه العملية الجداء المتقاطع (cross product) في SQL، وهي مكافئة للجداء المتقاطع في المجموعات. تعيد هذه العبارات أعمدة مُختارة من عدّة جداول في استعلام واحد، ولا توجد علاقة محددة بين الأعمدة المُعادة من كل جدول.
</p>

<p>
	ترجمة -وبتصرّف- للفصل Chapter 6: SELECT من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
	<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%AC%D9%85%D9%8A%D8%B9-%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8-%D9%81%D9%8A-sql-r846/" rel="">التجميع والترتيب في SQL</a>
	</li>
	<li>
		المقال السابق: <a href="https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/" rel="">مدخل إلى SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">845</guid><pubDate>Sat, 21 Mar 2020 13:04:00 +0000</pubDate></item><item><title>&#x645;&#x62F;&#x62E;&#x644; &#x625;&#x644;&#x649; SQL</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-sql-r844/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2020_03/1.jpg.90bec92bc75ae6db667c2b201f9106c6.jpg" /></p>

<p>
	لغة الاستعلامات الهيكلية SQL اختصار إلى Structured Query Language هي لغة برمجة متخصصة في إدارة قواعد البيانات العلائقية RDBMS اختصار إلى <a href="https://en.wikipedia.org/wiki/Relational_database#RDBMS" rel="external nofollow">Relational database management system</a>. كما تُستخدم اللغات المشتقة من SQL في أنظمة إدارة مجاري البيانات العلائقية RDSMS اختصار إلى Relational Data Stream Management Systems، أو في إدارة قواعد بيانات SQL الحصرية NoSQL.
</p>

<p>
	تتألف SQL من ثلاث لغات فرعية أساسية، وهي:
</p>

<ol>
<li>
		<strong>لغة تعريف البيانات DDL</strong>: تُستعمل لإنشاء وتعديل بنية قاعدة البيانات.
	</li>
	<li>
		<strong>لغة معالجة البيانات DML</strong>: تستعمل لتنفيذ عمليات قراءة البيانات وإدراجها وتحديثها وحذفها.
	</li>
	<li>
		<strong>لغة التحكم في البيانات DCL</strong>: تُستعمل للتحكم في الوصول إلى البيانات المخزّنة في قاعدة البيانات.
	</li>
</ol>
<p>
	تتألف DML من أربع عمليات أساسية، وهي عمليات الإنشاء (Create) والقراءة (Read) والتحديث (Update) والحذف (Delete)، ويُطلق عليها اختصارًا CRUD، تُنفّذ هذه العمليات عبر التعليمات <code>‎INSERT‎</code> و <code>‎SELECT‎</code> و <code>‎UPDATE‎</code> و <code>‎DELETE‎</code> على التوالي.
</p>

<p>
	أُضيفت مؤخرًا تعليمة <code>‎MERGE‎</code>، والتي تنفّذ العمليات <code>INSERT</code> و <code>UPDATE</code> و <code>DELETE</code> معًا.
</p>

<p>
	تُقدَّم العديد من قواعد بيانات SQL على هيئة نُظم عميل / خادم (client/server systems). ويُطلق على هذه الخوادم مصطلح "خادم SQL".
</p>

<p>
	أنشأت ميكروسوفت قاعدة بيانات تسمى "SQL Server". ورغم أنّها تُعدّ من لهجات SQL، إلا أنّنا لن نتحدث عنها في هذه السلسلة، إن كنت تريد تعلّمها فيمكنك الرجوع إلى توثيقها.
</p>

<h2>
	المعرفات identifiers
</h2>

<p>
	يستعرض هذا القسم موضوع المعرّفات (identifiers)، وتشرح قواعد تسمية الجداول والأعمدة وباقي كائنات قاعدة البيانات. سنحاول أن تغطي الأمثلة الاختلافات بين تقديمات SQL المختلفة.
</p>

<h3>
	المعرفات غير المقتبسة Unquoted identiﬁers
</h3>

<p>
	يمكن أن تحتوي المعرّفات غير المُقتبسة على الحروف (<code>‎a‎</code> - <code>‎z‎</code>) والأرقام (<code>‎0‎</code> - <code>‎9‎</code>) والشرطة السفلية (<code>‎_‎</code>)، وفي جميع الأحوال، ينبغي أن تبدأ بحرف.
</p>

<p>
	اعتمادًا على تقديم SQL المُستخدم، و / أو إعدادات قاعدة البيانات، قد يجوز استخدام أحرف أخرى، وبعضها يمكن أن تُستخدم حرفًا أولًا للمعرّف.
</p>

<p>
	هذه بعض الأمثلة على الأحرف الجائزة:
</p>

<ul>
<li>
		MS SQL:‏ <code>‎@‎</code> و <code>‎$‎</code> و <code>‎#‎</code> وباقي محارف اليونيكود -Unicode - الأخرى، <a href="https://docs.microsoft.com/en-us/sql/relational-databases/databases/database-identifiers" rel="external nofollow">المصدر</a>
	</li>
	<li>
		MySQL:‏ <code>‎$‎،</code> <a href="https://dev.mysql.com/doc/refman/5.7/en/identifiers.html" rel="external nofollow">المصدر</a>
	</li>
	<li>
		Oracle:‏ <code>‎$‎</code> و <code>‎#‎</code> وبافي الأحرف من مجموعة أحرف قاعدة البيانات، <a href="https://docs.oracle.com/database/121/SQLRF/sql_elements008.htm#SQLRF00223" rel="external nofollow">المصدر</a>
	</li>
	<li>
		PostgreSQL:‏ <code>‎$‎</code> وباقي أحرف اليونيكود الأخرى، <a href="https://www.postgresql.org/docs/current/static/sql-syntax-lexical.html" rel="external nofollow">المصدر</a>
	</li>
</ul>
<p>
	المعرّفات غير المقتبسة غير حسّاسة لحالة الأحرف عمومًا. بيْد أنّ طريقة التعامل مع حالة الأحرف تختلف بحسب تقديم SQL، مثلًا:
</p>

<ul>
<li>
		MS SQL: تحافظ على الحالة (Case-preserving)، إذ تُحدّد مسألة الحساسية لحالة الأحرف عبر مجموعة أحرف قاعدة البيانات (database character set)، لذا يمكن أن تكون حساسة لحالة الأحرف.
	</li>
	<li>
		MySQL: تحافظ على الحالة، وتعتمد الحساسية على إعدادات قاعدة البيانات ونظام الملفات الأساسي.
	</li>
	<li>
		Oracle: تُحوّل إلى أحرف كبيرة، ثم تُعامل كمعرفّات مقتبسة.
	</li>
	<li>
		PostgreSQL: تُحوّل إلى أحرف صغيرة، ثم تُعامل مثل المعرّفات المقتبسة.
	</li>
	<li>
		SQLite: تحافظ على الحالة. وعدم حساسيتها تقتصر على أحرف ASCII.
	</li>
</ul>
<h2>
	أنواع البيانات Data Types
</h2>

<h3>
	DECIMAL و NUMERIC
</h3>

<p>
	يمثل النوعان <code>‎DECIMAL‎</code> و <code>‎NUMERIC‎</code> أعدادّا عشرية ذات دقة ثابتة، وهما متكافئان وظيفيًا. ويُصاغان على النحو التالي:
</p>

<pre class="ipsCode">
DECIMAL ( precision [ , scale] )
NUMERIC ( precision [ , scale] )
</pre>

<p>
	أمثلة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_8" style="">
<span class="pln">SELECT CAST</span><span class="pun">(</span><span class="lit">123</span><span class="pln"> AS DECIMAL</span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="lit">2</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln">returns </span><span class="lit">123.00</span><span class="pln">
SELECT CAST</span><span class="pun">(</span><span class="lit">12345.12</span><span class="pln"> AS NUMERIC</span><span class="pun">(</span><span class="lit">10</span><span class="pun">,</span><span class="lit">5</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln">returns </span><span class="lit">12345.12000</span></pre>

<h3>
	FLOAT و REAL
</h3>

<p>
	يمثل نوعًا الأعداد FLOAT و REAL الأعداد التقريبية، ويُستخدمان لتمثيل البيانات الرقمية ذات الفاصلة العائمة (ﬂoating point numeric data).
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_10" style="">
<span class="pln">SELECT CAST</span><span class="pun">(</span><span class="pln"> PI</span><span class="pun">()</span><span class="pln"> AS FLOAT</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln">returns </span><span class="lit">3.14159265358979</span><span class="pln">
SELECT CAST</span><span class="pun">(</span><span class="pln"> PI</span><span class="pun">()</span><span class="pln"> AS REAL</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln">returns </span><span class="lit">3.141593</span></pre>

<h3>
	الأعداد الصحيحة Integers
</h3>

<p>
	يمثل النوع Integers البيانات العددية الصحيحة.
</p>

<table><tbody>
<tr>
<th>
				نوع البيانات
			</th>
			<th>
				النطاق
			</th>
			<th>
				مساحة التخزين
			</th>
		</tr>
<tr>
<td>
				bigint
			</td>
			<td>
				-2^63 (-9,223,372,036,854,775,808) إلى 2^63-1 (9,223,372,036,854,775,807)
			</td>
			<td>
				8 بايتات
			</td>
		</tr>
<tr>
<td>
				int
			</td>
			<td>
				-2^31 (-2,147,483,648) إلى 2^31-1 (2,147,483,647)
			</td>
			<td>
				4 بايتات
			</td>
		</tr>
<tr>
<td>
				smallint
			</td>
			<td>
				-2^15 (-32,768) إلى 2^15-1 (32,767)
			</td>
			<td>
				بايتان
			</td>
		</tr>
<tr>
<td>
				tinyint
			</td>
			<td>
				من 0 إلى 255
			</td>
			<td>
				بايت واحد
			</td>
		</tr>
</tbody></table>
<style type="text/css">
table {
    width: 100%;
}

thead {
    vertical-align: middle;
    text-align: center;
}

td, th {
    border: 1px solid #dddddd;
    text-align: right;
    padding: 8px;
    text-align: inherit;

}
tr:nth-child(even) {
    background-color: #dddddd;
}</style>
<h3>
	MONEY و SMALLMONEY
</h3>

<p>
	يمثل النوعان MONEY و SMALLMONEY البيانات التي تمثل القيم النقدية أو العملات.
</p>

<table><tbody>
<tr>
<th>
				نوع البيانات
			</th>
			<th>
				النطاق
			</th>
			<th>
				مساحة التخزين
			</th>
		</tr>
<tr>
<td>
				money
			</td>
			<td>
				-922,337,203,685,477.5808 إلى 922,337,203,685,477.5807
			</td>
			<td>
				8 بايتات
			</td>
		</tr>
<tr>
<td>
				smallmoney
			</td>
			<td>
				-214,748.3648 إلى 214,748.3647
			</td>
			<td>
				4 بايتات
			</td>
		</tr>
</tbody></table>
<h3>
	BINARY و VARBINARY
</h3>

<p>
	يمثل النوعان BINARY و VARBINARY البيانات الثنائية ذات الطول الثابت أو المتغير. ويُصاغان على النحو التالي:
</p>

<pre class="ipsCode">
BINARY [ ( n_bytes ) ]
VARBINARY [ ( n_bytes | max ) ]
</pre>

<p>
	يمكن أن يكون <code>‎n_bytes‎</code> أي عدد محصور بين 1 إلى 8000 أثمون. وتشير قيمة <code>max</code> إلى أنّ الحد الأقصى لمساحة التخزين هو <code>‎2^31-1‎‏</code>.
</p>

<p>
	أمثلة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_13" style="">
<span class="pln">SELECT CAST</span><span class="pun">(</span><span class="lit">12345</span><span class="pln"> AS BINARY</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">0x00000000000000003039</span><span class="pln">
SELECT CAST</span><span class="pun">(</span><span class="lit">12345</span><span class="pln"> AS VARBINARY</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="lit">0x00003039</span></pre>

<h3>
	CHAR و VARCHAR
</h3>

<p>
	يمثل النوعان CHAR و VARCHAR البيانات النصية ذات الطول الثابت أو المتغير. ويُصاغان على النحو التالي:
</p>

<pre class="ipsCode">
CHAR [ ( n_chars ) ]
VARCHAR [ ( n_chars ) ]
</pre>

<p>
	أمثلة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_15" style="">
<span class="pln">SELECT CAST</span><span class="pun">(</span><span class="str">'ABC'</span><span class="pln"> AS CHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'ABC       '</span><span class="pln"> </span><span class="pun">(إزاحة</span><span class="pln"> </span><span class="pun">بمسافات</span><span class="pln"> </span><span class="pun">بيضاء</span><span class="pln"> </span><span class="pun">إلى</span><span class="pln"> </span><span class="pun">اليمين)</span><span class="pln">
SELECT CAST</span><span class="pun">(</span><span class="str">'ABC'</span><span class="pln"> AS VARCHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'ABC'</span><span class="pln"> </span><span class="pun">(لا</span><span class="pln"> </span><span class="pun">إزاحة)</span><span class="pln">
SELECT CAST</span><span class="pun">(</span><span class="str">'ABCDEFGHIJKLMNOPQRSTUVWXYZ'</span><span class="pln"> AS CHAR</span><span class="pun">(</span><span class="lit">10</span><span class="pun">))</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'ABCDEFGHIJ'</span><span class="pln"> </span><span class="pun">(تُقصّ</span><span class="pln"> </span><span class="pun">إلى</span><span class="pln"> </span><span class="pun">عشرة</span><span class="pln"> </span><span class="pun">أحرف</span><span class="pln"> </span><span class="pun">فقط)</span></pre>

<h3>
	NCHAR و NVARCHAR
</h3>

<p>
	يمثل النوعان NCHAR و NVARCHAR نصوص اليونيكود ذات الطول الثابت أو المتغير. ويُصاغان على النحو التالي:
</p>

<pre class="ipsCode">
NCHAR [ ( n_chars ) ]
NVARCHAR [ ( n_chars | MAX ) ]
</pre>

<p>
	استخدم <code>‎MAX‎</code> لأجل السلاسل النصية الطويلة التي يمكن أن تتجاوز 8000 حرفًا.
</p>

<h3>
	UNIQUEIDENTIFIER
</h3>

<p>
	يمثل هذا النوع مُعرّفا كونيا فريدًا (Universally Unique IDentifier أو UUID) أو معرّفًا عامّا فريدًا (globally unique identifier أو GUID) مُخزّنا على 16 أثمونًا.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_17" style="">
<span class="pln">DECLARE </span><span class="lit">@GUID</span><span class="pln"> UNIQUEIDENTIFIER </span><span class="pun">=</span><span class="pln"> NEWID</span><span class="pun">();</span><span class="pln">
SELECT </span><span class="lit">@GUID</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'E28B3BD9-9174-41A9-8508-899A78A33540'</span><span class="pln">
DECLARE </span><span class="lit">@bad_GUID_string</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'E28B3BD9-9174-41A9-8508-899A78A33540_foobarbaz'</span><span class="pln">
SELECT
 </span><span class="lit">@bad_GUID_string</span><span class="pun">,</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'E28B3BD9-9174-41A9-8508-899A78A33540_foobarbaz'</span><span class="pln">
 CONVERT</span><span class="pun">(</span><span class="pln">UNIQUEIDENTIFIER</span><span class="pun">,</span><span class="pln"> </span><span class="lit">@bad_GUID_string</span><span class="pun">)</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="str">'E28B3BD9-9174-41A9-8508-899A78A33540'</span></pre>

<h2>
	الكلمة المفتاحية NULL
</h2>

<p>
	تمثل الكلمة المفتاحية <code>‎NULL‎</code> في SQL، وكذلك في لغات البرمجة الأخرى، القيمة المعدومة، أو "لا شيء". وتُستخدم عادة في SQL للإشارة إلى "عدم وجود قيمة".
</p>

<p>
	من المهم التمييز بينها وبين القيم الفارغة، مثل السلسلة النصية <code>‎''‎</code> الفارغة أو الرقم <code>‎0‎</code>، إذ لا يُعدّ أي منهما في الواقع معدومًا (<code>‎NULL‎</code>). من المهم أيضًا تجنّب إحاطة <code>‎NULL‎</code> بعلامات الاقتباس، على شاكلة <code>‎'NULL'‎</code>، والتي يمكن استخدامها في الأعمدة التي تقبل القيم النصية، بيد أنّها لا تمثّل القيمة <code>‎NULL‎</code>، ويمكن أن تسبّب أخطاءً، وتفسد البيانات.
</p>

<h3>
	ترشيح NULL في الاستعلامات
</h3>

<p>
	تختلف صياغة ترشيح <code>‎NULL‎</code> (أي عدم وجود قيمة) في كتل <code>‎WHERE‎</code> عن ترشيح القيم الأخرى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_19" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">ManagerId</span><span class="pln"> IS NULL </span><span class="pun">;</span><span class="pln">
SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Employees</span><span class="pln"> WHERE </span><span class="typ">ManagerId</span><span class="pln"> IS NOT NULL </span><span class="pun">;</span></pre>

<p>
	لاحظ أنّه لمّا لم تكن <code>‎NULL‎</code> مساوية لأيّ شيء آخر، ولا حتى لنفسها، فستُعيد عوامل الموازنة <code>‎= NULL‎</code> أو <code>‎&lt;&gt; NULL‎</code> (أو <code>‎!= NULL‎</code> ) دائمًا القيمة المنطقية الخاصة <code>UNKNOWN</code>، والتي ترفضها <code>WHERE</code>.
</p>

<p>
	ترشِّح <code>‎WHERE‎</code> كل الصفوف التي يساوي شرطها القيمة <code>‎FALSE‎</code> أو <code>UNKNOWN</code>، ولا تحتفظ إلا بالصفوف ذات الشرط الصحيح (<code>‎TRUE‎</code>).
</p>

<h3>
	الأعمدة المعدومة في الجداول
</h3>

<p>
	عند إنشاء الجداول، يمكن جعل العمود قابلًا للإلغاء (nullable) أو غير قابل للإلغاء.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_21" style="">
<span class="pln">CREATE TABLE </span><span class="typ">MyTable</span><span class="pln">
</span><span class="pun">(</span><span class="pln">
    </span><span class="typ">MyCol1</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> non</span><span class="pun">-</span><span class="pln">nullable
    </span><span class="typ">MyCol2</span><span class="pln"> INT NULL </span><span class="pun">--</span><span class="pln"> nullable
</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span></pre>

<p>
	افتراضيًا، تكون جميع الأعمدة قابلة للإلغاء (باستثناء تلك الموجودة في قيد المفتاح الأساسي - primary key constraint) ما لم نعيّن القيد عند القيمة <code>‎NOT NULL‎</code> صراحة. وسينتج خطأ عن محاولة تعيين <code>‎NULL‎</code> لعمود غير قابل للإلغاء.
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_23" style="">
<span class="pln">INSERT INTO </span><span class="typ">MyTable</span><span class="pln"> </span><span class="pun">(</span><span class="typ">MyCol1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">MyCol2</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> NULL</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span><span class="pln"> </span><span class="pun">--</span><span class="pln"> </span><span class="pun">صحيح</span><span class="pln">
INSERT INTO </span><span class="typ">MyTable</span><span class="pln"> </span><span class="pun">(</span><span class="typ">MyCol1</span><span class="pun">,</span><span class="pln"> </span><span class="typ">MyCol2</span><span class="pun">)</span><span class="pln"> VALUES </span><span class="pun">(</span><span class="pln">NULL</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span><span class="pln"> </span></pre>

<p>
	لا يمكن إدراج القيمة NULL في العمود 'MyCol1' في الجدول 'MyTable' لأنّ العمود لا يسمح بالقيمة المعدومة، لذا ستفشل عملية الإدراج <code>INSERT</code>.
</p>

<h3>
	إسناد NULL إلى حقل
</h3>

<p>
	إسناد القيمة <code>‎NULL‎</code> إلى حقل يشبه إسناد أيّ قيمة أخرى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_25" style="">
<span class="pln">UPDATE </span><span class="typ">Employees</span><span class="pln">
SET </span><span class="typ">ManagerId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> NULL
WHERE </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">4</span></pre>

<h3>
	إدراج الصفوف التي تحتوي حقولًا معدومة (NULL fields)
</h3>

<p>
	على سبيل المثال، إدراج بيانات موظف بدون رقم هاتف، وبدون مدير في جدول الموظفين Employees:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_27" style="">
<span class="pln">INSERT INTO </span><span class="typ">Employees</span><span class="pln">
 </span><span class="pun">(</span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">FName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">PhoneNumber</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ManagerId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">DepartmentId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Salary</span><span class="pun">,</span><span class="pln"> </span><span class="typ">HireDate</span><span class="pun">)</span><span class="pln">
VALUES
 </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Jane'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Doe'</span><span class="pun">,</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">800</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2016-07-22'</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span></pre>

<h2>
	أمثلة على قواعد البيانات والجداول
</h2>

<p>
	إليك بعض الأمثلة التوضيحية عن قواعد البيانات.
</p>

<h3>
	قاعدة بيانات متجر السيارات
</h3>

<p>
	سوف نستعرض في المثال التالي قاعدة بيانات لمتجر يبيع السيارات، سنخزّن في القاعدة قوائم تضمّ الأقسام والموظفين والعملاء وسيارات العملاء. وسنستخدم المفاتيح الخارجية (foreign keys) لإنشاء علاقات بين مختلف الجداول.
</p>

<p>
	هذا تطبيق <a href="http://sqlfiddle.com/#!9/faf2f/1" rel="external nofollow">حي للمثال</a>:
</p>

<h4>
	العلاقات بين الجداول
</h4>

<ul>
<li>
		يضم كل قسم 0 موظف أو أكثر،
	</li>
	<li>
		ولكل موظف مدير واحد أو أكثر،
	</li>
	<li>
		وقد يكون لكل عميل 0 سيارة أو أكثر
	</li>
</ul>
<p>
	الجدول <strong>Departments</strong>:
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				HR
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Sales
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Tech
			</td>
		</tr>
</tbody></table>
<p>
	لننشئ الجدول عبر SQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_29" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Departments</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Name</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">25</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Departments</span><span class="pln">
    </span><span class="pun">([</span><span class="typ">Id</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Name</span><span class="pun">])</span><span class="pln">
VALUES
   </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'HR'</span><span class="pun">),</span><span class="pln">
   </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Sales'</span><span class="pun">),</span><span class="pln">
   </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Tech'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	الجدول <strong>Employees</strong>:
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				ManagerId
			</th>
			<th>
				DepartmentId
			</th>
			<th>
				Salary
			</th>
			<th>
				HireDate
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				James
			</td>
			<td>
				Smith
			</td>
			<td>
				1234567890
			</td>
			<td>
				NULL
			</td>
			<td>
				1
			</td>
			<td>
				1000
			</td>
			<td>
				01-01-2002
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				John
			</td>
			<td>
				Johnson
			</td>
			<td>
				2468101214
			</td>
			<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				400
			</td>
			<td>
				23-03-2005
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Michael
			</td>
			<td>
				Williams
			</td>
			<td>
				1357911131
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				600
			</td>
			<td>
				12-05-2009
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Johnathon
			</td>
			<td>
				Smith
			</td>
			<td>
				1212121212
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				500
			</td>
			<td>
				24-07-2016
			</td>
		</tr>
</tbody></table>
<p>
	لننشئ الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_31" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Employees</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
   </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">FName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">LName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">PhoneNumber</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">11</span><span class="pun">),</span><span class="pln">
   </span><span class="typ">ManagerId</span><span class="pln"> INT</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">DepartmentId</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
</span><span class="typ">Salary</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
   </span><span class="typ">HireDate</span><span class="pln"> DATETIME NOT NULL</span><span class="pun">,</span><span class="pln">
   PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
   FOREIGN KEY </span><span class="pun">(</span><span class="typ">ManagerId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Employees</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
   FOREIGN KEY </span><span class="pun">(</span><span class="typ">DepartmentId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Departments</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Employees</span><span class="pln">
   </span><span class="pun">([</span><span class="typ">Id</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">FName</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">LName</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">PhoneNumber</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">ManagerId</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">DepartmentId</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Salary</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">HireDate</span><span class="pun">])</span><span class="pln">
VALUES
   </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'James'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Smith'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1234567890</span><span class="pun">,</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1000</span><span class="pun">,</span><span class="pln"> </span><span class="str">'01-01-2002'</span><span class="pun">),</span><span class="pln">
   </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'John'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Johnson'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2468101214</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">400</span><span class="pun">,</span><span class="pln"> </span><span class="str">'23-03-2005'</span><span class="pun">),</span><span class="pln">
   </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Michael'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Williams'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1357911131</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">600</span><span class="pun">,</span><span class="pln"> </span><span class="str">'12-05-2009'</span><span class="pun">),</span><span class="pln">
   </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Johnathon'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Smith'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1212121212</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">500</span><span class="pun">,</span><span class="pln"> </span><span class="str">'24-07-2016'</span><span class="pun">)</span></pre>

<p>
	الجدول <strong>Customers</strong>:
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				FName
			</th>
			<th>
				LName
			</th>
			<th>
				Email
			</th>
			<th>
				PhoneNumber
			</th>
			<th>
				PreferredContact
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				William
			</td>
			<td>
				Jones
			</td>
			<td>
				william.jones@example.com
			</td>
			<td>
				3347927472
			</td>
			<td>
				PHONE
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				David
			</td>
			<td>
				Miller
			</td>
			<td>
				dmiller@example.net
			</td>
			<td>
				2137921892
			</td>
			<td>
				EMAIL
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Richard
			</td>
			<td>
				Davis
			</td>
			<td>
				richard0123@example.com
			</td>
			<td>
				NULL
			</td>
			<td>
				EMAIL
			</td>
		</tr>
</tbody></table>
<p>
	لننشئ الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_33" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Customers</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">35</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Email</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PhoneNumber</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">11</span><span class="pun">),</span><span class="pln">
    </span><span class="typ">PreferredContact</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">5</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Customers</span><span class="pln">
     </span><span class="pun">([</span><span class="typ">Id</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">FName</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">LName</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Email</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">PhoneNumber</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">PreferredContact</span><span class="pun">])</span><span class="pln">
VALUES
     </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'William'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Jones'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'william.jones@example.com'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'3347927472'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'PHONE'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'David'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Miller'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'dmiller@example.net'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2137921892'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EMAIL'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Richard'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Davis'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'richard0123@example.com'</span><span class="pun">,</span><span class="pln"> NULL</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EMAIL'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	الجدول <strong>Cars</strong>:
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				CustomerId
			</th>
			<th>
				EmployeeId
			</th>
			<th>
				Model
			</th>
			<th>
				Status
			</th>
			<th>
				Total Cost
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				Ford F-150
			</td>
			<td>
				READY
			</td>
			<td>
				230
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				2
			</td>
			<td>
				Ford F-150
			</td>
			<td>
				READY
			</td>
			<td>
				200
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				2
			</td>
			<td>
				1
			</td>
			<td>
				Ford Mustang
			</td>
			<td>
				WAITING
			</td>
			<td>
				100
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				3
			</td>
			<td>
				3
			</td>
			<td>
				Toyota Prius
			</td>
			<td>
				WORKING
			</td>
			<td>
				1254
			</td>
		</tr>
</tbody></table>
<p>
	تعليمات SQL لإنشاء الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_35" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Cars</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">CustomerId</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">EmployeeId</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Model</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 </span><span class="typ">Status</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">25</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">TotalCost</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
 FOREIGN KEY </span><span class="pun">(</span><span class="typ">CustomerId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Customers</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
 FOREIGN KEY </span><span class="pun">(</span><span class="typ">EmployeeId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Employees</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Cars</span><span class="pln">
    </span><span class="pun">([</span><span class="typ">Id</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">CustomerId</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">EmployeeId</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Model</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">Status</span><span class="pun">],</span><span class="pln"> </span><span class="pun">[</span><span class="typ">TotalCost</span><span class="pun">])</span><span class="pln">
VALUES
     </span><span class="pun">(</span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Ford F-150'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'READY'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'230'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Ford F-150'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'READY'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'200'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'3'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'2'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Ford Mustang'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'WAITING'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'100'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'4'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'3'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'3'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Toyota Prius'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'WORKING'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'1254'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<h3>
	قاعدة بيانات المكتبة
</h3>

<p>
	سننشئ في هذا المثال قاعدة بيانات خاصة بمكتبة، ستحتوي القاعدة على جداول لتخزين المؤلفين والكتب والكتاب. هنا تجد <a href="http://sqlfiddle.com/#!9/7c06f/1" rel="external nofollow">مثالًا حيًّا</a> للقاعدة.
</p>

<p>
	يُعرف جدولَا المؤلفين والكتب بالجداول الأساسية (base tables)، لأنهما يحتويان على تعريف العمود، وكذا البيانات الخاصة بالكيانات الفعلية في النموذج العلائقي (relational model). ويُعرف الجدول BookAuthors باسم جدول العلاقة (relationship table)، لأنّه يحدّد العلاقة بين جدول الكتب Books والمؤلفين Authors.
</p>

<h4>
	العلاقات بين الجداول
</h4>

<ul>
<li>
		يمكن أن يكون لكل مؤلف كتاب واحد أو أكثر.
	</li>
	<li>
		كل كتاب يمكن أن يكون له مؤلف واحد أو أكثر
	</li>
</ul>
<p>
	الجدول Authors (<a href="http://sqlfiddle.com/#!9/7c06f/2" rel="external nofollow">عرض الجدول</a>):
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				Name
			</th>
			<th>
				Country
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				J.D. Salinger
			</td>
			<td>
				USA
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				F. Scott. Fitzgerald
			</td>
			<td>
				USA
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Jane Austen
			</td>
			<td>
				UK
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				Scott Hanselman
			</td>
			<td>
				USA
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				Jason N. Gaylord
			</td>
			<td>
				USA
			</td>
		</tr>
<tr>
<td>
				6
			</td>
			<td>
				Pranav Rastogi
			</td>
			<td>
				India
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				Todd Miranda
			</td>
			<td>
				USA
			</td>
		</tr>
<tr>
<td>
				8
			</td>
			<td>
				Christian Wenz
			</td>
			<td>
				USA
			</td>
		</tr>
</tbody></table>
<p>
	لننشئ الجدول الآن:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_37" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Authors</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Name</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">70</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Country</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">100</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Authors</span><span class="pln">
     </span><span class="pun">(</span><span class="typ">Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Country</span><span class="pun">)</span><span class="pln">
VALUES
     </span><span class="pun">(</span><span class="str">'J.D. Salinger'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'F. Scott. Fitzgerald'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Jane Austen'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'UK'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Scott Hanselman'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Jason N. Gaylord'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Pranav Rastogi'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'India'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Todd Miranda'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="str">'Christian Wenz'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	الجدول <strong>Books</strong> ( <a href="http://sqlfiddle.com/#!9/7c06f/3" rel="external nofollow">عرض الجدول</a>):
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				Title
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				The Catcher in the Rye
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				Nine Stories
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				Franny and Zooey
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				The Great Gatsby
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				Tender id the Night
			</td>
		</tr>
<tr>
<td>
				6
			</td>
			<td>
				Pride and Prejudice
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				Professional ASP.NET 4.5 in C# and VB
			</td>
		</tr>
</tbody></table>
<p>
	عبارات SQL لإنشاء الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_39" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Books</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Title</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">50</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">Books</span><span class="pln">
     </span><span class="pun">(</span><span class="typ">Id</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Title</span><span class="pun">)</span><span class="pln">
VALUES
     </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="str">'The Catcher in the Rye'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Nine Stories'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Franny and Zooey'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="str">'The Great Gatsby'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Tender id the Night'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Pride and Prejudice'</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Professional ASP.NET 4.5 in C# and VB'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	الجدول BooksAuthors (<a href="http://sqlfiddle.com/#!9/7c06f/4" rel="external nofollow">عرض الجدول</a>):
</p>

<table><tbody>
<tr>
<th>
				BookId
			</th>
			<th>
				AuthorId
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				1
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				2
			</td>
		</tr>
<tr>
<td>
				6
			</td>
			<td>
				3
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				4
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				5
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				6
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				7
			</td>
		</tr>
<tr>
<td>
				7
			</td>
			<td>
				8
			</td>
		</tr>
</tbody></table>
<p>
	تعليمات SQL لإنشاء الجدول:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_41" style="">
<span class="pln">CREATE TABLE </span><span class="typ">BooksAuthors</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">AuthorId</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">BookId</span><span class="pln">  INT NOT NULL</span><span class="pun">,</span><span class="pln">
 FOREIGN KEY </span><span class="pun">(</span><span class="typ">AuthorId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Authors</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">),</span><span class="pln">
 FOREIGN KEY </span><span class="pun">(</span><span class="typ">BookId</span><span class="pun">)</span><span class="pln"> REFERENCES </span><span class="typ">Books</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span><span class="pln">
INSERT INTO </span><span class="typ">BooksAuthors</span><span class="pln">
    </span><span class="pun">(</span><span class="typ">BookId</span><span class="pun">,</span><span class="pln"> </span><span class="typ">AuthorId</span><span class="pun">)</span><span class="pln">
VALUES
     </span><span class="pun">(</span><span class="lit">1</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">2</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">3</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">4</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">5</span><span class="pun">,</span><span class="pln"> </span><span class="lit">2</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">6</span><span class="pun">,</span><span class="pln"> </span><span class="lit">3</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">4</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">5</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">6</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">7</span><span class="pun">),</span><span class="pln">
     </span><span class="pun">(</span><span class="lit">7</span><span class="pun">,</span><span class="pln"> </span><span class="lit">8</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	الآن، إن أردت عرض جميع المؤلفين، فاكتب ما يلي (<a href="http://sqlfiddle.com/#!9/7c06f/2" rel="external nofollow">عرض المثال الحي</a>):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_43" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Authors</span><span class="pun">;</span></pre>

<p>
	عرض جميع عناوين الكتب (<a href="http://sqlfiddle.com/#!9/7c06f/3" rel="external nofollow">عرض مثال حي</a>):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_45" style="">
<span class="pln">SELECT </span><span class="pun">*</span><span class="pln"> FROM </span><span class="typ">Books</span><span class="pun">;</span></pre>

<p>
	عرض جميع الكتب ومؤلفيها (<a href="http://sqlfiddle.com/#!9/7c06f/5" rel="external nofollow">عرض مثال حي</a>):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_47" style="">
<span class="pln">SELECT
   ba</span><span class="pun">.</span><span class="typ">AuthorId</span><span class="pun">,</span><span class="pln">
   a</span><span class="pun">.</span><span class="typ">Name</span><span class="pln"> </span><span class="typ">AuthorName</span><span class="pun">,</span><span class="pln">
   ba</span><span class="pun">.</span><span class="typ">BookId</span><span class="pun">,</span><span class="pln">
   b</span><span class="pun">.</span><span class="typ">Title</span><span class="pln"> </span><span class="typ">BookTitle</span><span class="pln">
FROM </span><span class="typ">BooksAuthors</span><span class="pln"> ba
   INNER JOIN </span><span class="typ">Authors</span><span class="pln"> a ON a</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> ba</span><span class="pun">.</span><span class="pln">authorid
   INNER JOIN </span><span class="typ">Books</span><span class="pln"> b ON b</span><span class="pun">.</span><span class="pln">id </span><span class="pun">=</span><span class="pln"> ba</span><span class="pun">.</span><span class="pln">bookid
</span><span class="pun">;</span></pre>

<h3>
	جدول الدول
</h3>

<p>
	سننشئ في هذا المثال جدولًا للبلدان. يُستخدم جدول البلدان في العديد من المجالات، وخاصة في التطبيقات المالية التي تشمل العملات وأسعار الصرف.
</p>

<p>
	هذا <a href="http://sqlfiddle.com/#!9/14cfc6" rel="external nofollow">مثال حي</a>.
</p>

<p>
	تطلب بعض البرمجيات الخاصة بتحليل الأسواق مثل بلومبرج ورويترز أن تعطيهم رمزًا مؤلفًا من حرفين أو ثلاث يمثل الدولة، إلى جانب رمز العملة. يحتوي الجدول التالي على عمود يحتوي رموز <code>‎ISO‎</code> المؤلفة من حرفين، وكذلك على عمود يحتوي رموز <code>‎ISO3‎</code> المكونة من 3 أحرف، والتي تمثل الدول.
</p>

<p>
	الجدول <strong>Countries</strong> (<a href="http://sqlfiddle.com/#!9/14cfc6/1" rel="external nofollow">عرض الجدول</a>):
</p>

<table><tbody>
<tr>
<th>
				Id
			</th>
			<th>
				ISO
			</th>
			<th>
				ISO3
			</th>
			<th>
				ISONumeric
			</th>
			<th>
				CountryName
			</th>
			<th>
				Capital
			</th>
			<th>
				ContinentCode
			</th>
			<th>
				CurrencyCode
			</th>
		</tr>
<tr>
<td>
				1
			</td>
			<td>
				AU
			</td>
			<td>
				AUS
			</td>
			<td>
				36
			</td>
			<td>
				Australia
			</td>
			<td>
				Canberra
			</td>
			<td>
				OC
			</td>
			<td>
				AUD
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				DE
			</td>
			<td>
				DEU
			</td>
			<td>
				276
			</td>
			<td>
				Germany
			</td>
			<td>
				Berlin
			</td>
			<td>
				EU
			</td>
			<td>
				EUR
			</td>
		</tr>
<tr>
<td>
				2
			</td>
			<td>
				IN
			</td>
			<td>
				IND
			</td>
			<td>
				356
			</td>
			<td>
				India
			</td>
			<td>
				New Delhi
			</td>
			<td>
				AS
			</td>
			<td>
				INR
			</td>
		</tr>
<tr>
<td>
				3
			</td>
			<td>
				LA
			</td>
			<td>
				LAO
			</td>
			<td>
				418
			</td>
			<td>
				Laos
			</td>
			<td>
				Vientiane
			</td>
			<td>
				AS
			</td>
			<td>
				LAK
			</td>
		</tr>
<tr>
<td>
				4
			</td>
			<td>
				US
			</td>
			<td>
				USA
			</td>
			<td>
				840
			</td>
			<td>
				United States
			</td>
			<td>
				Washington
			</td>
			<td>
				NA
			</td>
			<td>
				USD
			</td>
		</tr>
<tr>
<td>
				5
			</td>
			<td>
				ZW
			</td>
			<td>
				ZWE
			</td>
			<td>
				716
			</td>
			<td>
				Zimbabwe
			</td>
			<td>
				Harare
			</td>
			<td>
				AF
			</td>
			<td>
				ZWL
			</td>
		</tr>
</tbody></table>
<p>
	لننشئ جدول الدول في SQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3498_49" style="">
<span class="pln">CREATE TABLE </span><span class="typ">Countries</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">Id</span><span class="pln"> INT NOT NULL AUTO_INCREMENT</span><span class="pun">,</span><span class="pln">
    ISO VARCHAR</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    ISO3 VARCHAR</span><span class="pun">(</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">ISONumeric</span><span class="pln"> INT NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">CountryName</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Capital</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">64</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">ContinentCode</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">2</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">CurrencyCode</span><span class="pln"> VARCHAR</span><span class="pun">(</span><span class="lit">3</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
 PRIMARY KEY</span><span class="pun">(</span><span class="typ">Id</span><span class="pun">)</span><span class="pln">
</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span><span class="pln">
INSERT INTO </span><span class="typ">Countries</span><span class="pln">
    </span><span class="pun">(</span><span class="pln">ISO</span><span class="pun">,</span><span class="pln"> ISO3</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ISONumeric</span><span class="pun">,</span><span class="pln"> </span><span class="typ">CountryName</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Capital</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ContinentCode</span><span class="pun">,</span><span class="pln"> </span><span class="typ">CurrencyCode</span><span class="pun">)</span><span class="pln">
VALUES
    </span><span class="pun">(</span><span class="str">'AU'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'AUS'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">36</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Australia'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Canberra'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'OC'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'AUD'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'DE'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'DEU'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">276</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Germany'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Berlin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EU'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'EUR'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'IN'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'IND'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">356</span><span class="pun">,</span><span class="pln"> </span><span class="str">'India'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'New Delhi'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'AS'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'INR'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'LA'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'LAO'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">418</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Laos'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Vientiane'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'AS'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'LAK'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'US'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USA'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">840</span><span class="pun">,</span><span class="pln"> </span><span class="str">'United States'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Washington'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'NA'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'USD'</span><span class="pun">),</span><span class="pln">
    </span><span class="pun">(</span><span class="str">'ZW'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'ZWE'</span><span class="pun">,</span><span class="pln"> </span><span class="lit">716</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Zimbabwe'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'Harare'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'AF'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'ZWL'</span><span class="pun">)</span><span class="pln">
</span><span class="pun">;</span></pre>

<p>
	ترجمة -وبتصرّف- للفصول الخمسة الأولى من الكتاب <a href="https://goalkicker.com/SQLBook" rel="external nofollow">SQL Notes for Professionals</a>
</p>

<h2>
	اقرأ أيضًا:
</h2>

<ul>
<li>
		المقال التالي: <a href="https://academy.hsoub.com/programming/sql/%D8%AC%D9%84%D8%A8-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-%D8%B9%D8%A8%D8%B1-select-%D9%81%D9%8A-sql-r845/" rel="">جلب الاستعلامات عبر SELECT في SQL</a>
	</li>
	<li>
		النسخة العربية الكاملة لكتاب <a href="https://academy.hsoub.com/files/16-%D9%85%D9%84%D8%A7%D8%AD%D8%B8%D8%A7%D8%AA-%D9%84%D9%84%D8%B9%D8%A7%D9%85%D9%84%D9%8A%D9%86-%D8%A8%D9%84%D8%BA%D8%A9-sql/" rel="">ملاحظات للعاملين بلغة SQL 1.0.0</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">844</guid><pubDate>Wed, 18 Mar 2020 13:09:00 +0000</pubDate></item><item><title>&#x62A;&#x639;&#x644;&#x645; &#x644;&#x63A;&#x629; &#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645; SQL &#x628;&#x627;&#x644;&#x623;&#x645;&#x62B;&#x644;&#x629; &#x627;&#x644;&#x639;&#x645;&#x644;&#x64A;&#x629;</title><link>https://academy.hsoub.com/programming/sql/%D8%AA%D8%B9%D9%84%D9%85-%D9%84%D8%BA%D8%A9-%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-sql-%D8%A8%D8%A7%D9%84%D8%A3%D9%85%D8%AB%D9%84%D8%A9-%D8%A7%D9%84%D8%B9%D9%85%D9%84%D9%8A%D8%A9-r637/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2018_05/5b05b98802fb2_---SQL--.png.0e05b6eff9c65af200711428bdc76290.png" /></p>

<p>
	<iframe allow="autoplay; encrypted-media" allowfullscreen="" frameborder="0" height="394" width="700" src="https://www.youtube.com/embed/OYF0960x3MU?rel=0"></iframe>
</p>

<p>
	مرّت قواعد البيانات بأشكال عديدة تطورت مع تطور التكنولوجيا ولعل أشهرها قواعد البيانات العلائقية relational database، والتي تعتمد على مفهوم الجدول كوحدة تخزين أساسية لتنظيم البيانات.
</p>

<p>
	وبالطبع فإن قواعد البيانات بحاجة إلى برامج وأدوات خاصة لإدارتها والتعامل معها، تعرف هذه البرامج باسم أنظمة إدارة قواعد البيانات Data Base Managements Systems DBMS ومن أشهر أنظمة إدارة قواعد البيانات: Oracle, Microsoft SQL Server, MySQL, Microsoft Access وغيرها من باقي الأنظمة.
</p>

<p>
	سنشرح في هذا الدرس أساسيات لغة الاستعلام SQL عبر الأمثلة العملية وذلك باستخدام لوحة التحكم phpMyAdmin.
</p>

<p>
	سنشرح كيفية إنشاء جدول جديد عبر استخدام تعليمة CREATE وكيف من الممكن إدخال البيانات وجلب البيانات من الجداول وذلك باستخدام تعليمتي INSERT INTO لتخزين السجلات في الجدول والتعليمة SELECT لجلب البيانات من جدول معين. بالإضافة إلى ذلك سنتعلّم كيف نقوم بتحديث وحذف السجلات، بالإضافة إلى أخذ لمحة سريعة عن التوابع الرياضية التي تقدمها SQL. 
</p>
]]></description><guid isPermaLink="false">637</guid><pubDate>Tue, 22 May 2018 14:34:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x644;&#x627;&#x642;&#x627;&#x62A; &#x628;&#x64A;&#x646; &#x627;&#x644;&#x62C;&#x62F;&#x627;&#x648;&#x644; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%AC%D8%AF%D8%A7%D9%88%D9%84-%D9%81%D9%8A-sql-r590/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a416e5ec3271_main(12).png.302ffa76bcfd440537f9c7c26450e5c6.png" /></p>
<p>
	سنتحدث في هذا المقال عن مفهوم العلاقات بين جداول قاعدة البيانات، وما أنواع هذه العلاقات وكيف تتمثل وما هو أثرها على العمل.
</p>

<h2 id="ما-هي-العلاقات-بين-الجداول">
	ما هي العلاقات بين الجداول
</h2>

<p>
	عند إنشاء جداول في <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قاعدة البيانات</a>، فإن الظاهر لنا أننا نقوم ببناء جداول منفصلة وغير مترابطة، ولكننا في الواقع العملي نحتاج لربط هذه الكيانات المنفصلة بحيث تُبنَى علاقات تحكم البيانات الموجودة في هذه الجداول، وتحكم طريقة التعامل مع هذه البيانات.
</p>

<p>
	تنشَأ العلاقة بين جدوليْن عندما يُربط عمودان فيهما مع بعضهما عن طريق وجود قيود مطبقة على العمودين، بحيث يكون قيد المفتاح الرئيسي على عمود في الجدول “الأب” وقيد المفتاح الأجنبي على العمود في الجدول “الابن”، وعادة يكون اسم العمودين واحدًا في كلا الجدولين.
</p>

<p>
	مثلا، لحفظ عناوين الأشخاص نستطيع إنشاء جدول باسم <code>Address</code> ونربطه بجدول الأشخاص <code>Persons</code> بعلاقة تحكم البيانات الموجودة في الجدولين، بحيث يكون لكل شخص في الجدول <code>Persons</code> عنوان واحد مرتبط به في الجدول <code>Address</code>. يُربَط الجدولان عن طريق عمود باسم <code>Person_Id</code> في كلا الجدولين.
</p>

<p>
	مثال آخر، لو أردنا أن نتابع عملية استعارة الكتب في مكتبة، فإننا سننشئ جدولًا باسم <code>Borrowed_Books</code> (كُتُب مُعارة) ونربطها بالجدول <code>Persons</code> عن طريق العمود <code>Person_Id</code>. يستطيع الشخص الواحد - في هذا النوع من الربط - أن يستعير أكثر من كتاب. في هذا المثال، لو أننا حفظنا بيانات الأشخاص والكتب المستعارة في جدول واحد، ستظهر لنا مشكلة تكرار البيانات Data Redundancy لأننا سنكرّر بيانات الشخص لكل كتاب يستعيره.
</p>

<h3 id="ماذا-نستفيد-من-بناء-العلاقات-بين-الجداول">
	ماذا نستفيد من بناء العلاقات بين الجداول؟
</h3>

<ol>
	<li>
		التخلص من مشكلة تكرار البيانات عن طريق فصلها وحفظها في أكثر من جدول، فمشكلة تكرار البيانات هي عدو مستخدمي قواعد البيانات ومسؤوليها، لأنها تتسبب بزيادة حجم قاعدة البيانات بقدر كبير وبسرعة، وترفع السرعات المطلوبة لتنفيذ الاستعلامات، وتجعل من موضوع صيانة قاعدة البيانات كابوسا مقلقا.
	</li>
	<li>
		الحفاظ على دقة وسلامة البيانات في قاعدة البيانات، فمع وجود العلاقات بين الجداول، سوف تضمن مثلا عدم وجود كتاب مُعار ليس له شخص استعاره، أو عنوان وهمي ليس له صاحب، وقس على ذلك العديد من الأمثلة.
	</li>
	<li>
		استخراج البيانات من أكثر من جدول بكفاءة وسرعة عن طريق بناء جمل ربط استعلامية تطلب المعلومات من أعمدة مختلفة في جداول مختلفة، وإخراج النتيجة بطريقة مفيدة ومرتبة.
	</li>
</ol>

<h2 id="أنواع-العلاقات">
	أنواع العلاقات
</h2>

<p>
	توجد أربعة أنواع من العلاقات بين الجداول كالتالي:
</p>

<ol>
	<li>
		علاقة واحد إلى واحد (One-to-One).
	</li>
	<li>
		علاقة واحد إلى كثير أو علاقة كثير إلى واحد (One-to-Many / Many-to-One).
	</li>
	<li>
		علاقة كثير إلى كثير (Many-to-Many).
	</li>
	<li>
		علاقة المرجعية الذاتية (Self Referencing).
	</li>
</ol>

<h3 id="علاقة-واحد-إلى-واحد">
	علاقة واحد إلى واحد
</h3>

<p>
	لنفترض أن الجدول <code>Persons</code> لديه البنية والبيانات التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Address
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					31
				</td>
				<td style=" padding: 5px 10px;">
					12 Main St, Doha
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
				<td style=" padding: 5px 10px;">
					Gaza, Middle Center
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	نستطيع أن نضع بيانات العنوان في جدول منفصل ونسميه <code>Address</code> وتكون بنية الجدوليْن كالتالي.
</p>

<ul>
	<li>
		الجدول <code>Persons</code>:
	</li>
</ul>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Address_Id
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					31
				</td>
				<td style=" padding: 5px 10px;">
					1
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
				<td style=" padding: 5px 10px;">
					2
				</td>
			</tr>
		</tbody>
	</table>
</center>

<ul>
	<li>
		الجدول <code>Address</code>:
	</li>
</ul>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Address_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Address
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					1
				</td>
				<td style=" padding: 5px 10px;">
					12 Main St, Doha
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					2
				</td>
				<td style=" padding: 5px 10px;">
					Gaza, Middle Center
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	لاحظ أنه أصبح لدينا عمود بنفس الاسم <code>Address_Id</code> في كلا الجدولين. لبناء العلاقة بين الجدولين، طبّقنا قيد المفتاح الأجنبي على العمود <code>Address_Id</code> في الجدول <code>Persons</code> بحيث يأخذ قيمه من العمود <code>Address_Id</code> في الجدول <code>Address</code> والمطبق عليه قيد المفتاح الرئيسي.
</p>

<p>
	أصبحت لدينا الآن علاقة بين الجدولين، وفي حال كان كل عنوان في الجدول <code>Address</code> يقترن فقط بشخص واحد في الجدول <code>Persons</code> فعندها نسمي هذه العلاقة واحدًا إلى واحد. يجب التنويه إلى أن هذا النوع من العلاقات غير مستخدم كثيرا، فالجدول الأول الذي يحتوي العنوان وبيانات الشخص يفي بالغرض في أغلب الأحيان.
</p>

<p>
	نستطيع تمثيل العلاقة بالشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="01_one_to_one.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26219" data-unique="mj24utkys" src="https://academy.hsoub.com/uploads/monthly_2017_12/01_one_to_one.png.7d733b9f386eab096e2df5f70c64851d.png">
</p>

<p>
	لاحظ أن وجود العلاقة اختياري، فمن الممكن أن يكون لدينا سجل في الجدول <code>Persons</code> دون عنوان له في الجدول <code>Address</code> وهذا مرتبط بعدم تطبيق قيد القيمة غير الفارغة على العمود <code>Address_Id</code>.
</p>

<p>
	في حال طُبِّق قيد غير القيمة غير الفارغة على العمود، فهنا تصبح العلاقة واجبة بين الجدولين، ولا يمكن أن نُنْشئ سجلًّا في الجدول <code>Persons</code> إلا بإدخال قيمة موجودة للعمود <code>Address_Id</code> وهو في مثالنا هذا غير منقطي نوعا ما.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h2 id="علاقة-واحد-إلى-كثير-أو-علاقة-كثير-إلى-واحد">
	علاقة واحد إلى كثير أو علاقة كثير إلى واحد
</h2>

<p>
	هذا النوع من العلاقات هو الشائع بين أنواع العلاقات بين الجداول في قاعدة البيانات، لوجود تطبيقات كثيرة عليه، فمثلا:
</p>

<ul>
	<li>
		الطالب (واحد) يستطيع أن يدرس أكثر من مساق (كثير).
	</li>
	<li>
		الطبيب يعالج ويتابع حالة مريض واحد أو أكثر.
	</li>
	<li>
		طلبية الشراء تحتوي على أكثر من عنصر.
	</li>
	<li>
		الشخص يستعير أكثر من كتاب.
	</li>
</ul>

<p>
	وقس على ذلك العديد من الأمثلة.
</p>

<p>
	لنفترض وجود جدول للزبناء <code>Customers</code> بالهيكلية التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Customer_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Customer_Name
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					1
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim Mohammed
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					2
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed Ahmed
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	نستطيع ربط جدول الزبناء السابق بجدولٍ للطلبيات <code>Orders</code> بعلاقة واحد إلى كثير، لتعبر العلاقة عن الطلبيات التي قام بها العملاء وقيمة كل طلبية وتاريخها. يمكن أن تكون هيكلية الجدول <code>Orders</code> كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Customer_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_Date
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_Value
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					997
				</td>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					1/5/2017
				</td>
				<td style=" padding: 5px 10px;">
					100
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					998
				</td>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					21/4/2016
				</td>
				<td style=" padding: 5px 10px;">
					150
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					999
				</td>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					21/4/2015
				</td>
				<td style=" padding: 5px 10px;">
					1500
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	تسمح هذه العلاقة للعميل بأن يطلُب طلبيةً أو أكثر، ويمكن ألا تكون له أية طلبية. ولكنّ كل طلبية في الجدول <code>Orders</code> ستكون تابعة لعميل واحد. ونستطيع تمثيل هذه العلاقة بالشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="02_many_to_one.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26220" data-unique="ypmhov4m7" src="https://academy.hsoub.com/uploads/monthly_2017_12/02_many_to_one.png.2428c8dce5fbd4390d4c1b2bac139165.png">
</p>

<h3 id="علاقة-كثير-إلى-كثير">
	علاقة كثير إلى كثير
</h3>

<p>
	في علاقة كثير إلى واحد، تكون العلاقة مبنية على أن يكون أحد أطرافها “واحدًا”، مثل طالب واحد، عميل واحد، طلبية واحدة، وفي الطرف الثاني “كثير”. نحتاج أحيانا أن يكون طرفا العلاقة كثيرين. فمثلا، قد تكون لدينا طلبية تحتوي أكثر من عنصر، ونفس العنصر يكون متواجدًا في أكثر من طلبية.
</p>

<p>
	في هذه الحالة نحتاج لوجود جدول إضافي لبناء العلاقة، فمثلا تكون هيكلية جدول <code>Orders</code> كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Customer_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_Date
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_Value
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					997
				</td>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					1/5/2017
				</td>
				<td style=" padding: 5px 10px;">
					100
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					998
				</td>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					21/4/2016
				</td>
				<td style=" padding: 5px 10px;">
					150
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					999
				</td>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					21/4/2015
				</td>
				<td style=" padding: 5px 10px;">
					1500
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	وهيكلية جدول <code>Items</code> كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Item_Id
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Item_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Item_Description
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					201
				</td>
				<td style=" padding: 5px 10px;">
					Hard Disk 1
				</td>
				<td style=" padding: 5px 10px;">
					1 Tera SSD Hard
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					202
				</td>
				<td style=" padding: 5px 10px;">
					Mouse
				</td>
				<td style=" padding: 5px 10px;">
					Microsoft Optical Mouse
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					203
				</td>
				<td style=" padding: 5px 10px;">
					LCD 42
				</td>
				<td style=" padding: 5px 10px;">
					42” LCD
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	نستطيع بناء علاقة كثير إلى كثير بين الجدولين السابقين بإضافة جدول ثالث يحلّ مكان الرابط وغرضه الوحيد هو بناء هذا النوع من العلاقات. نطلق عليه مثلا الاسم <code>Orders_Items</code>، ويكون بالهيكلية التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Order_Id
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Item_Id
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					997
				</td>
				<td style=" padding: 5px 10px;">
					201
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					997
				</td>
				<td style=" padding: 5px 10px;">
					202
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					999
				</td>
				<td style=" padding: 5px 10px;">
					201
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					999
				</td>
				<td style=" padding: 5px 10px;">
					202
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					999
				</td>
				<td style=" padding: 5px 10px;">
					203
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					998
				</td>
				<td style=" padding: 5px 10px;">
					203
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	يمثّل الشكل التالي علاقة كثير إلى كثير كما تظهر في الجدول <code>Orders_Items</code>:
</p>

<p style="text-align: center;">
	<img alt="03_many_to_many.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26221" data-unique="3fai9mlly" src="https://academy.hsoub.com/uploads/monthly_2017_12/03_many_to_many.png.0860f68a92d124195df1c424ce569fcd.png">
</p>

<h3 id="علاقة-المرجعية-الذاتية">
	علاقة المرجعية الذاتية
</h3>

<p>
	يُبنى هذا النوع من العلاقات عندما نريد أن نبني علاقة بين جدول ونفس الجدول، وأوضح مثال على هذا النوع من العلاقات هو جدول الموظفين الذي يحتوي على عمود رقم الموظف المسؤول، حيث يمكن ربط كل موظف بموظف آخر (مدير أو مسؤول) من نفس الجدول. فمثلا، لو كان لدينا جدول باسم <code>Employees</code> خاص بحفظ بيانات الموظفين، ستكون هيكليته على النحو التالي لتطبيق علاقة مرجعية ذاتية عليه:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Employee_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Employee_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Manager_Id
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					100
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim Elbouhissi
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Khaled Saber
				</td>
				<td style=" padding: 5px 10px;">
					100
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Yasmeen Hadi
				</td>
				<td style=" padding: 5px 10px;">
					100
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Duaa Yousef
				</td>
				<td style=" padding: 5px 10px;">
					101
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Sami Saber
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	بعلاقة المرجعية الذاتية، من الممكن أن يكون للموظف مسؤولًا أو لا يكون، ومن الممكن أن يكون الموظف مسؤولا عن موظف أو أكثر، ويمكن تمثيل العلاقة بالشكل التالي.
</p>

<p style="text-align: center;">
	<img alt="04_auto_relation.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26222" data-unique="1hbsj6uhd" src="https://academy.hsoub.com/uploads/monthly_2017_12/04_auto_relation.png.36a322610618a0edc3a114be546b0c7d.png">
</p>
]]></description><guid isPermaLink="false">590</guid><pubDate>Fri, 28 Jul 2017 08:11:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x641;&#x647;&#x627;&#x631;&#x633; Indexes &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D9%81%D9%87%D8%A7%D8%B1%D8%B3-indexes-%D9%81%D9%8A-sql-r589/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a416db14ecbc_main(11).png.5c3adf073ec67e4fd3f7cc92cfbd782d.png" /></p>
<p>
	بعد أن تكلمنا في <a href="https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r588/" rel="">المقال السابق</a> عن موضوع جملة الاستعلام في SQL وكيفية الاستعلام عن البيانات في جدول معين وترشيحها وفق الشروط التي نرغب بها، سنتناول في هذا المقال موضوع الفهارس Indexes وما تمثله في قاعدة البيانات، وما هي الفائدة منها.
</p>

<h2 id="فهرس-الجدول">
	فهرس الجدول
</h2>

<p>
	لو افترضنا وجود 1000 ملف ورقيّ غير مميزة عن بعضها وتحتوي على بيانات خاصة بطلاب جامعة، وهذه الملفات محفوظة في خزانتين منفصلتين، وأردنا الحصول على بيانات الطلاب الذين يسكنون منطقة معينة، ففي هذه الحالة سنضطر إلى فتح كل الملفات الموجودة في الخزانتيْن والبحث عن فئة الطلاب المستهدفة، وفرزهم والحصول على البيانات المطلوبة.
</p>

<p>
	ماذا لو كان لدينا عدد ملفات أكبر؟ سيزداد الوقت والجهد للحصول على البيانات، لذلك، فإن فكرة فهرسة الملفات في هذه الحالة ستكون أمرا جيدا بالتأكيد. سنُفهرِس مثلا الملفات حسب المكان ثم نحفظها في الخزانتين، بحيث تحتوي كل خزانة على بيانات الطلاب لمنطقة أو مناطق معينة. ثم داخل كل خزانة، نستطيع فرز الملفات وحفظها حسب الاسم مثلا. بتطبيق مفهوم الفهرسة، سنوفر على أنفسنا عناء البحث في الخزانتين، وسنقلل الوقت والجهد اللازمين لذلك.
</p>

<p>
	الفكرة الرئيسة للفهارس في قاعدة البيانات تدور حول المثال السابق، ففي ظل عصر تضخم البيانات، فإنه أصبح من الملح والضّروريّ وجود تقنيات لتسهيل الوصول السريع للمعلومة.
</p>

<h3 id="ما-هو-الفهرس">
	ما هو الفهرس؟
</h3>

<p>
	لو أردنا مثلا أن نبحث عن اسم شخص في جدول الأشخاص <code>Persons</code> عبر استخدام الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><span class="pln">SELECT </span><span class="pun">*</span><span class="pln">
FROM </span><span class="typ">Persons</span><span class="pln">
WHERE </span><span class="typ">First_Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Ibrahim"</span><span class="pun">;</span></pre>

<p>
	فإن نظام إدارة قاعدة البيانات سيمرّ على كل السجلات الموجودة في الجدول لترشيح السجلات وإرجاع تلك التي توافق الشرط في جملة <code>where</code>.
</p>

<p>
	ستظهر لنا مشكلة الوقت اللازم لتنفيذ جملة الاستعلام – وتزداد -كلما زاد عدد السجلات في الجدول، فلو كان لدينا مثلا مليون سجل في الجدول <code>Persons</code>، ولنفترض جدلاً أن النظام باستطاعته المرور على 10 آلاف سجل في الثانية، فإننا بحاجة إلى 100 ثانية لتنفيذ جملة الاستعلام السابقة.
</p>

<p>
	لحل المشكلة السابقة، فإن نُظم إدارة <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قواعد البيانات</a> تقدم خاصية الفَهْرَسة.
</p>

<p>
	الفَهْرَسة هي ببساطة عبارة عن مؤشر يحتوي على نسخة من جزء من البيانات في الجدول، بحيث تقوم هذه النسخة من البيانات بمهمة “الدليل” أو “المُؤَشّر” الذي يسرع الوصول إلى البيانات الأصلية الكاملة الموجودة في الجدول، بحيث لا تحتاج المرور الكامل على كل الجدول (No Full Table Scan) عند البحث عن البيانات.
</p>

<p>
	يعدّ الفهرس عمليا طريقةً من طُرُق تراكيب البيانات، وهو عنصر مرتبط بوجود جدول في قاعدة البيانات، ولكن نستطيع تعريفه وحذفه منفصلا عن تعريف الجدول، ولا يكون له أي تأثير على نفس البيانات، فعند حذف الفهرس، فإن البيانات الموجودة في الجدول لا تتأثر.
</p>

<p>
	يكون الفهرس في أغلب أنظمة إدارة قواعد البيانات من نوع “B-Tree” ويأتي هذا الاسم من بنية البيانات Data structure التي تحمل نفس الاسم، وهو المفضل لأن تُطبقه على العمود الذي يحتوي قيمًا متنوعة وكثيرة مثل الرقم القومي للشخص، وليس من المفضل أن تطبق فهرس “B-Tree” على العمود الذي يحتوي عددًا قليلًا من القيم.
</p>

<p>
	توجد أنواع أخرى من الفهارس تُقدمها أنظمة إدارة قواعد البيانات مثل “Bitmap Index” و “Denes Index” ولكننا لن نتكلم عنها هنا لأنها خارج إطار موضوع المقال ولأنها تحتاج إلى مقالة منفصلة لشرحها.
</p>

<h3 id="كيف-تعرف-الفهارس">
	كيف تُعرَّف الفهارس؟
</h3>

<p>
	يُعرَّف الفهرس بطريقتيْن:
</p>

<ul>
	<li>
		تعريفه ضمنيًّا: تُبنَى الفهارس ضمنيا على الأعمدة التي يُطَبَّق عليها القيد الفريد وقيد المفتاح الرئيسي، فعند تعريف أحد القيود السابقة، يُبنى فهرس تلقائيًّا على العمود أو الأعمدة المُقيَّدة.
	</li>
	<li>
		تعريفه صراحةً: يُبنَى الفهرس بطريقة مباشرة على العمود أو الأعمدة الذي نرغب وذلك باستخدام جملة <code>Create Index</code>.
	</li>
</ul>

<p>
	على الرغم من أنه لا يوجد تعريف للفهرس في معايير SQL، إلا أن أغلب أنظمة إدارة قواعد البيانات تقدم الإمكانية لتعريف الفهرس ويتفق أغلبها على الصيغة العامة لذلك.
</p>

<p>
	الصيغة العامة لتعريف الفهرس:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs r"><span class="pln">CREATE INDEX index_name
ON table_name </span><span class="pun">(</span><span class="pln">column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pun">);</span></code></pre>

<p>
	عند تعريف الفهرس، لابد أن يكون اسمه متوافقا مع القيود الخاصة بنظام إدارة قاعدة البيانات المستخدم، كما أنه يجب ألا يكون مُكررا، فأسماء الفهارس في قواعد البيانات يجب أن تكون فريدة ولا تتكرر.
</p>

<p>
	لإضافة فهرس باسم <code>First_Name_idx</code> على عمود <code>First_Name</code> في الجدول <code>Persons</code> ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> INDEX </span><span class="typ">First_Name_idx</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ON</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="typ">First_Name</span><span class="pun">);</span></span></code></pre>

<p>
	نستطيع تعريف فهرس فريد UNIQUE Index على عمود ممّا يجعل نظام قواعد البيانات يفحص التكرار داخل هذا النوع من الفهارس، حيث يتأكد النظام - في حالة إضافة أو تعديل قيمة لعمود عليه فهرس فريد - من أن هذه القيمة فريدة وغير مكررة؛ وفي حال كانت مكررة، يُرفَض هذا التغيير ويُظهَر خطأ في العملية.
</p>

<p>
	مثلا، لو أردنا أن نضيف فهرسًا فريدًا على عمود <code>Age</code> في الجدول <code>Persons</code> ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">UNIQUE</span></span><span class="pln"> INDEX </span><span class="typ">Age_idx</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ON</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Age</span><span class="pun">);</span></span></code></pre>

<p>
	نستطيع أيضا تعريف الفهرس على أكثر من عمود، كما في المثال التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">UNIQUE</span></span><span class="pln"> INDEX </span><span class="typ">Multiple_Columns_idx</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ON</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="typ">First_Name</span><span class="pln"> </span><span class="pun">,</span><span class="typ">Age</span><span class="pun">);</span></span></code></pre>

<p>
	عرّفنا في المثال السابق فهرسًا على عمودين، وفي هذه الحالة، فإن الفهرس سيفيد في تنفيذ جملة الترتيب <code>Order by</code> التي تحتوي العمود <code>First_Name</code> ثم عمود <code>Age</code> بنفس الترتيب.
</p>

<p>
	لن نستفيد من الفهرس السابق في حالة تنفيذ جملة الترتيب بترتيب مختلف للعمودين، ولن نستفيد أيضا منه في حالة تنفيذ جملة الاستعلام المشروطة بالبحث في هذين العمودين، حيث نحتاج لتعريف فهارس أخرى لكل عمود على حدة لتسريع عملية الاستعلام مع جملة <code>Where</code>.
</p>

<h3 id="حذف-الفهارس">
	حذف الفهارس
</h3>

<p>
	الصيغة العامة لحذف الفهرس كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DROP</span></span><span class="pln"> INDEX </span><span class="typ">Index_Name</span><span class="pln"> </span><span class="pun">;</span></span></code></pre>

<p>
	فلحذف فهرس باسم Age_idx ننفذ الأمر التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_7811_8" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DROP</span></span><span class="pln"> INDEX </span><span class="typ">Age_idx</span><span class="pln"> </span><span class="pun">;</span></span></code></pre>

<h3 id="متى-نستخدم-الفهارس">
	متى نستخدم الفهارس؟
</h3>

<p>
	يفضل أن يتم بناء الفهارس على الأعمدة التي:
</p>

<ul>
	<li>
		يُبحث عنها في جملة <code>Where</code>.
	</li>
	<li>
		تُكتَب في جملة الترتيب <code>Order By</code>.
	</li>
	<li>
		تُكتَب في جملة التجميع <code>Group By</code>.
	</li>
	<li>
		تُستخدَم في جمل الربط <code>Joins</code>.
	</li>
	<li>
		تُستخدَم في الدوال الإحصائية مثل <code>min</code> و<code>max</code> و<code>median</code>.
	</li>
</ul>

<h3 id="متى-نتجنب-استخدام-الفهارس">
	متى نتجنب استخدام الفهارس؟
</h3>

<p>
	لا تعدّ الفهارس مناسبة على الأعمدة التي:<br>
	- تحتوي على قيم فريدة قليلة مثل عمود الجنس (قيمتان فقط)، أو الحالة الاجتماعية.<br>
	- نادرة الاستخدام في جمل الاستعلام <code>SELECT</code>.<br>
	- التي تكون جزءًا من جدول ذي سجلات قليلة.
</p>

<h2 id="ملاحظات-هامة">
	ملاحظات هامة:
</h2>

<ul>
	<li>
		لأن الفهرس عنصر مستقل في قواعد البيانات، وبناؤه وتعريفه يعدّ إضافة عليها، فلابد أن يدير مسؤول قاعدة البيانات الصلاحيات اللازمة لهذا الأمر بحيث لا يؤثر سلبا على أداء قاعدة البيانات.
	</li>
	<li>
		لا يعدّ الفهرس أساسيا في بناء الجدول في قاعدة البيانات، وعليه قد لا يحتوي الجدول على فهرس، وقد يحتوي على فهرس أو أكثر.
	</li>
	<li>
		نستطيع أن نُعرّف الفهرس عند بناء الجدول (في نفس جملة بناء الجدول)، ولكن من ناحية عملية، فإن إدارة الفهارس والتعامل معها تعدّ عملية مستمرة ومتكررة. تُبنَى الفهارس وتُحذَف حسب الحاجة للوصول إلى الكفاءة المطلوبة في قاعدة البيانات، لذلك تُقدم نُظم قواعد البيانات الأدوات اللازمة لقياس كفاءة جمل الاستعلام وقياس الحاجة لبناء الفهارس من عدمه.
	</li>
	<li>
		لا تُعَرِّف فهارس أكثر من حاجتك وخاصة في الجداول التي تحتوي سجلات كثيرة، فكما أن الفهارس تُسرع من عملية الوصول للبيانات، فإنها تؤثر سلبا على عمليات الإضافة والتعديل، فعند كل إضافة أو تعديل لابد من تعديل الفهرس ليتلاءم مع التغييرات الجديدة.
	</li>
	<li>
		عند تعريف الفهرس، فإن نظام قاعدة البيانات هو الذي يحافظ على الفهرس ويستخدمه تلقائيا، وعليه لا يُطلب من مسؤول قاعدة البيانات أو المبرمج أو حتى المستخدم أي إجراء آخر بعد تعريف وبناء الفهرس.
	</li>
	<li>
		يُسمى الفهرس الذي يُعرَّف على عمود واحد “فهرسا بسيطا”، والفهرس الذي يُعرَّف على أكثر من عمود يسمى “فهرسا مركبا”.<br>
		 
	</li>
</ul>
]]></description><guid isPermaLink="false">589</guid><pubDate>Tue, 25 Jul 2017 08:11:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x627;&#x633;&#x62A;&#x639;&#x644;&#x627;&#x645; &#x639;&#x646; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85-%D8%B9%D9%86-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-r588/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a416d147a060_main(10).png.4260f7b02f0c4027714bf3777be59fed.png" /></p>
<p>
	تعرّفنا في الدروس السابقة على إنشاء الجدول في قاعدة البيانات وإضافة البيانات إليه والتعامل معها من حيث التعديل والإضافة. سوف نبدأ في هذا المقال بالتعرف على أشهر جمل لغة الاستعلام البنائية، وهي جملة الاستعلام Select Statement، حيث سنتكلم عن كيفية كتابة جملة الاستعلام، وأشكالها، وكيفية ترشيح البيانات وتحديد الأعمدة التي نريدها وغيرها من المواضيع.
</p>

<h2 id="جملة-الاستعلام">
	جملة الاستعلام
</h2>

<p>
	تجلب جملة الاستعلام <code>SELECT</code> بيانات جدول أو أكثر بعد الاستعلام عن وجود هذه الجداول في قاعدة البيانات، ونقصد بالاستعلام هنا ماذا نريد؟ ومن أين؟
</p>

<p>
	ماذا نريد من أعمدة وسجلات، ومن أين، أي من أي الجداول نأتي بالمعلومات. البيانات الناتجة عن تنفيذ جملة الاستعلام تسمى مجموعة البيانات الناتجة Result Data-Set.
</p>

<h3 id="الصيغة-العامة-لجملة-الاستعلام">
	الصيغة العامة لجملة الاستعلام
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><span class="pln">SELECT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="pun">...</span><span class="pln">
FROM table_name
</span><span class="pun">[</span><span class="pln">WHERE where_condition</span><span class="pun">]</span><span class="pln">
</span><span class="pun">[</span><span class="pln">GROUP BY group_by_expression</span><span class="pun">]</span><span class="pln">
</span><span class="pun">[</span><span class="pln">ORODER BY order_by_expression</span><span class="pun">];</span></pre>

<p>
	في بداية كل جملة استعلام نكتب كلمة <code>SELECT</code> (جمل SQL غير حساسة لحالة الأحرف) ومن ثم نُتبعها بأسماء الأعمدة التي نريد الاستعلام عنها، أو نستبدل أسماء الأعمدة برمز <code>*</code> والذي يعني كل الأعمدة، ثم نكتب كلمة <code>From</code> والتي يليها اسم الجدول أو أسماء الجداول التي تحتوي على البيانات التي نريدها.
</p>

<p>
	ما بين الأقواس المعكوفة هي جمل إضافية تقوم بمهام معينة في جملة الاستعلام وهي كالتالي:
</p>

<ul>
	<li>
		<code>Where</code>: هي جملة الشرط والتي ترشّح البيانات بناءً على الشرط الموجود بعدها.
	</li>
	<li>
		<code>Group By</code>: تجمّع البيانات الناتجة من تنفيذ جملة الاستعلام بناءً على جملة التجميع التي تليها.
	</li>
	<li>
		<code>Order By</code>: ترتّب البيانات تصاعديا أو تنازليا بناءً على جملة الترتيب التي تليها.
	</li>
</ul>

<p>
	سنتطرق لتفاصيل الجمل الإضافية في هذا المقال وفي مقالات قادمة.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h3 id="مثال-على-جملة-الاستعلام">
	مثال على جملة الاستعلام
</h3>

<p>
	لو أردنا الاستعلام عن كافة البيانات الموجودة في جدول <code>Persons</code> والذي تكلمنا عنه في المقال السابق، ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	كما ذكرتُ سابقا، فإن <code>*</code> تعني عرض جميع البيانات، حيث ستُظهر كافة الأعمدة الموجودة في الجدول والسجلات التي يحتويها. وسيكون ناتج الجملة البيانات التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					105
				</td>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	لو أردنا أن نستعلم عن اسم الشخص الأول وعمره، نقوم بتنفيذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="typ">First_Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Age</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	لاحظ أننا فصلنا بين الأعمدة التي نريد إظهاراها بفاصلة عادية <code>,</code>، والعمود الأخير لا نكتب بعده فاصلة، بل كلمة From مباشر.<br>
	وسيكون ناتج الجملة البيانات التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<h3 id="الاستعلام-عن-السجلات-الفريدة">
	الاستعلام عن السجلات الفريدة
</h3>

<p>
	في بيانات الجدول، ستجد في كثير من الأحيان أن هناك تكراراً للقيم في عمود ما، وقد تحتاج إلى الاستعلام عن القيم دون تكرار، فمثلا، في جدول الأشخاص <code>Persons</code> السابق، ستلاحظ أن عمود العمر <code>Age</code> يحتوي على 5 قيم، ولكن توجد 4 سجلات من نفس القيمة وهي 25، وهنا يأتي دور جملة الاستعلام الفريد <code>DISTINCT Select</code>.
</p>

<p>
	تُرجع جملة الاستعلام عن السجلّات الفريدة سجلات دون تكرار في القيم وصيغتها العامة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs r"><span class="pln">SELECT DISTINCT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
FROM table_name</span><span class="pun">;</span></code></pre>

<p>
	لو نفذنا الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln">  </span><span class="typ">Age</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	سيكون الناتج:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	ولكن لو استخدمنا جملة الاستعلام عن السجلّات الفريدة
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">DISTINCT</span></span><span class="pln">  </span><span class="typ">Age</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	ستكون النتيجة كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<h2 id="ترشيح-السجلات">
	ترشيح السجلات
</h2>

<p>
	لإجراء عملية ترشيح السجلات، سنضيف إلى جملة الاستعلام جملة شرطية تبدأ بالكلمة <code>Where</code> ويتبعها الشرط (أو مجموعة الشروط) الذي نريد والذي سيُرشِّح السجلات بحيث تبقى السجلات التي تحقق الشرط في مجموعة البيانات الراجعة، وتُستبعد السجلات التي لا تحقق الشرط.
</p>

<p>
	الصيغة العامة لجملة الاستعلام والتي تحتوي على شرط لترشيح السجلات:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs r"><span class="pln">SELECT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
FROM table_name
WHERE condition</span><span class="pun">;</span></code></pre>

<h3 id="أمثلة-على-ترشيح-البيانات-في-جدول-persons">
	أمثلة على ترشيح البيانات في جدول Persons
</h3>

<ol>
	<li>
		الحصول على البيانات الكاملة للشخص الذي له <code>Person_ID</code> يساوي <code>101</code>:
	</li>
</ol>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Person_ID</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">101</span></span><span class="pun">;</span></span></code></pre>

<ol>
	<li>
		الاستعلام عن أسماء الأشخاص الذين تساوي أعمارهم 25 سنة أو تزيد عليها:
	</li>
</ol>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="typ">First_Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Last_Name</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="pun">&gt;=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">25</span></span><span class="pun">;</span></span></code></pre>

<ol>
	<li>
		الاستعلام عن الاسم الأول والعمر للأشخاص الذين ليس لديهم قيمة للعمود <code>Last_Name</code> وأعمارهم فوق <code>22</code>:
	</li>
</ol>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="typ">First_Name</span><span class="pun">,</span><span class="pln"> </span><span class="typ">Age</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="hljs-number"><span class="lit">22</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">AND</span></span><span class="pln"> </span><span class="typ">Last_Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">IS</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="typ">Null</span></span><span class="pun">;</span></span></code></pre>

<h3 id="عمليات-المقارنة-في-جملة-where">
	عمليات المقارنة في جملة Where
</h3>

<p>
	يلخص الجدول التالي العمليات التي من الممكن استخدامها في بناء شرط جملة <code>Where</code>:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					العمليّة
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					الوصف
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					مثال
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					=
				</td>
				<td style=" padding: 5px 10px;">
					يساوي
				</td>
				<td style=" padding: 5px 10px;">
					Age = 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					&lt;&gt;
				</td>
				<td style=" padding: 5px 10px;">
					لا يساوي (في بعض النظم تكتب != )
				</td>
				<td style=" padding: 5px 10px;">
					Age &lt;&gt; 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					&gt;
				</td>
				<td style=" padding: 5px 10px;">
					أكبر من
				</td>
				<td style=" padding: 5px 10px;">
					Age &gt; 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					&lt;
				</td>
				<td style=" padding: 5px 10px;">
					أصغر من
				</td>
				<td style=" padding: 5px 10px;">
					Age &lt; 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					&gt;=
				</td>
				<td style=" padding: 5px 10px;">
					أكبر من أو يساوي
				</td>
				<td style=" padding: 5px 10px;">
					Age &gt;= 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					&lt;=
				</td>
				<td style=" padding: 5px 10px;">
					أصغر من أو يساوي
				</td>
				<td style=" padding: 5px 10px;">
					Age &lt;= 20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					BETWEEN … AND
				</td>
				<td style=" padding: 5px 10px;">
					بين قيمتين أو يساويهما
				</td>
				<td style=" padding: 5px 10px;">
					Age BETWEEN 20 AND 25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					LIKE
				</td>
				<td style=" padding: 5px 10px;">
					مطابقة <a alt="مطابقة نمط" href="https://academy.hsoub.com/devops/linux/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D9%81%D9%8A-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-%D8%A7%D9%84%D9%86%D9%85%D8%B7%D9%8A%D8%A9-regular-expressions-r63/" rel=""> نمط</a>
				</td>
				<td style=" padding: 5px 10px;">
					First_Name LIKE “%Ibr%”
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					IN
				</td>
				<td style=" padding: 5px 10px;">
					يوجد ضمن قيم معينة
				</td>
				<td style=" padding: 5px 10px;">
					Age in (20,23,25)
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	<strong>ملاحظة هامة:</strong> نستطيع الجمع بين أكثر من شرط في جملة <code>Where</code> وذلك باستخدام العمليات المنطقية <code>NOT</code> (للنفي)، <code>AND</code> (وجوب تحقّق جميع الشروط) أو <code>OR</code> (يكفي تحقّق شرط واحد من الشروط).
</p>

<h2 id="ترتيب-السجلات">
	ترتيب السجلات
</h2>

<p>
	نستطيع الحصول على البيانات الراجعة مرتبة تصاعديا أو تنازليا بعد تنفيذ جملة الاستعلام، وذلك باستخدام جملة <code>Order By</code>.
</p>

<p>
	ترتّب الجملةُ السجلات تصاعديًّا وهو الخيار المبدئي، ولترتيبها تنازليًّا نستخدم الكلمة المحجوزة <code>DESC</code>، كما أنه يمكن الترتيب باستخدام عمود واحد أو أكثر.
</p>

<p>
	الصيغة العامة لجملة الاستعلام مع جملة الترتيب هي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs r"><span class="pln">SELECT column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
FROM table_name
ORDER BY column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln"> ASC</span><span class="pun">|</span><span class="pln">DESC</span><span class="pun">;</span></code></pre>

<p>
	فمثلا لو أردنا أن نستعلم عن كل البيانات من جدول <code>Persons</code> بحيث تكون البيانات مرتبة ترتيبا تصاعديا حسب عمود <code>First_Name</code>، نستخدم الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ORDER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">BY</span></span><span class="pln"> </span><span class="typ">First_Name</span><span class="pun">;</span></span></code></pre>

<p>
	وستكون النتيجة:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td>
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					105
				</td>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	في حال أردنا أن نرتب نفس البيانات بطريقة تنازلية نستخدم الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_8552_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">SELECT</span></span><span class="pln"> </span><span class="pun">*</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ORDER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">BY</span></span><span class="pln"> </span><span class="typ">First_Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">DESC</span></span><span class="pun">;</span></span></code></pre>

<p>
	وتكون نتيجة الاستعلام كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(250, 200, 250); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					105
				</td>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<h2 id="تجميع-البيانات-باستخدام-group-by">
	تجميع البيانات باستخدام Group By:
</h2>

<p>
	تُستخدم جملة تجميع البيانات غالبا مع دوال التجميع Aggregate Functions بهدف تجميع وترتيب البيانات الناتجة عن الاستعلام حسب عمود أو أكثر.
</p>

<p>
	سوف نتكلم عن جملة تجميع البيانات في مقال متقدم لعلاقته بموضوع الدوال الموجودة في SQL. 
</p>
]]></description><guid isPermaLink="false">588</guid><pubDate>Fri, 21 Jul 2017 20:11:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; (&#x627;&#x644;&#x625;&#x62F;&#x62E;&#x627;&#x644;&#x60C; &#x627;&#x644;&#x62D;&#x630;&#x641; &#x648;&#x627;&#x644;&#x62A;&#x639;&#x62F;&#x64A;&#x644;) &#x641;&#x64A; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%D8%8C-%D8%A7%D9%84%D8%AD%D8%B0%D9%81-%D9%88%D8%A7%D9%84%D8%AA%D8%B9%D8%AF%D9%8A%D9%84-%D9%81%D9%8A-sql-r587/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a416c092bd50_main(9).png.3f630543aead1e7dd2c224b754e4a0f1.png" /></p>
<p>
	بعد أن تعلمنا كيفية إنشاء الجدول في قواعد البيانات، وتعرفنا على أنواع البيانات المستخدمة غالبا، وكيفية إضافة القيود على الجدول، سوف نبدأ في هذا المقال التعرف على جمل التعامل مع البيانات Data Manipulation Language، بحيث ستكون لدينا في نهاية المقال المعرفة اللازمة لإضافة سجل بيانات على الجدول، تعديل سجل بيانات، وحذف سجل بيانات وذلك باستخدام جمل SQL اللازمة لذلك:<code>UPDATE</code>،<code>INSERT</code> و<code>DELETE</code>.
</p>

<p>
	تغيّر جمل التعامل مع البيانات على البيانات في الجدول، لذلك فإن مسؤول قواعد البيانات لا بدّ أن يدير الصلاحيّات اللازمة للتغيير على البيانات بطريقة مُثلى.<br>
	لابد التنويه إلى أن جمل التعامل مع البيانات (<code>UPDATE</code>،<code>INSERT</code> و<code>DELETE</code>) لا تُرجع بيانات أو مُخرجات عند تنفيذها، ولكن أغلب أنظمة إدارة قواعد البيانات تطبع لك ملخص السجلات التي تأثرت بتنفيذ الجمل السابقة.
</p>

<h2 id="هيكلية-الجدول">
	هيكلية الجدول
</h2>

<p>
	قبل البدء بشرح جمل التعامل مع البيانات ومعرفة كيفية تنفيذها، لابد أن تكون لدينا المعرفة الكاملة بهيكلية الجدول الذي نريد إضافة سجل إليه أو تعديله أو الحذف منه، والتعرف على هيكلية الجدول يتضمن:
</p>

<ul>
	<li>
		معرفة ترتيب الأعمدة الموجودة في الجدول،
	</li>
	<li>
		معرفة أسماء الأعمدة،
	</li>
	<li>
		معرفة نوع البيانات الخاصة بكل عمود،
	</li>
	<li>
		التعرف على الأعمدة المطبق عليها قيود ومعرفة هذه القيود وطبيعتها،
	</li>
	<li>
		معرفة القيم المبدئية إذا وجدت.
	</li>
</ul>

<p>
	تُقدم أغلب نظم إدارة قواعد البيانات الأمر اللازم لمعرفة هيكلية الجدول، والصيغة العامة لهذا الأمر تكون كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><span class="pln">DESCRIBE table_name</span><span class="pun">;</span></pre>

<p>
	أو تكون بالصيغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs oxygene"><span class="hljs-keyword"><span class="pln">DESC</span></span><span class="pln"> table_name</span><span class="pun">;</span></code></pre>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h2 id="جملة-إضافة-السجلات">
	جُملة إضافة السجلات
</h2>

<p>
	توجد طريقتان لإضافة سجلات البيانات على الجدول في قاعدة البيانات، الأولى تتضمن كتابة أسماء الأعمدة التي نريد إعطاءها قيمًا بالإضافة للقيم نفسها التي نريد حفظها، وتسمى هذه الطريقة <strong>الإضافة بأسماء الأعمدة</strong>، والطريقة الثانية، في حال أردنا أن نضيف بيانات لكل الأعمدة في الجدول بنفس الترتيب الموجود في الجدول، فهنا لا نكتب أسماء الأعمدة، وتسمى هذه الطريقة <strong>الإضافة بمواقع الأعمدة</strong>.
</p>

<p>
	الصيغة العامة للطريقة الأولى:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs r"><span class="pln">INSERT INTO table_name </span><span class="pun">(</span><span class="pln">column1</span><span class="pun">,</span><span class="pln"> column2</span><span class="pun">,</span><span class="pln"> column3</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pun">)</span><span class="pln">
VALUES </span><span class="pun">(</span><span class="pln">value1</span><span class="pun">,</span><span class="pln"> value2</span><span class="pun">,</span><span class="pln"> value3</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pun">);</span></code></pre>

<p>
	الصيغة العامة للطريقة الثانية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs r"><span class="pln">INSERT INTO table_name
VALUES </span><span class="pun">(</span><span class="pln">value1</span><span class="pun">,</span><span class="pln"> value2</span><span class="pun">,</span><span class="pln"> value3</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pun">);</span></code></pre>

<p>
	لنفترض وجود جدول Persons بالهيكلية والبيانات التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					31
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	لإضافة سجل إلى هذا الجدول نستخدم الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">INSERT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">INTO</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">VALUES</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-number"><span class="lit">103</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">'Saleem'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">'Yaser'</span></span><span class="pun">,</span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">);</span></span></code></pre>

<p>
	<strong>ملاحظة:</strong> تُكتَب النصوص في بعض أنظمة قواعد البيانات بين علامتي التنصيص المزدوجة. فمثلا لكتابة اسم <code>Ibrahim</code> في جملة الإضافة نكتبها هكذا <code>"Ibrahim"</code>، بينما توجد أنظمة أخرى تعتمد التعامل مع النصوص بين علامتي تنصيص منفردة، هكذا <code>'Ibrahim'</code>.
</p>

<p>
	في جملة إضافة السجل السابقة لم نذكر اسم أي من الأعمدة، لأننا أدخلنا قيمًا لكل الأعمدة. القيمة الأولى (<code>103</code>) هي للعمود الأول (<code>Person_ID</code>) والثانية (<code>'Saleem'</code>) للعمود الثاني (<code>First_Name</code>) وهكذا. ولكن في بعض الحالات لا نضيف السجل بهذه الطريقة، ففي كثير من الأحيان نحتاج إلى إضافة قيم لأعمدة معينة.
</p>

<h3 id="مثال-على-تحديد-الأعمدة">
	مثال على تحديد الأعمدة
</h3>

<p>
	الأعمدة التي يكون عليها قيد مفتاح رئيسي غالبا لا تُدخَل قيم إليها في جمل الإضافة، ويُستخدم بدلاً لذلك طرق لتوليد قيم لها مثل طريقة جعل العمود (ذي النوع الرقمي) Auto Increment الذي يزيد آخر رقم في العمود بالعدد واحد ثم يستخدمه للعمود الذي يوجد عليه المفتاح الرئيسي. في هذه الحالة تكون جملة الإضافة بالصيغة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">INSERT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">INTO</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">first_name</span><span class="pun">,</span><span class="pln"> last_name</span><span class="pun">,</span><span class="pln"> age</span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">VALUES</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-string"><span class="str">'Aly'</span></span><span class="pun">,</span><span class="typ">Mohammed</span><span class="hljs-string"><span class="str">',25);</span></span></span></code></pre>

<p>
	ويصبح الجدول بعد تنفيذ الجملتيْن السابقتيْن كالتالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					31
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					Mohanmmed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	<strong>نصيحة عملية:</strong> يُفضل أن تعتمد جمل الإضافة باستخدام أسماء الأعمدة وذلك لتجنب ظهور أخطاء عند تغيير هيكلية الجدول.
</p>

<h3 id="القيم-الفارغة">
	القيم الفارغة
</h3>

<p>
	لو افترضنا وجود قيد العمود غير الفارغ على الأعمدة <code>First_Name</code> و<code>Age</code> مع وجود قيد المفتاح الرئيسي على العمود <code>Person_Id</code> وخاصية <code>Auto Increment</code> عليه، فإن أي جملة إضافة لا تشتمل على قيم ل <code>First_Name</code> أو <code>Age</code> سوف تُظهِر خطأ عند تنفيذها، ولكن لأننا لم نضف قيد العمود غير الفارغ على عمود <code>Last_Name</code>، فإننا نستطيع تجاهل هذا العمود عند الإضافة كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">INSERT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">INTO</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">first_name</span><span class="pun">,</span><span class="pln"> age</span><span class="pun">)</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">VALUES</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-string"><span class="str">'Reem'</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">);</span></span></code></pre>

<p>
	تصبح البيانات في الجدول كالتالي عند تنفيذ الجملة السابقة:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					31
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					20
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					Mohanmmed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					105
				</td>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
				<td style=" padding: 5px 10px;">
					20
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	من المهم فهم طبيعة القيم الفارغة <code>Null</code> في جداول قواعد البيانات، حيث إنها تختلف عن قيمة الصفر أو القيم النصية <code>""</code>. القيم الفارغة هي التي تُركت بدون اعتبار عند إضافة السجل أو تعديله، كما أن القيم الفارغة لا تخضع للفحص أو المقارنة باستخدام عمليات مثل <code>=</code> <code>&gt;</code> <code>&lt;</code> <code>&lt;&gt;</code>؛ ونستخدم بدلا منها عمليات <code>IS NULL</code> أو <code>IS NOT NULL</code> (هذه النقطة سوف نشرحها في درس جملة الاستعلام).
</p>

<h2 id="جملة-تعديل-السجل">
	جملة تعديل السجل
</h2>

<p>
	نستخدم جملة تعديل السجل لإجراء عملية تغيير لقيم الأعمدة في سجل معين أو مجموعة سجلات أو على الجدول بأكمله.
</p>

<p>
	الصيغة العامة لجملة تعديل السجل كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs r"><span class="pln">UPDATE table_name
SET column1 </span><span class="pun">=</span><span class="pln"> value1</span><span class="pun">,</span><span class="pln"> column2 </span><span class="pun">=</span><span class="pln"> value2</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="pun">...</span></span><span class="pln">
WHERE condition</span><span class="pun">;</span></code></pre>

<h4 id="ملاحظات-هامة">
	ملاحظات هامة:
</h4>

<ul>
	<li>
		في حالة تعديل أكثر من عمود، يجب وضع فاصلة بين القيم الجديدة للأعمدة.<br>
		تُمثل <code>column1</code>و<code>column2</code> أسماء الأعمدة التي نريد تغيير قيمها، وتمثل <code>value1</code> و <code>value2</code> القيم الجديدة للأعمدة السابقة بالترتيب.
	</li>
	<li>
		نستطيع التعديل على أكثر من عمود في نفس جملة التعديل.
	</li>
	<li>
		لا بد من الحذر والانتباه الشديديْن عند تنفيذ جملة التعديل، حيث إن جملة الشرط (<code>WHERE condition</code>) تحدد السجلات التي سيُعدَّل عليها، وفي حالة عدم وجود جملة الشرط، فإن جميع السجلات في الجدول ستدخل في العملية.
	</li>
</ul>

<h3 id="تعديل-سجل-واحد">
	تعديل سجل واحد
</h3>

<p>
	لتعديل سجل واحد، يجب أن نُحدد الشرط الذي يميز هذا السجل على نحو فريد في جملة الشرط، وغالبا يُستخدَم عمود قيد المفتاح الرئيسي في الجدول. فمثلا، إذا أردنا أن نُعدل قيمة العمر <code>Age</code> من <code>31</code> إلى <code>21</code> للشخص صاحب الرقم <code>101</code> في جدول <code>Persons</code> ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">UPDATE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">SET</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">21</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Person_Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">101</span></span><span class="pun">;</span></span></code></pre>

<p>
	ويصبح السجل بالقيم التالية:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
		</tbody>
	</table>
</center>

<p>
	لاحظ أننا في جملة الشرط استخدمنا عملية المقارنة <code>=</code> لتحديد رقم <code>Person_Id</code>، وهنا يجب أن ننوه أننا نستطيع استخدام جميع عمليات المقارنة في جملة الشرط بشرط أن تكون منطقية ومكتوبة بطريقة صحيحة، فمثلا، لو أردنا أن نُعدل جميع أعمار الأشخاص الذين أعمارهم <code>20</code> أو أقل، لتصبح <code>25</code> ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">UPDATE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">SET</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">25</span></span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">20</span></span><span class="pun">;</span></span></code></pre>

<p>
	السجلات التي لها القيمة <code>103</code> و<code>105</code> في العمود <code>Person_Id</code> هي التي ستتأثر بالجملة السابقة عند تنفيذها، وتصبح البيانات في الجدول على النحو التالي:
</p>

<center>
	<table border="1">
		<tbody>
			<tr>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Person_ID
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					First_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Last_Name
				</td>
				<td style="background-color: rgb(186, 255, 125); padding: 5px 10px; text-align: center;">
					Age
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					101
				</td>
				<td style=" padding: 5px 10px;">
					Ibrahim
				</td>
				<td style=" padding: 5px 10px;">
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					21
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					102
				</td>
				<td>
					Mohammed
				</td>
				<td style=" padding: 5px 10px;">
					Khaled
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					103
				</td>
				<td style=" padding: 5px 10px;">
					Saleem
				</td>
				<td style=" padding: 5px 10px;">
					Yaser
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					104
				</td>
				<td style=" padding: 5px 10px;">
					Aly
				</td>
				<td style=" padding: 5px 10px;">
					Mohanmmed
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
			<tr>
				<td style=" padding: 5px 10px;">
					105
				</td>
				<td style=" padding: 5px 10px;">
					Reem
				</td>
				<td style=" padding: 5px 10px;">
					 
				</td>
				<td style=" padding: 5px 10px;">
					25
				</td>
			</tr>
		</tbody>
	</table>
</center>

<h2 id="جملة-حذف-السجل">
	جملة حذف السجل
</h2>

<p>
	تُستخدَم جملة الحذف لإجراء عملية مسح بيانات موجودة في جدول معين وتتحكّم فيها جملة الشرط والتي تحدد السجل أو السجلات التي ستُحذَف.
</p>

<p>
	الصيغة العامة لجملة الحذف
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DELETE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> table_name
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> condition</span><span class="pun">;</span></span></code></pre>

<p>
	لابد من الانتباه عند تنفيذ جملة الحذف، حيث إنه في حالة عدم تحديد جملة الشرط، فإن كل البيانات في الجدول ستُحذَف.
</p>

<h3 id="حذف-سجل-واحد">
	حذف سجل واحد
</h3>

<p>
	لحذف السجل الخاص بالشخص الذي رقمه 103 ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DELETE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Person_Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">103</span></span><span class="pun">;</span></span></code></pre>

<p>
	لحذف السجل الخاص بالشخص ذي القيمة الفارغة في الحقل <code>Last_Name</code> ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DELETE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">WHERE</span></span><span class="pln"> </span><span class="typ">Last_Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">IS</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">;</span></span></code></pre>

<h3 id="حذف-بيانات-الجدول">
	حذف بيانات الجدول
</h3>

<p>
	لحذف البيانات بالكامل من الجدول <code>Persons</code> ننفذ إحدى الجملتيْن التاليّتيْن:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DELETE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	أو
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_5133_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">DELETE</span></span><span class="pln"> </span><span class="pun">*</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">FROM</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">;</span></span></code></pre>

<p>
	<strong>ملاحظة</strong>: العلامة <code>*</code> تعني جميع السجلات. 
</p>
]]></description><guid isPermaLink="false">587</guid><pubDate>Tue, 18 Jul 2017 20:11:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; SQL: &#x623;&#x646;&#x648;&#x627;&#x639;&#x647;&#x627; &#x648;&#x627;&#x644;&#x642;&#x64A;&#x648;&#x62F; &#x639;&#x644;&#x64A;&#x647;&#x627;</title><link>https://academy.hsoub.com/programming/sql/%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-sql-%D8%A3%D9%86%D9%88%D8%A7%D8%B9%D9%87%D8%A7-%D9%88%D8%A7%D9%84%D9%82%D9%8A%D9%88%D8%AF-%D8%B9%D9%84%D9%8A%D9%87%D8%A7-r586/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a416add1050f_main(8).png.f6bfb4790803ae169ff43eed67960d0c.png" /></p>
<p>
	تعرفنا في<a href="https://academy.hsoub.com/programming/sql/" rel=""> المقالات السابقة</a> على مفهوم <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قواعد البيانات</a>، وعرضنا مقدمة عن لغة الاستعلام البنائية SQL وأنواع الجمل فيها، وتعرفنا أيضا على كيفية بناء الجدول في قاعدة البيانات والتعديل على هيكله.
</p>

<p>
	سنتطرق في هذا المقال إلى مفهوم القيود الموجودة في قواعد البيانات، وسنتكلم عن أنواع البيانات التي يمكن استخدامها.
</p>

<h2 id="أنواع-البيانات-data-types-في-قاعدة-البيانات">
	أنواع البيانات Data Types في قاعدة البيانات
</h2>

<p>
	يُحدّد نوع البيانات طبيعة وشكل القيمة التي من الممكن أن يأخذها العمود في الجدول، ويجب علينا أن نحدد اسم العمود ونوع بياناته عند إنشاء هذا الجدول وذلك في جملة إنشائه.
</p>

<p>
	توجد أنواع بيانات معيارية حدّدتها مؤسسة ANSI، ولكن ليس كل أنظمة إدارة قواعد البيانات توفر هذه المعايير وتطبقها على نحو كامل. يلخص الجدول التالي أهم وأشهر الأنواع المستخدمة
</p>

<p style="text-align: center;">
	<img alt="01_datatypes.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26218" data-unique="j1350rwj9" src="https://academy.hsoub.com/uploads/monthly_2017_12/01_datatypes.png.befefb08952f646a790f99a8fdb9e1d4.png">
</p>

<p>
	هناك أنواع معيارية أخرى مثل <code>XML</code>، <code>ARRAY</code>، <code>MULTISET</code> ولكنها غير متداولة على نطاق واسع، ويجب الانتباه إلى أن نظم إدارة قواعد البيانات تختلف في تسمية وتعريف بعض <a href="https://academy.hsoub.com/programming/general/%D8%AF%D9%84%D9%8A%D9%84%D9%83-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r1726/" rel="">أنواع البيانات</a>، فمثلاً، نوع البيانات الرقم يسمى في قواعد بيانات أوراكل بـ <code>Number</code> ولكن في قواعد البيانات MySQL وPostgreSQL يسمى <code>Int</code> أو <code>Integer</code>.
</p>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h2 id="القيود">
	القيود
</h2>

<p>
	يعدّ موضوع القيود من المواضيع الهامة جدا في قواعد البيانات، ويجب على المبرمج ومسؤول قواعد البيانات الإلمام بأنواع القيود وكيفية تعريفها والتعامل معها.
</p>

<p>
	الهدف العام من القيود هو الحفاظ على سلامة البيانات Data integrity ودقتها. نستطيع أن نُعرّف القيد على أنه شرط يحكم العمود أو الجدول ويُتأكد من الالتزام بهذا الشرطعند إجراء عمليات مثل الإضافة والتعديل والحذف (على سبيل الذكر لا الحصر)، وفي حال لم يُحترَم الشرط فإن العملية مصدر الأمر تُرفَض ويوقَف تنفيذها ويُتراجع عن أي أثر أحدثته.
</p>

<h3 id="مجال-القيود">
	مجال القيود
</h3>

<p>
	تُطبَّق القيود على مستويين:
</p>

<ul>
	<li>
		مستوى العمود: يُعَرَّف القيد ضمن تعريف العمود ويطبق القيد على مستوى هذا العمود فقط.
	</li>
	<li>
		مستوى الجدول: يُعَرَّف القيد منفصلا عن أي عمود (عادة في نهاية تعريف الجدول)، ويمكن أن يطبق القيد على واحد أو أكثر من الأعمدة.
	</li>
</ul>

<h3 id="أنواع-القيود">
	أنواع القيود
</h3>

<ul>
	<li>
		<p>
			<strong>قيد “العمود غير الفارغ” Not Null Constraint:</strong> نستطيع إعطاء قيمة فارغة لعمود ما لم نُعرف هذا القيد عليه، والذي نقصد به منع إدخال أو إعطاء العمود قيمة فارغة <code>Null</code> عند إجراء عمليات مثل الإضافة أو التعديل على السجلات. يعرف المثال التالي جدولًا <code>Persons</code> مع تطبيق قيد العمود غير الفارغ على أول ثلاث أعمدة (طبقنا المثال على MySQL 5.7 وOracle XE):
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><span class="pln">CREATE TABLE </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="kwd">int</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">255</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> varchar</span><span class="pun">(</span><span class="lit">255</span><span class="pun">)</span><span class="pln"> NOT NULL</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="kwd">int</span><span class="pln">
</span><span class="pun">);</span></pre>
	</li>
	<li>
		<p>
			<strong>قيد القيمة الفريدة UNIQUE Constraint:</strong> مهمة هذا القيد هي ضمان عدم تكرار قيمة عمود في أي من سجلات الجدول، بحيث تكون هذه القيمة فريدة ومختلفة. نستطيع تعريف أكثر من قيد فريد في الجدول على أكثر من عمود، كما أن قيد المفتاح الرئيسي (انظر بالأسفل) يقدم ضمان القيمة الفريدة للعمود بجانب القيد الفريد. يُعرَّف القيد الفريد بالطريقة التالية:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">UNIQUE</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

		<p>
			أو
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">UNIQUE</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

		<p>
			وفي حال أردنا أن نعرف القيد على مستوى أكثر من عمود:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">CONSTRAINT</span></span><span class="pln"> UC_Person </span><span class="hljs-keyword"><span class="pln">UNIQUE</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">ID</span><span class="pun">,</span><span class="typ">LastName</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>
	</li>
	<li>
		<p>
			<strong>قيد المفتاح الرئيسي Primary Key Constraint:</strong> يُطبَّق هذا القيد على عمود أو أكثر بحيث تكون قيمة العمود أو قيمة الأعمدة مجتمعة تُعَرِّف كل سجل على نحو فريد عن السجلات الأخرى في الجدول. يُعدّ قيد المفتاح الرئيسي قيدًا فريدًا أضيف إليه قيد غير فارغ.<br>
			خصائص قيد المفتاح الرئيسي:
		</p>

		<ul>
			<li>
				يمكن تعريف قيد مفتاح رئيسي واحد على مستوى الجدول.
			</li>
			<li>
				لا يمكن تعريف قيد المفتاح الرئيسي على أعمدة من نوع <code>BLOB</code>،<code>CLOB</code>،<code>NCLOB</code>،<code>ARRAY</code>.
			</li>
			<li>
				قيم العمود المطبق عليه قيد المفتاح الرئيسي لابد أن تكون فريدة لكل سجل وألا تأخذ قيمة فارغة.
			</li>
			<li>
				تُعَرف قيود المفتاح الأجنبي بأخذها مَرجِعاً من مفتاح قيد رئيسي في جدول آخر، وذلك لبناء علاقة بين جدولين.<br>
				يُعرَّف قيد المفتاح الرئيسي كالتالي:
			</li>
		</ul>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

		<p>
			أو
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

		<p>
			نعرّف في ما يلي قيد مفتاح رئيسي على أكثر من عمود ونعطيه الاسم <code>PK_Person</code>:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    ID </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">CONSTRAINT</span></span><span class="pln"> PK_Person </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">ID</span><span class="pun">,</span><span class="typ">LastName</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>
	</li>
	<li>
		<p>
			<strong>قيد المفتاح الأجنبي Foreign Key Constraint:</strong> يعرّف قيد المفتاح الأجنبي عمودًا - أو أكثر - في الجدول على أنه مرجع من عمود يوجد في جدول آخر، بحيث تكون قيمة العمود مأخوذة من هذا العمود المرجعي بشرط أن يُعرَّف عليه قيد فريد أو قيد مفتاح رئيسي (في الجدول الآخر).<br>
			يعدّ هذا القيد وسيلة لربط جداول قاعدة البيانات وبناء علاقات بينها، ومن الممكن تعريف أكثر من قيد أجنبي في الجدول الواحد. نستطيع أن نعرف القيد الأجنبي في الجدول كالتالي:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Orders</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">OrderID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">OrderNumber</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="typ">OrderID</span><span class="pun">),</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">FOREIGN</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="typ">PersonID</span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">REFERENCES</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

		<p>
			لإعطاء القيد الأجنبي اسما مخصَّصا نستخدم الطريقة التالية:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_3143_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Orders</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">OrderID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">OrderNumber</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="typ">OrderID</span><span class="pun">),</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">CONSTRAINT</span></span><span class="pln"> FK_PersonOrder </span><span class="hljs-keyword"><span class="pln">FOREIGN</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pln"> </span><span class="pun">(</span><span class="typ">PersonID</span><span class="pun">)</span><span class="pln">
    </span><span class="hljs-keyword"><span class="pln">REFERENCES</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pun">(</span><span class="pln">ID</span><span class="pun">)</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>
	</li>
</ul>

<p>
	إن أردت الاستزادة، فارجع إلى توثيق <a href="https://wiki.hsoub.com/SQL/datatype" rel="external">أنواع البيانات في لغة SQL</a> من موسوعة حسوب.
</p>
]]></description><guid isPermaLink="false">586</guid><pubDate>Sun, 16 Jul 2017 08:11:00 +0000</pubDate></item><item><title>&#x623;&#x633;&#x627;&#x633;&#x64A;&#x651;&#x627;&#x62A; &#x644;&#x63A;&#x629; SQL</title><link>https://academy.hsoub.com/programming/sql/%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D9%91%D8%A7%D8%AA-%D9%84%D8%BA%D8%A9-sql-r585/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a4169d7919a7_main(7).png.54d7e491c296bb38efdf2fb1f5ddb41a.png" /></p>
<p>
	تَعرفنا في <a href="https://academy.hsoub.com/programming/sql/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r584/" rel="">المقال السابق</a> على مفهوم قواعد البيانات وما هي أنواعها. سوف نبدأ في هذا المقال أُولى خطواتنا في شرح لغة الاستعلام البنائية SQL، حيث سنتكلم عن لغة SQL ونعطي لمحة عن دورها وعلاقتها بقاعدة البيانات، ومن ثم سوف نبدأ بشرح أساسيات وجمل بناء قاعدة البيانات والجداول الخاصة بها باستخدام لغة SQL.
</p>

<h2 id="لغة-sql-وماذا-تقدم">
	لغة SQL وماذا تقدم
</h2>

<p>
	SQL هي اختصارٌ لـ Structured Query language وترجمتها هي “لغة الاستعلام البنائية” وتنطق بطريقتيْن؛ إما حرفًا حرفًا S Q L، أو تنطق كلمة واحدة “سيكيوال”.<br>
	لغة SQL هي لغة ذات غرض متخصص هدفها إعطاء القدرة على إدارة البيانات الموجودة في <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قواعد البيانات</a> العلاقية والتعامل معها، وتخضع هذه اللغة لمعايير دولية متفق عليها، ويقوم المعهد الوطني الأمريكي للمعايير (ANSI) بإدارة وإصدار المعايير الخاصة ب SQL.
</p>

<p>
	لا يعني ما سبق أن كل برمجيات إدارة قواعد البيانات التي ذكرناها في المقال السابق والتي لم نذكرها، لا يعني بأن SQL لديها موحدة، ولا يعني أنك تستطيع تماما أن تُنفذ نفس جملة SQL في جميع تلك البرمجيات بنجاح. فمن المهم أن نذكر هنا أن الشركات المسؤولة عن تلك البرمجيات الخاصة بإدارة قواعد البيانات، اعتمدت نسخًا مطورة من SQL المعيارية لتصبح خاصة بها وبأنظمتها مع اعتماد حد أدنى في التوافقية مع SQL المعيارية.
</p>

<p>
	تستطيع باستخدام لغة SQL أن تقوم بالتالي:
</p>

<ol>
	<li>
		الاستعلام عن البيانات وجلبها من قاعدة البيانات.
	</li>
	<li>
		إضافة، تعديل السجلات في قاعدة البيانات وحذفها منها.
	</li>
	<li>
		الحفاظ على سلامة ودقة البيانات في قاعدة البيانات.
	</li>
	<li>
		تحديد الصلاحيات والأذونات الخاصة بمستخدمي قاعدة البيانات.
	</li>
</ol>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h2 id="أنواع-أوامر-sql">
	أنواع أوامر SQL
</h2>

<p>
	تنقسم جمل وأوامر SQL إلى ثلاث مجموعات، وذلك حسب الدور الذي يقوم به الأمر:
</p>

<ul>
	<li>
		<strong>لغة التعامل مع البيانات Data Manipulation Language</strong>: تحتوي هذه المجموعة على جمل غرضها إعطاء القدرة على التعامل مع البيانات دون التأثير على هيكليتها وشكلها العام، بحيث تستطيع الاستعلام عن البيانات، إضافة سجلّات، حذفها أو تعديلها.
	</li>
	<li>
		<strong>لغة تعريف البيانات Data Definition Language</strong>: تُقدم الأوامر التي تندرج تحت هذه المجموعة القدرة على تعريف البيانات وشكلها وطريقة ربطها ببعضها عبر استخدام أوامر لإنشاء الجداول وإنشاء قاعدة البيانات.
	</li>
	<li>
		<strong>لغة التحكم بالبيانات Data Control Language</strong>: تساعد هذه المجموعة من الأوامر في تحديد الصلاحيات التي يمكن منحها أو سلبها من المستخدمين الموجودين في قاعدة البيانات.
	</li>
</ul>

<p>
	يسرد الجدول التالي أهم الأوامر التي تُمَكّن المبرمج من إنشاء قاعدة البيانات الخاصة به وتنفيذ الجمل الخاصة بإدارتها وإدارة بياناتها.
</p>

<p style="text-align: center;">
	<img alt="01_sql_commands.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26217" data-unique="jsp1oquhm" src="https://academy.hsoub.com/uploads/monthly_2017_12/01_sql_commands.png.8f599673fc889143d85a2e7423a03bf1.png">
</p>

<h3 id="جملة-إنشاء-قاعدة-البيانات">
	جملة إنشاء قاعدة البيانات
</h3>

<p>
	في الواقع لا يوجد معيار لأمر إنشاء قاعدة البيانات في معيار SQL المقدم من معهد ANSI ولكن برمجيات قواعد البيانات العلاقية تقدم نسخة من هذا الأمر، وتختلف الصيغة من نظام إلى آخر.<br>
	الصيغة العامة لأمر إنشاء قاعدة البيانات هي كالتالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><span class="pln">CREATE DATABASE database_name</span><span class="pun">;</span></pre>

<p>
	<strong>ملاحظات هامة</strong>
</p>

<ul>
	<li>
		يُنشئ الأمر السابق قاعدة بيانات فارغة بالاسم المُمَرَّر (أي <code>database_name</code> في الجملة أعلاه).
	</li>
	<li>
		تتطلب أغلب نظم إدارة قواعد البيانات وجود صلاحيات المسؤول للمستخدم الذي ينشئ قاعدة البيانات.
	</li>
	<li>
		بمجرد إنشاء قاعدة البيانات، يستطيع المستخدم أو من له صلاحية، البدء بإضافة عناصر إلى قاعدة البيانات من جداول Tables، مشاهد Views، دوال وحزم، وإضافة سجلات وبيانات إلى الجداول المُنشأة.
	</li>
	<li>
		أثناء تنفيذ أمر إنشاء قاعدة البيانات وبعده، تُنشَأ ملفات خاصة بقاعدة البيانات الجديدة حسب النظام المستخدم، وتُدار هذه الملفات وتُسمَّى إما تلقائيًّا أو من قبل المستخدم.
	</li>
	<li>
		لأن أمر إنشاء قاعدة البيانات غير معياري، فإن خيارات هذا الأمر متعددة وكثيرة وتأتي حسب نوع النظام المستخدم، وحسب نوع نظام إدارة قواعد البيانات.
	</li>
	<li>
		يظهر أمر الإنشاء بأحرف كبيرة Upper case. ليس هذا ضروريّاً في أغلب برامج إدارة قواعد البيانات، إلا أنها عادة في التوثيقات Documentations لتمييز الكلمات المفتاحية التي تعدّ جزءًا من SQL.
	</li>
</ul>

<h3 id="جملة-إنشاء-جدول">
	جملة إنشاء جدول
</h3>

<p>
	يُعد إنشاء الجدول في قاعدة البيانات أول الخطوات في طريق بناء قاعدة البيانات وملئها بالسجلات، وهذا الأمر يقوم به مسؤول قواعد البيانات أو المبرمج على حد سواء.
</p>

<p>
	ستحتاج قبل أن تتمكّن من البدء في تنفيذ أوامر على القاعدة إلى تحديد قاعدة البيانات التي تريد العمل عليها، أي تلك التي ستُنشِئ الجداول فيها. تختلف طريقة تحديد قاعدة البيانات حسب طريقة الاتصال ببرنامج إدارة قواعد البيانات:
</p>

<ul>
	<li>
		<p>
			في سطر أوامر MySQL يُنفَّذ الأمر بالطريقة التالية:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs php"><span class="hljs-keyword"><span class="pln">USE</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">database_name</span></span><span class="pun">;</span></code></pre>
	</li>
	<li>
		<p>
			في سطر أوامر PostgreSQL:
		</p>

		<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs tex"><span class="pln">  </span><span class="hljs-command"><span class="pln">\connect</span></span><span class="pln"> DBNAME</span></code></pre>
	</li>
</ul>

<p>
	الصيغة العامة لجملة إنشاء الجدول في SQL:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> table_name </span><span class="pun">(</span><span class="pln">
    column1 datatype </span><span class="pun">[</span><span class="hljs-keyword"><span class="pln">constraint</span></span><span class="pun">],</span><span class="pln">
    column2 datatype </span><span class="pun">[</span><span class="hljs-keyword"><span class="pln">constraint</span></span><span class="pun">],</span><span class="pln">
    column3 datatype </span><span class="pun">[</span><span class="hljs-keyword"><span class="pln">constraint</span></span><span class="pun">],</span><span class="pln">
   </span><span class="pun">....</span><span class="pln">
</span><span class="pun">);</span></span></code></pre>

<p>
	شرح الصيغة:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> table_name </span><span class="pun">(</span></span></code></pre>

<ul>
	<li>
		<code>CREATE</code> تعني إنشاء العنصر (الجدول هنا) وهي بداية الأمر.
	</li>
	<li>
		<code>TABLE</code> لتحديد أن هذه الجملة لإنشاء جدول.
	</li>
	<li>
		<code>table_name</code> وهو الاسم الذي نريد إطلاقه على الجدول الجديد الذي نريد بناءه.
	</li>
	<li>
		القوس المفتوح باتجاه اليسار يعني البدء بكتابة هيكل الجدول والذي يتضمن الأعمدة ونوعها والقيود التي من الممكن أن نضيفها وبعض الإعدادات الأخرى.
	</li>
</ul>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs css"><span class="hljs-tag"><span class="pln">column1</span></span><span class="pln"> </span><span class="hljs-tag"><span class="pln">datatype</span></span><span class="pln"> </span><span class="hljs-attr_selector"><span class="pun">[</span><span class="pln">constraint</span><span class="pun">]</span></span><span class="pun">,</span></code></pre>

<ul>
	<li>
		<code>column1</code>: هو الاسم الذي سوف نعطيه للعمود الأول.
	</li>
	<li>
		<code>Datatype</code>:يعني نوع العمود (نصي, رقم, تاريخ. الخ).
	</li>
	<li>
		<code>[Constraint]</code>:تعني – اختيارياً - تستطيع تحديد قيود على مستوى هذا العمود (سنتكلم لاحقا بالتفصيل عن القيود).
	</li>
	<li>
		الفاصلة تعني وجود عمود آخر سوف نعرّفه بعد هذا العمود.
	</li>
	<li>
		عند كتابة العمود الأخير لا نضيف فاصلة، ومن ثم نضيف القوس المعاكس للقوس الذي فُتح عند بداية كتابة الأعمدة، ونختم الأمر بقاصلة منقوطة.
	</li>
</ul>

<p>
	<strong>ملاحظات هامة</strong>
</p>

<ul>
	<li>
		تبدأ أسماء الجداول والأعمدة عموما بحرف وليس برقم (بعض نظم إدارة قواعد البيانات تسمح بذلك)، ومن الممكن أن تُتبع بعد ذلك بالأرقام.
	</li>
	<li>
		يُفضَّل ألا يتجاوز طول اسم الجدول أو العمود30 محرفا Characters، حيث إن بعض النظم تمنع أن تتجاوز ذلك مثل نظام إدارة قواعد البيانات أوراكل.
	</li>
	<li>
		يجب ألا تُستخدَم كلمات محجوزة في تسمية الجدول أو العمود.
	</li>
</ul>

<h3 id="جملة-تعديل-الجدول">
	جملة تعديل الجدول
</h3>

<p>
	بعد أن تكلمنا عن جملة إنشاء الجدول، يجب علينا توضيح جملة تعديل الجدول بعد إنشائه، حيث إن إجراء عمليات التغيير على الجدول يُعد أمراً مهما للمبرمج ومسؤول قواعد البيانات إذ يُنفَّذ باستمرار أثناء وفي بداية بناء النظم البرمجية والبرامج نظرا لتغير المتطلبات وعدم اكتمالها.
</p>

<p>
	تُستخدَم جملة تعديل الجدول <code>Alter Table</code> عموما في الحالات التالية:
</p>

<ul>
	<li>
		إضافة عمود للجدول.
	</li>
	<li>
		حذف عمود من الجدول.
	</li>
	<li>
		تغيير نوع عمود في الجدول.
	</li>
	<li>
		إضافة قيد على العمود.
	</li>
	<li>
		حذف قيد عن العمود.
	</li>
</ul>

<p>
	نسرُد في ما يلي الصيغ العامة لجملة تعديل الجدول.
</p>

<h3 id="إضافة-عمود">
	إضافة عمود
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> table_name </span><span class="hljs-keyword"><span class="pln">ADD</span></span><span class="pln"> column_name datatype</span><span class="pun">;</span></span></code></pre>

<h3 id="حذف-عمود">
	حذف عمود
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> table_name </span><span class="hljs-keyword"><span class="pln">DROP</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">COLUMN</span></span><span class="pln"> column_name</span><span class="pun">;</span></span></code></pre>

<h3 id="تعديل-عمود">
	تعديل عمود
</h3>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> table_name MODIFY </span><span class="pun">|</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">COLUMN</span></span><span class="pln"> column_name datatype</span><span class="pun">;</span></span></code></pre>

<h3 id="إنشاء-جداول-وتعديلها">
	إنشاء جداول وتعديلها
</h3>

<p>
	لإنشاء جدول باسم <code>Persons</code> يحتوي على 5 أعمدة تمثل معلومات أشخاص مثل رقم الشخص واسمه وعنوانه، نُنَفذ الجملة التالية (اختبرناها على MySQL 5.7 و Oracle XE 11.2):
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">Last_Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">First_Name</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Address</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">City</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> 
</span><span class="pun">);</span></span></code></pre>

<p>
	يتكوّن الجدول السابق:
</p>

<ul>
	<li>
		من العمود <code>PersonID</code> الذي هو من النوع <code>int</code>، أي أن قيم هذا العموم يجب أن تكون أرقامًا؛
	</li>
	<li>
		الأعمدة <code>City</code>، <code>Last_Name</code>، <code>First_Name</code> و<code>Address</code>التي هي من النوع <code>varchar</code>، أي سلسلة محارف، بطول <code>255</code> محرفا.
	</li>
</ul>

<p>
	بعد تنفيذ جملة إنشاء الجدول السابقة، ينتج لدينا جدول فارغ بالشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_9" style=""><span class="pun">+--------------+------------------+------------------+-------------+--------+</span><span class="pln">
</span><span class="pun">|</span><span class="pln"> </span><span class="typ">PersonID</span><span class="pln">     </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Last_Name</span><span class="pln">        </span><span class="pun">|</span><span class="pln"> </span><span class="typ">First_Name</span><span class="pln">       </span><span class="pun">|</span><span class="pln"> </span><span class="typ">Address</span><span class="pln">     </span><span class="pun">|</span><span class="pln"> </span><span class="typ">City</span><span class="pln">   </span><span class="pun">|</span><span class="pln"> 
</span><span class="pun">+--------------+------------------+------------------+-------------+--------+</span></pre>

<p>
	نستطيع أن نملأ الجدول بالبيانات باستخدام جملة الإضافة والتي سوف نتكلم عنها في مقال قادم.
</p>

<p>
	لإنشاء نفس الجدول السابق بحيث يتضمن وجود قيود على مستوى الأعمدة، ننفذ الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">CREATE</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln"> </span><span class="pun">(</span><span class="pln">
    </span><span class="typ">PersonID</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">PRIMARY</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">KEY</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">LastName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">),</span><span class="pln">
    </span><span class="typ">Address</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NOT</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">NULL</span></span><span class="pun">,</span><span class="pln">
    </span><span class="typ">City</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">255</span></span><span class="pun">)</span><span class="pln"> 
</span><span class="pun">);</span></span></code></pre>

<p>
	أضفنا في الجملة السابقة، قيودا على مستوى أعمدة الجدول، بحيث يُعرَّف العمود <code>PersonID</code> بأنه المفتاح الرئيسي للجدول، والأعمدة <code>Last_Name</code> و <code>Address</code> بأنها لا تستقبل القيم الفارغة.
</p>

<p>
	في حال أردنا أن نضيف عمودًا جديدًا للجدول باسم <code>Age</code> (العمر) ومن نوع البيانات رقم نستخدم جملة التعديل التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">ADD</span></span><span class="pln"> </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pun">;</span></span></code></pre>

<p>
	تمكن ترجمة الأمر على النحو التالي: “<strong>عدّل الجدول <code>Persons</code> بإضافة عمود اسمه <code>Age</code> ونوعه <code>int</code></strong>“.
</p>

<p>
	في حال أردنا أن نحذف عمود City من الجدول نستخدم الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
</span><span class="hljs-keyword"><span class="pln">DROP</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">COLUMN</span></span><span class="pln"> </span><span class="typ">City</span><span class="pun">;</span></span></code></pre>

<p>
	أي: “<strong>عدّل الجدول <code>Persons</code> بحذف العمود <code>City</code></strong>“.
</p>

<p>
	إذا أردنا تعديل نوع عمود <code>Age</code> إلى نص بدلا من رقم نستخدم الجملة التالية:
</p>

<pre class="ipsCode prettyprint lang-sql prettyprinted" id="ips_uid_2967_7" style=""><code class="hljs sql"><span class="hljs-operator"><span class="hljs-keyword"><span class="pln">ALTER</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">TABLE</span></span><span class="pln"> </span><span class="typ">Persons</span><span class="pln">
MODIFY </span><span class="typ">Age</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">varchar</span></span><span class="pun">(</span><span class="hljs-number"><span class="lit">10</span></span><span class="pun">);</span></span></code></pre>

<p>
	ذكرنا خلال هذا المقال مصطلحي القيود ونوع البيانات في العمود.
</p>

<p>
	ولكن ما هي القيود؟ وماذا نستفيد منها في قواعد البيانات؟ وما هي أنواع البيانات التي من الممكن التعامل معها؟
</p>

<p>
	يقدّم المقال القادم شرحا تفصيليا عن القيود وأنواعها، وكذلك سيشرح المقال الأنواع التي من الممكن أن نتعامل معها.
</p>

<h2>
	اقرأ أيضًا
</h2>

<ul>
	<li>
		<a href="https://academy.hsoub.com/programming/general/%D8%AF%D9%84%D9%8A%D9%84%D9%83-%D8%A7%D9%84%D8%B4%D8%A7%D9%85%D9%84-%D8%A5%D9%84%D9%89-%D8%A3%D9%86%D9%88%D8%A7%D8%B9-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r1726/" rel="">دليلك الشامل إلى أنواع البيانات</a>
	</li>
</ul>
]]></description><guid isPermaLink="false">585</guid><pubDate>Fri, 14 Jul 2017 08:11:00 +0000</pubDate></item><item><title>&#x645;&#x642;&#x62F;&#x645;&#x629; &#x639;&#x646; &#x642;&#x648;&#x627;&#x639;&#x62F; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A;</title><link>https://academy.hsoub.com/programming/sql/%D9%85%D9%82%D8%AF%D9%85%D8%A9-%D8%B9%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-r584/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_12/5a4168a7c749a_main(6).png.e9d39a2148dc75b2524c5b5b57d4c13a.png" /></p>
<p>
	يتناول هذا المقال، الأول من سلسلة دروس عن لغة الاستعلام البنائية Structured Query language التي تعرف بالاختصار المشهور SQL، مفهوم قواعد البيانات، وماذا نقصد بأنظمة إدارة قواعد البيانات، وما هو الجدول، وما هي خصائص قواعد البيانات العلاقية.
</p>

<h2 id="ما-هي-قاعدة-البيانات">
	ما هي قاعدة البيانات؟
</h2>

<p>
	بطريقة بسيطة مجرّدة من مفاهيم التقنية، <a href="https://academy.hsoub.com/devops/servers/databases/%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-database/" rel="">قاعدة البيانات</a> هي مكان لحفظ بيانات معينة على نحو مستمر بهدف الرجوع إليها وقت الحاجة، فدفتر أرقام الهواتف الذي كنا نستعمله في الماضي يُعدّ قاعدة بيانات؛ والكم الهائل من الفواتير المحاسبية الورقية المحفوظة في خزانات الأقسام المالية في الشركات قديماً، أيضاً هو قاعدة بيانات. وقِس على ذلك العديد من الأمثلة الواقعية والملموسة.
</p>

<p>
	نستنبطُ من هذا التعريف البسيط وجود خاصية هامة لقاعدة البيانات، ألا وهي “الاستمرارية” أو “الدوام” في حفظ البيانات.
</p>

<p>
	في الجانب التقني والبرمجي، فإن قاعدة البيانات Database هي عبارة عن مستودع تُحفظ البيانات فيه داخل جهاز الحاسوب أو <a href="https://academy.hsoub.com/devops/servers/" rel="">الخادوم</a>، ويتمتع هذا المستودع بخاصية الاستمرارية في حفظ البيانات. ونعني بخاصية الاستمرارية هنا أنه في حال إطفاء جهاز الحاسوب أو إعادة تشغيله أو انقطاع التواصل معه، فإن قاعدة البيانات وما تحتويه من بيانات تبقى موجودة ومحفوظة دون أي خلل.
</p>

<h2 id="أنظمة-إدارة-قواعد-البيانات-العلاقية">
	أنظمة إدارة قواعد البيانات العلاقية
</h2>

<p>
	تُسمى البرمجيات التي تنشئ وتدير قواعد البيانات بأنظمة إدارة قواعد البيانات (Databases Management Systems) وتكتب بالاختصار DBMS.
</p>

<h2 id="ما-هي-أنواع-أنظمة-إدارة-قواعد-البيانات">
	ما هي أنواع أنظمة إدارة قواعد البيانات؟
</h2>

<p>
	تختلف وتتعدد تسميات أنواع أنظمة إدارة البيانات، وهذا الاختلاف نابع بالدرجة الأولى من تقدم الزمن وما صاحبه من تقدم في العلوم والتقنيات، ومن ثم بالدرجة الثانية، ينبع الاختلاف من التقنيات والخصائص المتعددة لهذه الأنظمة وما تقدمه من خدمات.<br>
	تنقسم أنواع أنظمة قواعد البيانات إلى ثلاثة أنواع رئيسية.
</p>

<ol>
	<li>
		نظام قاعدة البيانات الملف والواحد Flat File Database: يعدّ هذا النوع من الأنظمة قديما ومن النادر أن تجد أحدا يعمل عليه إلى الآن، وهو ببساطة قاعدة بيانات من ملف واحد كبير يحتوي على كل البيانات، وهو يشبه جدول واحد به كل البيانات.
	</li>
	<li>
		نظام إدارة قاعدة البيانات غير العلاقية Non-Relational DBMS :ظهر هذا النوع من أنظمة قواعد البيانات في ظل عصر تضخم البيانات وزيادة حجمها، وخاصة مع انتشار ما يسمى بالمواقع الاجتماعية وتطبيقات الجوال و<a href="https://academy.hsoub.com/programming/html5/" rel="">صفحات الوب</a> الحديثة، فهذا النوع من الأنظمة يسمح بحفظ بيانات غير مرتبة وفق بنية معينة Unstructured Data، وليس من الشرط أن تترابط هذه البيانات Not relational، كما يطلق عليها <a href="https://academy.hsoub.com/devops/servers/databases/%D8%B4%D8%B1%D8%AD-%D8%A7%D9%84%D9%81%D8%B1%D9%88%D9%82%D8%A7%D8%AA-%D8%A8%D9%8A%D9%86-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-sql-%D9%88%D9%86%D8%B8%D9%8A%D8%B1%D8%A7%D8%AA%D9%87%D8%A7-nosql-r71/" rel="">No-SQL Databases</a>.
	</li>
	<li>
		نظام إدارة قاعدة البيانات العلاقية Relational DBMS: وهو النوع الأشهر والأكثر استخداما منذ بداية ظهوره والذي سنعتمده في هذه السلسلة لشرح SQL، حيث تُجمَّع في هذا النوع من الأنظمة البيانات التي لها علاقة ببعضها البعض في مكان واحد يسمى الجدول، مع وجود الإمكانية لربط الجداول مع بعضها البعض بعلاقات ترابط.
	</li>
</ol>

<div class="banner-container ipsBox ipsPadding">
	<div class="inner-banner-container">
		<p class="banner-heading">
			دورة علوم الحاسوب
		</p>

		<p class="banner-subtitle">
			دورة تدريبية متكاملة تضعك على بوابة الاحتراف في تعلم أساسيات البرمجة وعلوم الحاسوب
		</p>

		<div>
			<a class="ipsButton ipsButton_large ipsButton_primary ipsButton_important" href="https://academy.hsoub.com/learn/computer-science/" rel="">اشترك الآن</a>
		</div>
	</div>

	<div class="banner-img">
		<img alt="دورة علوم الحاسوب" src="https://academy.hsoub.com/learn/assets/images/courses/computer-science.png">
	</div>
</div>

<h2 id="ما-هو-الجدول">
	ما هو الجدول؟
</h2>

<p>
	يُعدّ الجدول العنصر الأساسي في قواعد البيانات العلاقية، وعليه تعتمد أغلب مكونات قاعدة البيانات من مشاهد Views ودوال Functions وحِزم Packages وغيرها من العناصر الأخرى. يتكون الجدول من أعمدة Columns وصفوف Rows، حيث تمثل الأعمدة ما يسمى بالخصائص Features، والصفوف عبارة عن القيم التي تأخذها الأعمدة وتسمى بالسجلات Records.
</p>

<p>
	يوضح الشكل التالي مثالا لجدول يحتوي على بيانات تواريخ ميلاد وأسماء طلاب في مدرسة، وفي المثال نوضح مكونات الجدول في قاعدة البيانات.
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileext="png" data-fileid="26216" href="https://academy.hsoub.com/uploads/monthly_2017_12/01_table.png.44c2e4faa06a53e5caa90414f043c0bb.png" rel=""><img alt="01_table.png" class="ipsImage ipsImage_thumbnailed" data-fileid="26216" data-unique="qq86wnuo7" src="https://academy.hsoub.com/uploads/monthly_2017_12/01_table.thumb.png.ed2723ae451d00fe8d41cb0e75f3b57a.png"></a>
</p>

<h2 id="خصائص-قواعد-البيانات-العلاقية-ومميزاتها">
	خصائص قواعد البيانات العلاقية ومميزاتها
</h2>

<p>
	ظلت قواعد البيانات العلاقية مسيطرة منذ بدايات ظهور النموذج الأساسي لها عام 1970 على يد عالم الحاسوب Frank Codd أثناء عمله لصالح شركة IBM، ولم تكن هذه الأفضلية التي يتمتع بها نظام قواعد البيانات العلاقية تأتي من فراغ، بل من الخصائص التي تتمتع بها.
</p>

<h3 id="البساطة">
	البساطة
</h3>

<p>
	تُرتَّب البيانات في أنظمة قواعد البيانات العلاقية وتُحفَظ بطريقة بعيدة عن التعقيد، حيث يعدّ الجدول الذي تُحفظ فيه البيانات مفهوما لأغلب المستخدمين وخاصة الذين مارسوا أعمالا في مجال البيانات المجدولة أو مراجعة السجلات.
</p>

<h3 id="سهولة-الاستعلام-عن-البيانات">
	سهولة الاستعلام عن البيانات
</h3>

<p>
	بعد عمليات الإضافة على قاعدة البيانات، وعند الحاجة للرجوع لها، فإن نظام قواعد البيانات العلائقية يوفر آلية سهلة للاستعلام عن هذه البيانات واستردادها، وذلك عن طريق لغة SQL، بالإضافة إلى وجود الإمكانية للمستخدم أن يستعلم عن البيانات من أكثر من جدول في نفس الوقت باستخدام جمل الربط Joins. كما أن خاصية ترشيح Filtering البيانات وتحديد شروط خاصة لظهور سجلات معينة هو أمر متاح بكل سهولة.
</p>

<h3 id="سلامة-البيانات">
	سلامة البيانات
</h3>

<p>
	تعدّ هذه الخاصية أساسية في أي نظام قواعد بيانات بغض النظر عن نوعه. ونعني بهذه الخاصية أن تتوفر جميع القدرات والإمكانات في نظام قواعد البيانات لضمان دقة وصحة المعلومات الموجودة فيه. ويندرج تحت هذه الخاصية ما يسمى بقيود التكامل Integrity constraints والتي هي عبارة عن مجموعة من القيود التي يجب الالتزام بها عند التعامل مع البيانات في الجدول، وسنتكلم عنها في مقال متقدم.
</p>

<h3 id="المرونة">
	المرونة
</h3>

<p>
	تتمتع قواعد البيانات العلاقية بطبيعتها بالمرونة والقابلية للتطوير، مما يجعلها قابلة للتكيف مع طلبات التغيير والزيادة في كم البيانات. وهذا يعني مثلا أنك تستطيع التغيير على هيكلية جدول معين دون التأثير على البيانات الموجودة فيه أو على قاعدة البيانات ككل، كما أنك – مثلا - لن تحتاج إلى وقف قاعدة البيانات وإعادة تشغيلها مرة أخرى لتنفيذ بعض لتغييرات عليها.
</p>

<h3 id="ما-هي-البرمجيات-التي-تقدم-قواعد-البيانات-العلاقية">
	ما هي البرمجيات التي تقدم قواعد البيانات العلاقية؟
</h3>

<p>
	تَتَعدد الشركات والبرمجيات التي تُقدم أنظمة إدارة قواعد البيانات، وكل منها له سوقه ومجاله الذي يشتهر به. نُقدم لكم في الفقرات القادمة بعضًا من أشهر أنظمة <a href="https://academy.hsoub.com/devops/servers/databases/%D9%85%D9%82%D8%A7%D8%B1%D9%86%D8%A9-%D8%A8%D9%8A%D9%86-%D8%A3%D9%86%D8%B8%D9%85%D8%A9-%D8%A5%D8%AF%D8%A7%D8%B1%D8%A9-%D9%82%D9%88%D8%A7%D8%B9%D8%AF-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D8%A7%D9%84%D8%B9%D9%84%D8%A7%D9%82%D9%8A%D8%A9-sqlite-%D9%85%D8%B9-mysql-%D9%85%D8%B9-postgresql-r72/" rel="">إدارة قواعد البيانات العلاقية</a>.
</p>

<h3 id="قواعد-بيانات-mysql">
	قواعد بيانات MySQL
</h3>

<p>
	أحد أشهر أنظمة قواعد البيانات العلاقية مفتوحة المصدر. تستطيع إنشاء العديد من قواعد البيانات بداخلها، وتستطيع الوصول لها عبر الوِب. تَعمل <a href="https://academy.hsoub.com/devops/servers/databases/mysql/" rel="">MySQL</a> على هيئة خِدمة Service تُتيح لأكثر من مستخدم الوصول إلى أكثر من قاعدة بيانات، وتشتهر بين معشر مبرمجي تطبيقات الوِب لارتباطها الشائع مع لغة البرمجة PHP، ويمكن تنصيبها على أكثر من نظام تشغيل مثل وندوز أو لينكس أو ماك.<br>
	تعدّ MySQL الخيار المفضل للشركات الناشئة أو المتوسطة وذلك لسهولة التعامل معها وانخفاض تكاليف تشغيلها مقارنة بخيارات أخرى.
</p>

<h3 id="قواعد-بيانات-أوراكل-oracle">
	قواعد بيانات أوراكل Oracle
</h3>

<p>
	تعدّ شركة أوراكل عملاق الشركات البرمجية التي تقدم أنظمة إدارة قواعد البيانات العلاقية، وتأتي قاعدة البيانات أوراكل بأكثر من إصدار (حسب البيئة والغرض) تبدأ من الإصدار الشخصي والخفيف، وتنتهي بالإصدار المتقدم Enterprise.<br>
	تتميز قواعد بيانات أوراكل بكم كبير من الإمكانات التي تسهل عليك حل العديد من المشاكل والعقبات في التطبيقات التي تديرها وتنشئها، مع وجود دعم فني قوي عبر مجتمع أوراكل، لذلك فهي تعتبر الخيار الإستراتيجي (البعيد المدى) للعديد من الشركات الكبيرة والجامعات والحكومات.
</p>

<h3 id="قواعد-بيانات-مايكروسوفت-microsoft-sql-server">
	قواعد بيانات مايكروسوفت Microsoft SQL Server
</h3>

<p>
	من قواعد البيانات الشهيرة، والذي تأتي أيضا بأكثر من إصدار، لتلبي احتياجات المستخدمين المختلفة وبيئات عملهم، ولكي تتعامل مع البيانات في هذا النوع تحتاج لاستخدام النسخة الخاصة من SQL والمسماة T-SQL اختصارا ل Transact SQL والتي هي عبارة عن نسخة SQL مضاف عليه ادوال خاصة وتعديلات على طريقة حذف وتعديل السجلات.
</p>

<h3 id="قواعد-بيانات-postgresql">
	قواعد بيانات PostgreSQL
</h3>

<p>
	قواعد بينات <a href="https://academy.hsoub.com/devops/servers/databases/postgresql/" rel="">PostgreSQL</a> من قواعد البيانات العلاقية المفضلة لدى بعض مطوري تطبيقات الوِب و<a href="https://academy.hsoub.com/programming/general/%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%B3%D8%B7%D8%AD-%D8%A7%D9%84%D9%85%D9%83%D8%AA%D8%A8/" rel="">تطبيقات سطح المكتب</a>، وهو نظام إدارة قواعد بيانات مفتوح المصدر. توجد الكثير من الشركات الكبيرة والعاملة في مجال نطاقات إنترنت تعتمد على هذا النوع من قواعد البيانات.
</p>
]]></description><guid isPermaLink="false">584</guid><pubDate>Tue, 11 Jul 2017 08:11:00 +0000</pubDate></item></channel></rss>
