| ÐокÑменÑаÑÐ¸Ñ Ð¿Ð¾ PostgreSQL 9.4.1 | |||
|---|---|---|---|
| ÐÑед. | УÑÐ¾Ð²ÐµÐ½Ñ Ð²ÑÑе | Ðлава 4. СинÑакÑÐ¸Ñ SQL | След. |
4.2. ÐÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð½Ð°ÑениÑ
ÐÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿ÑименÑÑÑÑÑ Ð² ÑамÑÑ ÑазнÑÑ ÐºÐ¾Ð½ÑекÑÑÐ°Ñ , напÑÐ¸Ð¼ÐµÑ Ð² ÑпиÑке ÑезÑлÑÑаÑов ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ SELECT, в знаÑениÑÑ ÐºÐ¾Ð»Ð¾Ð½Ð¾Ðº в INSERT или UPDATE или в ÑÑловиÑÑ Ð¿Ð¾Ð¸Ñка во Ð¼Ð½Ð¾Ð³Ð¸Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ . РезÑлÑÑÐ°Ñ Ñакого вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð½Ð¾Ð³Ð´Ð° назÑваÑÑ ÑкалÑÑом, ÑÑÐ¾Ð±Ñ Ð¾ÑлиÑиÑÑ ÐµÐ³Ð¾ Ð¾Ñ ÑезÑлÑÑаÑа ÑаблиÑного вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (коÑоÑÑй пÑедÑÑавлÑÐµÑ Ñобой ÑаблиÑÑ). Ð Ñами вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑаÑÑо назÑваÑÑ ÑкалÑÑнÑми (или пÑоÑÑо вÑÑажениÑми). СинÑакÑÐ¸Ñ ÑÐ°ÐºÐ¸Ñ Ð²ÑÑажений позволÑÐµÑ Ð²ÑÑиÑлÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð· пÑимиÑивнÑÑ ÑаÑÑей, иÑполÑзÑÑ Ð°ÑиÑмеÑиÑеÑкие, логиÑеÑкие и дÑÑгие опеÑаÑии.
ÐÑÑажениÑми знаÑÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ:
ÐонÑÑанÑа или непоÑÑедÑÑвенное знаÑение
СÑÑлка на колонкÑ
СÑÑлка на позиÑионнÑй паÑамеÑÑ Ð² Ñеле опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ ÑÑнкÑии или подгоÑовленного опеÑаÑоÑа
ÐÑÑажение Ñ Ð¸Ð½Ð´ÐµÐºÑом
ÐÑÑажение вÑбоÑа полÑ
ÐÑименение опеÑаÑоÑа
ÐÑзов ÑÑнкÑии
ÐгÑегаÑное вÑÑажение
ÐÑзов оконной ÑÑнкÑии
ÐÑиведение Ñипов
ÐÑименение пÑавил ÑоÑÑиÑовки
СкалÑÑнÑй подзапÑоÑ
ÐонÑÑÑÑкÑÐ¾Ñ Ð¼Ð°ÑÑива
ÐонÑÑÑÑкÑÐ¾Ñ ÑаблиÑной ÑÑÑоки
ÐÑоме Ñого, вÑÑажением знаÑÐµÐ½Ð¸Ñ ÑвлÑÑÑÑÑ Ñкобки (пÑедназнаÑеннÑе Ð´Ð»Ñ Ð³ÑÑппиÑовки подвÑÑажений и пеÑеопÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¿ÑиоÑиÑеÑа )
Рдополнение к ÑÑÐ¾Ð¼Ñ ÑпиÑÐºÑ ÐµÑÑÑ ÐµÑÑ Ð½ÐµÑколÑко конÑÑÑÑкÑий, коÑоÑÑе можно клаÑÑиÑиÑиÑоваÑÑ ÐºÐ°Ðº вÑÑажениÑ, Ñ Ð¾ÑÑ Ð¾Ð½Ð¸ не ÑооÑвеÑÑÑвÑÑÑ Ð¾Ð±Ñим ÑинÑакÑиÑеÑким пÑавилам. Ðни обÑÑно имеÑÑ Ð²Ð¸Ð´ ÑÑнкÑии или опеÑаÑоÑа и бÑдÑÑ ÑаÑÑмоÑÑÐµÐ½Ñ Ð² ÑооÑвеÑÑÑвÑÑÑем Ñазделе ÐÐ»Ð°Ð²Ñ 9. ÐÑÐ¸Ð¼ÐµÑ Ñакой конÑÑÑÑкÑии — пÑедложение IS NULL.
ÐÑ Ñже обÑÑдили конÑÑанÑÑ Ð² ÐодÑазделе 4.1.2. Ð ÑледÑÑÑÐ¸Ñ ÑÐ°Ð·Ð´ÐµÐ»Ð°Ñ ÑаÑÑмаÑÑиваÑÑÑÑ Ð¾ÑÑалÑнÑе ваÑианÑÑ.
4.2.1. СÑÑлки на колонки
СÑÑÐ»ÐºÑ Ð½Ð° ÐºÐ¾Ð»Ð¾Ð½ÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ запиÑаÑÑ Ð² ÑоÑме:
оÑноÑение.имÑ_колонки
ÐдеÑÑ Ð¾ÑноÑение — Ð¸Ð¼Ñ ÑаблиÑÑ (возможно, полное, Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑÑ ÐµÐ¼Ñ) или ÐµÑ Ð¿Ñевдоним, опÑеделÑннÑй в пÑедложении FROM. ÐÑо Ð¸Ð¼Ñ Ð¸ ÑазделÑÑÑÑÑ ÑоÑÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ опÑÑÑиÑÑ, еÑли Ð¸Ð¼Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸ ÑникалÑно ÑÑеди вÑÐµÑ ÑаблиÑ, задейÑÑвованнÑÑ Ð² ÑекÑÑем запÑоÑе. (См. Ñакже ÐÐ»Ð°Ð²Ñ 7.)
4.2.2. ÐозиÑионнÑе паÑамеÑÑÑ
СÑÑлка на позиÑионнÑй паÑамеÑÑ Ð¿ÑименÑеÑÑÑ Ð´Ð»Ñ Ð¾Ð±ÑаÑÐµÐ½Ð¸Ñ Ðº знаÑениÑ, пеÑÐµÐ´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð² SQL-опеÑаÑÐ¾Ñ Ð¸Ð·Ð²Ð½Ðµ. ÐаÑамеÑÑÑ Ð¸ÑполÑзÑÑÑÑÑ Ð² опÑеделениÑÑ SQL-ÑÑнкÑий и подгоÑовленнÑÑ Ð¾Ð¿ÐµÑаÑоÑов. ÐекоÑоÑÑе клиенÑÑкие библиоÑеки Ñакже поддеÑживаÑÑ Ð¿ÐµÑедаÑÑ Ð·Ð½Ð°Ñений даннÑÑ Ð¾ÑделÑно Ð¾Ñ Ñамой SQL-командÑ, и в ÑÑом ÑлÑÑае паÑамеÑÑÑ Ð¿Ð¾Ð·Ð²Ð¾Ð»ÑÑÑ ÑÑÑлаÑÑÑÑ Ð½Ð° Ñакие знаÑениÑ. СÑÑлка на паÑамеÑÑ Ð·Ð°Ð¿Ð¸ÑÑваеÑÑÑ Ð² ÑледÑÑÑей ÑоÑме:
$ÑиÑло
ÐапÑимеÑ, ÑаÑÑмоÑÑим ÑледÑÑÑее опÑеделение ÑÑнкÑии dept:
CREATE FUNCTION dept(text) RETURNS dept
AS $$ SELECT * FROM dept WHERE name = $1 $$
LANGUAGE SQL;ÐдеÑÑ $1 вÑегда бÑÐ´ÐµÑ ÑÑÑлаÑÑÑÑ Ð½Ð° знаÑение пеÑвого аÑгÑменÑа ÑÑнкÑии.
4.2.3. ÐндекÑÑ ÑлеменÑов
ÐÑли в вÑÑажении Ð²Ñ Ð¸Ð¼ÐµÐµÑе дело Ñ Ð¼Ð°ÑÑивом, Ñо можно извлеÑÑ Ð¾Ð¿ÑеделÑннÑй его ÑлеменÑ, напиÑав:
вÑÑажение[индекÑ]
или неÑколÑко ÑоÑÐµÐ´Ð½Ð¸Ñ ÑлеменÑов ("ÑÑез маÑÑива"):
вÑÑажение[нижний_индекÑ:веÑÑ Ð½Ð¸Ð¹_индекÑ]
(ÐдеÑÑ ÐºÐ²Ð°Ð´ÑаÑнÑе Ñкобки [ ] Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð² Ñвном виде.) ÐаждÑй Ð¸Ð½Ð´ÐµÐºÑ Ñам по Ñебе ÑвлÑеÑÑÑ Ð²ÑÑажением, ÑезÑлÑÑаÑом коÑоÑого должно бÑÑÑ Ñелое ÑиÑло.
РобÑем ÑлÑÑае вÑÑажение маÑÑива должно заклÑÑаÑÑÑÑ Ð² кÑÑглÑе Ñкобки, но Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ опÑÑÑиÑÑ, когда вÑÑажение Ñ Ð¸Ð½Ð´ÐµÐºÑом — ÑÑо пÑоÑÑо ÑÑÑлка на ÐºÐ¾Ð»Ð¾Ð½ÐºÑ Ð¸Ð»Ð¸ позиÑионнÑй паÑамеÑÑ. ÐÑоме Ñого, можно ÑоединиÑÑ Ð½ÐµÑколÑко индекÑов, еÑли иÑÑ Ð¾Ð´Ð½Ñй маÑÑив многомеÑнÑй. ÐапÑимеÑ:
моÑ_ÑаблиÑа.колонка_маÑÑив[4] моÑ_ÑаблиÑа.колонка_маÑÑив_2d[17][34] $1[10:42] (ÑÑнкÑиÑ_маÑÑив(a,b))[42]
РпоÑледней ÑÑÑоке кÑÑглÑе Ñкобки Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñ. ÐодÑобнее маÑÑÐ¸Ð²Ñ ÑаÑÑмаÑÑиваÑÑÑÑ Ð² Разделе 8.15.
4.2.4. ÐÑÐ±Ð¾Ñ Ð¿Ð¾Ð»Ñ
ÐÑли ÑезÑлÑÑÐ°Ñ Ð²ÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ — знаÑение ÑоÑÑавного Ñипа (ÑÑÑока ÑаблиÑÑ), Ñогда опÑеделÑнное поле ÑÑой ÑÑÑоки можно извлеÑÑ, напиÑав:
вÑÑажение.имÑ_полÑ
РобÑем ÑлÑÑае вÑÑажение Ñакого Ñипа должно заклÑÑаÑÑÑÑ Ð² кÑÑглÑе Ñкобки, но Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ опÑÑÑиÑÑ, когда ÑÑо ÑÑÑлка на ÑаблиÑÑ Ð¸Ð»Ð¸ позиÑионнÑй паÑамеÑÑ. ÐапÑимеÑ:
моÑ_ÑаблиÑа.колонка $1.колонка (ÑÑнкÑиÑ_коÑÑеж(a,b)).кол3
(Таким обÑазом, Ð¿Ð¾Ð»Ð½Ð°Ñ ÑÑÑлка на ÐºÐ¾Ð»Ð¾Ð½ÐºÑ — ÑÑо пÑоÑÑо ÑаÑÑнÑй ÑлÑÑай вÑбоÑа полÑ.) ÐажнÑй оÑобÑй ÑлÑÑай здеÑÑ — извлеÑение Ð¿Ð¾Ð»Ñ Ð¸Ð· колонки ÑоÑÑавного Ñипа:
(ÑоÑÑавнаÑ_колонка).поле (моÑ_ÑаблиÑа.ÑоÑÑавнаÑ_колонка).поле
ÐдеÑÑ Ñкобки нÑжнÑ, ÑÑÐ¾Ð±Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ, ÑÑо ÑоÑÑавнаÑ_колонка — ÑÑо Ð¸Ð¼Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸, а не ÑаблиÑÑ, и ÑÑо моÑ_ÑаблиÑа — Ð¸Ð¼Ñ ÑаблиÑÑ, а не ÑÑ ÐµÐ¼Ñ.
Ð ÑпиÑке вÑбоÑки (Ñм. Раздел 7.3) Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе запÑоÑиÑÑ Ð²Ñе Ð¿Ð¾Ð»Ñ ÑоÑÑавного знаÑениÑ, напиÑав .*:
(ÑоÑÑавнаÑ_колонка).*
4.2.5. ÐÑименение опеÑаÑоÑа
СÑÑеÑÑвÑÑÑ ÑÑи возможнÑÑ ÑинÑакÑиÑа пÑÐ¸Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¾Ð¿ÐµÑаÑоÑов:
| вÑÑажение опеÑаÑÐ¾Ñ Ð²ÑÑажение (бинаÑнÑй инÑикÑнÑй опеÑаÑоÑ) |
| опеÑаÑÐ¾Ñ Ð²ÑÑажение (ÑнаÑнÑй пÑеÑикÑнÑй опеÑаÑоÑ) |
| вÑÑажение опеÑаÑÐ¾Ñ (ÑнаÑнÑй поÑÑÑикÑнÑй опеÑаÑоÑ) |
где опеÑаÑÐ¾Ñ ÑооÑвеÑÑÑвÑÐµÑ ÑинÑакÑиÑеÑким пÑавилам, опиÑаннÑм в ÐодÑазделе 4.1.3, либо ÑÑо одно из клÑÑевÑÑ Ñлов AND, OR и NOT, либо полное Ð¸Ð¼Ñ Ð¾Ð¿ÐµÑаÑоÑа в ÑоÑме:
OPERATOR(ÑÑ ÐµÐ¼Ð°.имÑ_опеÑаÑоÑа)
СÑÑеÑÑвование конкÑеÑнÑÑ Ð¾Ð¿ÐµÑаÑоÑов и Ð¸Ñ Ñип (ÑнаÑнÑй или бинаÑнÑй) завиÑÐ¸Ñ Ð¾Ñ Ñого, как и какие опеÑаÑоÑÑ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ñ ÑиÑÑемой и полÑзоваÑелем. ÐÑÑÑоеннÑе опеÑаÑоÑÑ Ð¾Ð¿Ð¸ÑÐ°Ð½Ñ Ð² Ðлаве 9.
4.2.6. ÐÑÐ·Ð¾Ð²Ñ ÑÑнкÑий
ÐÑзов ÑÑнкÑии запиÑÑваеÑÑÑ Ð¿ÑоÑÑо как Ð¸Ð¼Ñ ÑÑнкÑии (возможно, дополненное именем ÑÑ ÐµÐ¼Ñ) и ÑпиÑок аÑгÑменÑов в ÑÐºÐ¾Ð±ÐºÐ°Ñ :
имÑ_ÑÑнкÑии ([вÑÑажение [, вÑÑажение ... ]])ÐапÑимеÑ, Ñак вÑÑиÑлÑеÑÑÑ ÐºÐ²Ð°Ð´ÑаÑнÑй коÑÐµÐ½Ñ Ð¸Ð· 2:
sqrt(2)
СпиÑок вÑÑÑоеннÑÑ ÑÑнкÑий пÑиведÑн в Ðлаве 9. ÐолÑзоваÑÐµÐ»Ñ Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ Ð¸ дÑÑгие ÑÑнкÑии.
ÐÑгÑменÑам могÑÑ Ð±ÑÑÑ Ð¿ÑиÑÐ²Ð¾ÐµÐ½Ñ Ð½ÐµÐ¾Ð±ÑзаÑелÑнÑе имена. ÐодÑобнее об ÑÑом Ñм. Раздел 4.3.
ÐамеÑание: ФÑнкÑиÑ, пÑинимаÑÑÑÑ Ð¾Ð´Ð¸Ð½ аÑгÑÐ¼ÐµÐ½Ñ ÑоÑÑавного Ñипа, можно Ñакже вÑзÑваÑÑ, иÑполÑзÑÑ ÑинÑакÑÐ¸Ñ Ð²ÑбоÑа полÑ, и наобоÑоÑ, вÑÐ±Ð¾Ñ Ð¿Ð¾Ð»Ñ Ð¼Ð¾Ð¶Ð½Ð¾ запиÑаÑÑ Ð² ÑÑнкÑионалÑном ÑÑиле. То еÑÑÑ Ð·Ð°Ð¿Ð¸Ñи col(table) и table.col ÑавноÑилÑÐ½Ñ Ð¸ взаимозаменÑемÑ. ÐÑо поведение не оговоÑено ÑÑандаÑÑом SQL, но Ñеализовано в PostgreSQL, Ñак как ÑÑо позволÑÐµÑ Ð¸ÑполÑзоваÑÑ ÑÑнкÑии Ð´Ð»Ñ ÑмÑлÑÑии "вÑÑиÑлÑемÑÑ Ð¿Ð¾Ð»ÐµÐ¹". ÐодÑобнее ÑÑо опиÑано в ÐодÑазделе 35.4.3.
4.2.7. ÐгÑегаÑнÑе вÑÑажениÑ
ÐгÑегаÑное вÑÑажение пÑедÑÑавлÑÐµÑ Ñобой пÑименение агÑегаÑной ÑÑнкÑии к ÑÑÑокам, вÑбÑаннÑм запÑоÑом. ÐгÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ ÑÐ²Ð¾Ð´Ð¸Ñ Ð¼Ð½Ð¾Ð¶ÐµÑÑво Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð·Ð½Ð°Ñений к Ð¾Ð´Ð½Ð¾Ð¼Ñ Ð²ÑÑ Ð¾Ð´Ð½Ð¾Ð¼Ñ, как напÑимеÑ, ÑÑмма или ÑÑеднее. ÐгÑегаÑное вÑÑажение Ð¼Ð¾Ð¶ÐµÑ Ð·Ð°Ð¿Ð¸ÑÑваÑÑÑÑ ÑледÑÑÑим обÑазом:
агÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ (вÑÑажение [ , ... ] [ пÑедложение_order_by ] ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] агÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ (ALL вÑÑажение [ , ... ] [ пÑедложение_order_by ] ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] агÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ (DISTINCT вÑÑажение [ , ... ] [ пÑедложение_order_by ] ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] агÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ ( * ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] агÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ ( [ вÑÑажение [ , ... ] ] ) WITHIN GROUP ( пÑедложение_order_by ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ]
ÐдеÑÑ Ð°Ð³ÑегаÑнаÑ_ÑÑнкÑÐ¸Ñ — Ð¸Ð¼Ñ Ñанее опÑеделÑнной агÑегаÑной ÑÑнкÑии (возможно, дополненное именем ÑÑ ÐµÐ¼Ñ), вÑÑажение — лÑбое вÑÑажение знаÑениÑ, не ÑодеÑжаÑее в Ñебе агÑегаÑного вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ вÑзова оконной ÑÑнкÑии. ÐеобÑзаÑелÑнÑе пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð¿Ñедложение_order_by и ÑÑловие_ÑилÑÑÑа опиÑÑваÑÑÑÑ Ð½Ð¸Ð¶Ðµ.
РпеÑвой ÑоÑме агÑегаÑного вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð°Ð³ÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки. ÐÑоÑÐ°Ñ ÑоÑма ÑквиваленÑна пеÑвой, Ñак как Ñказание ALL подÑазÑмеваеÑÑÑ Ð¿Ð¾ ÑмолÑаниÑ. Ð ÑÑеÑÑей ÑоÑме агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð´Ð»Ñ Ð²ÑеÑ
ÑазлиÑнÑÑ
знаÑений вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (или набоÑа ÑазлиÑнÑÑ
знаÑений, Ð´Ð»Ñ Ð½ÐµÑколÑкиÑ
вÑÑажений), вÑделеннÑÑ
во вÑ
однÑÑ
даннÑÑ
. Ð ÑеÑвÑÑÑой ÑоÑме агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð²ÑзÑваеÑÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки, Ñак как никакого конкÑеÑного знаÑÐµÐ½Ð¸Ñ Ð½Ðµ Ñказано (обÑÑно ÑÑо Ð¸Ð¼ÐµÐµÑ ÑмÑÑл ÑолÑко Ð´Ð»Ñ ÑÑнкÑии count(*)). РпоÑледней ÑоÑме иÑполÑзÑÑÑÑÑ ÑоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии, коÑоÑÑе бÑдÑÑ Ð¾Ð¿Ð¸ÑÐ°Ð½Ñ Ð½Ð¸Ð¶Ðµ.
ÐолÑÑинÑÑво агÑегаÑнÑÑ ÑÑнкÑий игноÑиÑÑÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ NULL, Ñак ÑÑо ÑÑÑоки, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ Ð²ÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð²ÑдаÑÑ Ð¾Ð´Ð½Ð¾ или неÑколÑко знаÑений NULL, оÑбÑаÑÑваÑÑÑÑ. ÐÑо можно ÑÑиÑаÑÑ Ð¸ÑÑиннÑм Ð´Ð»Ñ Ð²ÑÐµÑ Ð²ÑÑÑоеннÑÑ Ð¾Ð¿ÐµÑаÑоÑов, еÑли Ñвно не говоÑиÑÑÑ Ð¾Ð± обÑаÑном.
ÐапÑимеÑ, count(*) подÑÑиÑÐ°ÐµÑ Ð¾Ð±Ñее колиÑеÑÑво ÑÑÑок, а count(f1) ÑолÑко колиÑеÑÑво ÑÑÑок, в коÑоÑÑÑ
f1 не NULL (Ñак как count игноÑиÑÑÐµÑ NULL), а count(distinct f1) подÑÑиÑÐ°ÐµÑ ÑиÑло ÑазлиÑнÑÑ
и оÑлиÑнÑÑ
Ð¾Ñ NULL знаÑений колонки f1.
ÐбÑÑно ÑÑÑоки даннÑÑ
пеÑедаÑÑÑÑ Ð°Ð³ÑегаÑной ÑÑнкÑии в неопÑеделÑнном поÑÑдке и во многиÑ
ÑлÑÑаÑÑ
ÑÑо не Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениÑ, напÑÐ¸Ð¼ÐµÑ ÑÑнкÑÐ¸Ñ min вÑдаÑÑ Ð¾Ð´Ð¸Ð½ и ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑÐ°Ñ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо Ð¾Ñ Ð¿Ð¾ÑÑдка поÑÑÑпаÑÑиÑ
даннÑÑ
. Ðднако некоÑоÑÑе агÑегаÑнÑе ÑÑнкÑии (Ñакие как array_agg и string_agg) вÑдаÑÑ ÑезÑлÑÑаÑÑ, завиÑÑÑие Ð¾Ñ Ð¿Ð¾ÑÑдка даннÑÑ
. ÐÐ»Ñ ÑакиÑ
агÑегаÑнÑÑ
ÑÑнкÑий можно добавиÑÑ Ð¿Ñедложение_order_by и задаÑÑ Ð½ÑжнÑй поÑÑдок. ÐÑо пÑедложение_order_by Ð¸Ð¼ÐµÐµÑ ÑÐ¾Ñ Ð¶Ðµ ÑинÑакÑиÑ, ÑÑо и пÑедложение ORDER BY на ÑÑовне запÑоÑа, как опиÑано в Разделе 7.5, за иÑклÑÑением Ñого, ÑÑо его вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÑоÑÑо вÑÑажениÑми, а не именами ÑезÑлÑÑиÑÑÑÑиÑ
колонок или ÑиÑлами. ÐапÑимеÑ:
SELECT array_agg(a ORDER BY b DESC) FROM table;
ÐамеÑÑÑе, ÑÑо пÑи иÑполÑзовании агÑегаÑнÑÑ ÑÑнкÑий Ñ Ð½ÐµÑколÑкими аÑгÑменÑами, пÑедложение ORDER BY идÑÑ Ð¿Ð¾Ñле вÑÐµÑ Ð°ÑгÑменÑов. ÐапÑимеÑ, надо пиÑаÑÑ Ñак:
SELECT string_agg(a, ',' ORDER BY a) FROM table;
а не Ñак:
SELECT string_agg(a ORDER BY a, ',') FROM table; -- непÑавилÑно
ÐоÑледний ваÑÐ¸Ð°Ð½Ñ ÑинÑакÑиÑеÑки допÑÑÑим, но он пÑедÑÑавлÑÐµÑ Ñобой вÑзов агÑегаÑной ÑÑнкÑии одного аÑгÑменÑа Ñ Ð´Ð²ÑÐ¼Ñ ÐºÐ»ÑÑами ORDER BY (пÑи ÑÑом вÑоÑой не Ð¸Ð¼ÐµÐµÑ ÑмÑÑла, Ñак как ÑÑо конÑÑанÑа).
ÐÑли пÑедложение_order_by дополнено Ñказанием DISTINCT, Ñогда вÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ ORDER BY Ð´Ð¾Ð»Ð¶Ð½Ñ ÑооÑвеÑÑÑвоваÑÑ Ð¾Ð±ÑÑнÑм аÑгÑменÑам агÑегаÑной ÑÑнкÑии; Ñо еÑÑÑ Ð²Ñ Ð½Ðµ можеÑе ÑоÑÑиÑоваÑÑ ÑÑÑоки по вÑÑажениÑ, не вклÑÑÑÐ½Ð½Ð¾Ð¼Ñ Ð² ÑпиÑок DISTINCT.
ÐамеÑание: ÐозможноÑÑÑ ÑказÑваÑÑ Ð¸ DISTINCT, и ORDER BY в агÑегаÑной ÑÑнкÑии — ÑÑо ÑаÑÑиÑение PostgreSQL.
ÐÑи добавлении ORDER BY в обÑÑнÑй ÑпиÑок аÑгÑменÑов агÑегаÑной ÑÑнкÑии, опиÑанном до ÑÑого, вÑполнÑеÑÑÑ ÑоÑÑиÑовка ÑÑÑок Ð´Ð»Ñ "обÑÑной" агÑегаÑной ÑÑнкÑии, Ð´Ð»Ñ ÐºÐ¾ÑоÑой ÑоÑÑиÑовка необÑзаÑелÑна. Ðо еÑÑÑ Ð¿Ð¾Ð´Ð¼Ð½Ð¾Ð¶ÐµÑÑво агÑегаÑнÑÑ ÑÑнкÑий, ÑоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ Ð¿Ñедложение_order ÑвлÑеÑÑÑ Ð¾Ð±ÑзаÑелÑнÑм, обÑÑно поÑомÑ, ÑÑо вÑÑиÑление ÑÑой ÑÑнкÑии Ð¸Ð¼ÐµÐµÑ ÑмÑÑл ÑолÑко пÑи опÑеделÑнной ÑоÑÑиÑовке Ð²Ñ Ð¾Ð´Ð½ÑÑ ÑÑÑок. ТипиÑнÑми пÑимеÑами ÑоÑÑиÑÑÑÑÐ¸Ñ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑий ÑвлÑÑÑÑÑ Ð²ÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ñанга и пеÑÑенÑилÑ. ÐÐ»Ñ ÑоÑÑиÑÑÑÑей агÑегаÑной ÑÑнкÑии пÑедложение_order_by запиÑÑваеÑÑÑ Ð²Ð½ÑÑÑи WITHIN GROUP (...), ÑÑо иллÑÑÑÑиÑÑÐµÑ Ð¿Ð¾Ñледний пÑимеÑ, пÑиведÑннÑй вÑÑе. ÐÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð² пÑедложении_order_by вÑÑиÑлÑÑÑÑÑ Ð¾Ð´Ð½Ð¾ÐºÑаÑно Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ ÑÑÑоки как аÑгÑменÑÑ Ð¾Ð±ÑÑной агÑегаÑной ÑÑнкÑии, ÑоÑÑиÑÑемÑе в ÑооÑвеÑÑÑвии Ñ ÑÑебованием пÑедложениÑ_order_by, и поÑÑÑпаÑÑ Ð² агÑегаÑнÑÑ ÑÑнкÑии как Ð²Ñ Ð¾Ð´ÑÑие аÑгÑменÑÑ. (ÐÑли же пÑедложение_order_by Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ Ð½Ðµ в WITHIN GROUP, оно не пеÑедаÑÑÑÑ ÐºÐ°Ðº аÑгÑменÑ(Ñ) агÑегаÑной ÑÑнкÑии.) ÐÑÑажениÑ-аÑгÑменÑÑ, пÑедÑеÑÑвÑÑÑие WITHIN GROUP, (еÑли они еÑÑÑ), назÑваÑÑÑÑ Ð¿ÑÑмÑми аÑгÑменÑами, а вÑÑажениÑ, ÑказаннÑе в пÑедложении_order_by — агÑегиÑÑемÑми аÑгÑменÑами. РоÑлиÑие Ð¾Ñ Ð°ÑгÑменÑов обÑÑной агÑегаÑной ÑÑнкÑии, пÑÑмÑе аÑгÑменÑÑ Ð²ÑÑиÑлÑÑÑÑÑ Ð¾Ð´Ð½Ð¾ÐºÑаÑно Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð³Ð¾ вÑзова ÑÑнкÑии, а не Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки. ÐÑо знаÑиÑ, ÑÑо они могÑÑ ÑодеÑжаÑÑ Ð¿ÐµÑеменнÑе, ÑолÑко еÑли ÑÑи пеÑеменнÑе ÑгÑÑппиÑÐ¾Ð²Ð°Ð½Ñ Ð² GROUP BY; ÑÑо ÑÑÑÑ Ñо же огÑаниÑение, ÑÑо дейÑÑвовало бÑ, бÑÐ´Ñ ÑÑи пÑÑмÑе аÑгÑменÑÑ Ð²Ð½Ðµ агÑегаÑного вÑÑажениÑ. ÐÑÑмÑе аÑгÑменÑÑ Ð¾Ð±ÑÑно иÑполÑзÑÑÑÑÑ, напÑимеÑ, Ð´Ð»Ñ ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿ÐµÑÑенÑили, коÑоÑое Ð¸Ð¼ÐµÐµÑ ÑмÑÑл, ÑолÑко еÑли ÑÑо конкÑеÑное ÑиÑло Ð´Ð»Ñ Ð²Ñего ÑаÑÑÑÑа агÑегаÑной ÑÑнкÑии. СпиÑок пÑÑмÑÑ Ð°ÑгÑменÑов Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¿ÑÑÑ; в ÑÑом ÑлÑÑае запиÑиÑе пÑоÑÑо (), но не (*). (Ðа Ñамом деле PostgreSQL пÑÐ¸Ð¼ÐµÑ Ð¾Ð±Ðµ запиÑи, но ÑолÑко пеÑÐ²Ð°Ñ ÑооÑвеÑÑÑвÑÐµÑ ÑÑандаÑÑÑ SQL.) ÐÑÐ¸Ð¼ÐµÑ Ð²Ñзова ÑоÑÑиÑÑÑÑей агÑегаÑной ÑÑнкÑии:
SELECT percentile_disc(0.5) WITHIN GROUP (ORDER BY income) FROM households;
percentile_disc
-----------------
50489ÐдеÑÑ Ð¿Ð¾Ð»ÑÑаеÑÑÑ 50-Ð°Ñ Ð¿ÐµÑÑенÑÐ¸Ð»Ñ (или медиана) знаÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸ income (Ð´Ð¾Ñ Ð¾Ð´) из ÑаблиÑÑ households (домоÑадÑÑ). Рданном ÑлÑÑае, 0.5 — пÑÑмой аÑгÑменÑ; вÑÑажение не имело Ð±Ñ ÑмÑÑла, еÑли Ð±Ñ ÑÑÐ¾Ñ Ð°ÑгÑÐ¼ÐµÐ½Ñ Ð·Ð°Ð²Ð¸Ñел Ð¾Ñ Ð¾Ð±ÑабаÑÑваемÑÑ ÑÑÑок.
ÐÑли добавлено пÑедложение FILTER, агÑегаÑной ÑÑнкÑии подаÑÑÑÑ ÑолÑко Ñе Ð²Ñ Ð¾Ð´Ð½Ñе ÑÑÑоки, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ ÑÑловие_ÑилÑÑÑа вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº иÑÑинное; дÑÑгие ÑÑÑоки оÑбÑаÑÑваÑÑÑÑ. ÐапÑимеÑ:
SELECT
count(*) AS unfiltered,
count(*) FILTER (WHERE i < 5) AS filtered
FROM generate_series(1,10) AS s(i);
unfiltered | filtered
------------+----------
10 | 4
(1 row)ÐÑедопÑеделÑннÑе агÑегаÑнÑе ÑÑнкÑии опиÑÐ°Ð½Ñ Ð² Разделе 9.20. ÐолÑзоваÑÐµÐ»Ñ Ñакже Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделиÑÑ Ð´ÑÑгие агÑегаÑнÑе ÑÑнкÑии.
ÐгÑегаÑное вÑÑажение Ð¼Ð¾Ð¶ÐµÑ ÑигÑÑиÑоваÑÑ ÑолÑко в ÑпиÑке ÑезÑлÑÑаÑов или в пÑедложении HAVING ÐºÐ¾Ð¼Ð°Ð½Ð´Ñ SELECT. Ðо вÑÐµÑ Ð¾ÑÑалÑнÑÑ Ð¿ÑедложениÑÑ , напÑÐ¸Ð¼ÐµÑ WHERE, они запÑеÑенÑ, Ñак как ÑÑи пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑки вÑÑиÑлÑÑÑÑÑ Ð´Ð¾ Ñого, как ÑоÑмиÑÑÑÑÑÑ ÑезÑлÑÑаÑÑ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑий.
Ðогда агÑегаÑное вÑÑажение иÑполÑзÑеÑÑÑ Ð² подзапÑоÑе (Ñм. ÐодÑаздел 4.2.11 и Раздел 9.22), оно обÑÑно вÑÑиÑлÑеÑÑÑ Ð´Ð»Ñ Ð²ÑÐµÑ ÑÑÑок подзапÑоÑа. Ðо еÑли в аÑгÑменÑÐ°Ñ (или в ÑÑловии_filter) агÑегаÑной ÑÑнкÑии еÑÑÑ ÑолÑко пеÑеменнÑе внеÑнего ÑÑовнÑ, агÑегаÑÐ½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¾ÑноÑиÑÑÑ Ðº ближайÑÐµÐ¼Ñ Ð²Ð½ÐµÑÐ½ÐµÐ¼Ñ ÑÑÐ¾Ð²Ð½Ñ Ð¸ вÑÑиÑлÑеÑÑÑ Ð´Ð»Ñ Ð²ÑÐµÑ ÑÑÑок ÑооÑвеÑÑÑвÑÑÑего запÑоÑа. Такое агÑегаÑное вÑÑажение в Ñелом ÑвлÑеÑÑÑ Ð²Ð½ÐµÑней ÑÑÑлкой Ð´Ð»Ñ Ñвоего подзапÑоÑа и на каждом вÑÑиÑлении ÑÑиÑаеÑÑÑ ÐºÐ¾Ð½ÑÑанÑой. ÐÑи ÑÑом допÑÑÑимое положение агÑегаÑной ÑÑнкÑии огÑаниÑиваеÑÑÑ ÑпиÑком ÑезÑлÑÑаÑов и пÑедложением HAVING на Ñом ÑÑовне запÑоÑов, где она Ð½Ð°Ñ Ð¾Ð´Ð¸ÑÑÑ.
4.2.8. ÐÑÐ·Ð¾Ð²Ñ Ð¾ÐºÐ¾Ð½Ð½ÑÑ ÑÑнкÑий
ÐÑзов оконной ÑÑнкÑии пÑедÑÑавлÑÐµÑ Ñобой пÑименение ÑÑнкÑии, подобной агÑегаÑной, к некоÑоÑÐ¾Ð¼Ñ Ð½Ð°Ð±Ð¾ÑÑ ÑÑÑок, вÑбÑÐ°Ð½Ð½Ð¾Ð¼Ñ Ð·Ð°Ð¿ÑоÑом. РоÑлиÑие Ð¾Ñ Ð¾Ð±ÑÑнÑÑ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑий, оконнÑе ÑÑнкÑии не ÑвÑÐ·Ð°Ð½Ñ Ñ Ð³ÑÑппиÑовкой вÑбÑаннÑÑ ÑÑÑок в Ð¾Ð´Ð½Ñ — ÐºÐ°Ð¶Ð´Ð°Ñ ÑÑÑока оÑÑаÑÑÑÑ Ð¾ÑделÑной в ÑезÑлÑÑаÑе запÑоÑа. Ðднако Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑоÑканиÑоваÑÑ Ð²Ñе ÑÑÑоки, воÑедÑие в гÑÑÐ¿Ð¿Ñ ÑекÑÑей ÑÑÑоки ÑоглаÑно ÑÐºÐ°Ð·Ð°Ð½Ð¸Ñ (ÑпиÑÐºÑ PARTITION BY) пÑи вÑзове оконной ÑÑнкÑии. ÐÑзов оконной ÑÑнкÑии Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ ÑледÑÑÑие ÑоÑмÑ:
имÑ_ÑÑнкÑии ([вÑÑажение [, вÑÑажение ... ]]) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] OVER имÑ_окна имÑ_ÑÑнкÑии ([вÑÑажение [, вÑÑажение ... ]]) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] OVER ( опÑеделение_окна ) имÑ_ÑÑнкÑии ( * ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] OVER имÑ_окна имÑ_ÑÑнкÑии ( * ) [ FILTER ( WHERE ÑÑловие_ÑилÑÑÑа ) ] OVER ( опÑеделение_окна )
ÐдеÑÑ Ð¾Ð¿Ñеделение_окна запиÑÑваеÑÑÑ Ð² виде:
[ имÑ_ÑÑÑеÑÑвÑÑÑего_окна ]
[ PARTITION BY вÑÑажение [, ...] ]
[ ORDER BY вÑÑажение [ ASC | DESC | USING опеÑаÑÐ¾Ñ ] [ NULLS { FIRST | LAST } ] [, ...] ]
[ опÑеделение_Ñамки ]и необÑзаÑелÑное опÑеделение_Ñамки Ð¼Ð¾Ð¶ÐµÑ Ð¸Ð¼ÐµÑÑ Ð²Ð¸Ð´:
[ RANGE | ROWS ] наÑало_Ñамки [ RANGE | ROWS ] BETWEEN наÑало_Ñамки AND конеÑ_Ñамки
ÐдеÑÑ Ð½Ð°Ñало_Ñамки и конеÑ_Ñамки задаÑÑÑÑ Ð¾Ð´Ð½Ð¸Ð¼ из ÑледÑÑÑÐ¸Ñ ÑпоÑобов:
UNBOUNDED PRECEDING знаÑение PRECEDING CURRENT ROW знаÑение FOLLOWING UNBOUNDED FOLLOWING
ÐдеÑÑ Ð²ÑÑажение — ÑÑо лÑбое вÑÑажение знаÑениÑ, не ÑодеÑжаÑее вÑзовов оконнÑÑ ÑÑнкÑий.
имÑ_окна — ÑÑÑлка на именованное окно, опÑеделÑнное пÑедложением WINDOW в данном запÑоÑе. Также возможно напиÑаÑÑ Ð² ÑÐºÐ¾Ð±ÐºÐ°Ñ Ð¿Ð¾Ð»Ð½Ð¾Ðµ опÑеделение_окна, иÑполÑзÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑинÑакÑÐ¸Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ð¾Ð³Ð¾ окна в пÑедложении WINDOW; подÑобнее ÑÑо опиÑано в ÑпÑавке по SELECT. СÑÐ¾Ð¸Ñ Ð¾ÑмеÑиÑÑ, ÑÑо запиÑÑ OVER имÑ_окна не полноÑÑÑÑ ÑавнознаÑна OVER (имÑ_окна); поÑледний ваÑÐ¸Ð°Ð½Ñ Ð¿Ð¾Ð´ÑазÑÐ¼ÐµÐ²Ð°ÐµÑ ÐºÐ¾Ð¿Ð¸Ñование и изменение опÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð¾ÐºÐ½Ð° и не бÑÐ´ÐµÑ Ð´Ð¾Ð¿ÑÑÑимÑм, еÑли опÑеделение ÑÑого окна вклÑÑÐ°ÐµÑ Ð¾Ð¿Ñеделение Ñамки.
Указание PARTITION BY гÑÑппиÑÑÐµÑ ÑÑÑоки запÑоÑа в ÑазделÑ, коÑоÑÑе заÑем обÑабаÑÑваÑÑÑÑ Ð¾ÐºÐ¾Ð½Ð½Ð¾Ð¹ ÑÑнкÑией незавиÑимо дÑÑг Ð¾Ñ Ð´ÑÑга. PARTITION BY ÑабоÑÐ°ÐµÑ Ð¿Ð¾Ð´Ð¾Ð±Ð½Ð¾ пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ GROUP BY на ÑÑовне запÑоÑа, за иÑклÑÑением Ñого, ÑÑо его аÑгÑменÑÑ Ð²Ñегда пÑоÑÑо вÑÑажениÑ, а не имена вÑÑ Ð¾Ð´Ð½ÑÑ ÐºÐ¾Ð»Ð¾Ð½Ð¾Ðº или ÑиÑла. Ðез PARTITION BY вÑе ÑÑÑоки, вÑдаваемÑе запÑоÑом, ÑаÑÑмаÑÑиваÑÑÑÑ ÐºÐ°Ðº один Ñаздел. Указание ORDER BY опÑеделÑÐµÑ Ð¿Ð¾ÑÑдок, в коÑоÑом Ð¾ÐºÐ¾Ð½Ð½Ð°Ñ ÑÑнкÑÐ¸Ñ Ð¾Ð±ÑабаÑÑÐ²Ð°ÐµÑ ÑÑÑоки Ñаздела. Ðно Ñак же подобно пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ORDER BY на ÑÑовне запÑоÑа и Ñак же не пÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð¸Ð¼ÐµÐ½Ð° вÑÑ Ð¾Ð´Ð½ÑÑ ÐºÐ¾Ð»Ð¾Ð½Ð¾Ðº или ÑиÑла. Ðез ORDER BY ÑÑÑоки обÑабаÑÑваÑÑÑÑ Ð² неопÑеделÑнном поÑÑдке.
опÑеделение_Ñамки задаÑÑ Ð½Ð°Ð±Ð¾Ñ ÑÑÑок, обÑазÑÑÑÐ¸Ñ ÑÐ°Ð¼ÐºÑ Ð¾ÐºÐ½Ð°, коÑоÑÐ°Ñ Ð¿ÑедÑÑавлÑÐµÑ Ñобой подмножеÑÑво ÑÑÑок ÑекÑÑего Ñаздела и иÑполÑзÑеÑÑÑ Ð´Ð»Ñ Ð¾ÐºÐ¾Ð½Ð½ÑÑ ÑÑнкÑий, ÑабоÑаÑÑÐ¸Ñ Ñ Ñамкой, а не Ñо вÑем Ñазделом. Ð Ð°Ð¼ÐºÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑказаÑÑ Ð² ÑÐµÐ¶Ð¸Ð¼Ð°Ñ RANGE или ROWS; в лÑбом ÑлÑÑае она наÑинаеÑÑÑ Ñ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð°Ñало_Ñамки и заканÑиваеÑÑÑ Ð¿Ð¾Ð»Ð¾Ð¶ÐµÐ½Ð¸ÐµÐ¼ конеÑ_Ñамки. ÐÑли конеÑ_Ñамки опÑÑен, подÑазÑмеваеÑÑÑ CURRENT ROW (ÑекÑÑÐ°Ñ ÑÑÑока).
ÐÑли наÑало_Ñамки задано как UNBOUNDED PRECEDING, Ñамка наÑинаеÑÑÑ Ñ Ð¿ÐµÑвой ÑÑÑоки Ñаздела, а еÑли конеÑ_Ñамки опÑеделÑн как UNBOUNDED FOLLOWING, Ñамка заканÑиваеÑÑÑ Ð¿Ð¾Ñледней ÑÑÑокой Ñаздела.
Ð Ñежиме RANGE наÑало_Ñамки, заданное как CURRENT ROW, опÑеделÑÐµÑ Ð² каÑеÑÑве наÑала пеÑвÑÑ ÑодÑÑвеннÑÑ ÑÑÑÐ¾ÐºÑ (ÑÑÑокÑ, коÑоÑÑÑ ORDER BY ÑÑиÑÐ°ÐµÑ Ñавной ÑекÑÑей), Ñогда как конеÑ_Ñамки, заданнÑй как CURRENT ROW, опÑеделÑÐµÑ ÐºÐ¾Ð½Ñом Ñамки поÑледнÑÑ ÑодÑÑвеннÑÑ (Ð´Ð»Ñ ORDER BY) ÑÑÑокÑ. Ð Ñежиме ROWS ваÑÐ¸Ð°Ð½Ñ CURRENT ROW пÑоÑÑо обознаÑÐ°ÐµÑ ÑекÑÑÑÑ ÑÑÑокÑ.
ÐаÑианÑÑ Ð·Ð½Ð°Ñение PRECEDING и знаÑение FOLLOWING допÑÑкаÑÑÑÑ ÑолÑко в Ñежиме ROWS. Ðни ÑказÑваÑÑ, ÑÑо Ñамка наÑинаеÑÑÑ Ð¸Ð»Ð¸ заканÑиваеÑÑÑ Ñо Ñдвигом на заданное ÑиÑло ÑÑÑок пеÑед или поÑле заданной ÑÑÑоки. ÐдеÑÑ Ð·Ð½Ð°Ñение должно бÑÑÑ ÑелоÑиÑленнÑм вÑÑажением, не ÑодеÑжаÑим пеÑеменнÑе, агÑегаÑнÑе или оконнÑе ÑÑнкÑии, и Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½ÑлевÑм, ÑÑо бÑÐ´ÐµÑ Ð¾Ð·Ð½Ð°ÑаÑÑ Ð²ÑÐ±Ð¾Ñ ÑекÑÑей ÑÑÑоки.
Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ñамка опÑеделÑеÑÑÑ ÐºÐ°Ðº RANGE UNBOUNDED PRECEDING, ÑÑо ÑавноÑилÑно ÑаÑÑиÑÐµÐ½Ð½Ð¾Ð¼Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW. С Ñказанием ORDER BY ÑÑо ознаÑаеÑ, ÑÑо Ñамка бÑÐ´ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ Ð²Ñе ÑÑÑоки Ð¾Ñ Ð½Ð°Ñала Ñаздела до поÑледней ÑÑÑоки, ÑодÑÑвенной ÑекÑÑей (Ð´Ð»Ñ ORDER BY). Ðез ORDER BY в ÑÐ°Ð¼ÐºÑ Ð²ÐºÐ»ÑÑаÑÑÑÑ Ð²Ñе ÑÑÑоки Ñаздела, Ñак как вÑе они ÑÑиÑаÑÑÑÑ ÑодÑÑвеннÑми ÑекÑÑей.
ÐейÑÑвÑÑÑ Ñакже огÑаниÑениÑ: наÑало_Ñамки не Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделÑÑÑÑÑ ÐºÐ°Ðº UNBOUNDED FOLLOWING, а конеÑ_Ñамки — UNBOUNDED PRECEDING, и конеÑ_Ñамки не Ð¼Ð¾Ð¶ÐµÑ Ð¾Ð¿ÑеделÑÑÑÑÑ ÑанÑÑе, Ñем наÑало_Ñамки — напÑимеÑ, запиÑÑ RANGE BETWEEN CURRENT ROW AND знаÑение PRECEDING недопÑÑÑима.
ÐÑли добавлено пÑедложение FILTER, оконной ÑÑнкÑии подаÑÑÑÑ ÑолÑко Ñе Ð²Ñ Ð¾Ð´Ð½Ñе ÑÑÑоки, Ð´Ð»Ñ ÐºÐ¾ÑоÑÑÑ ÑÑловие_ÑилÑÑÑа вÑÑиÑлÑеÑÑÑ ÐºÐ°Ðº иÑÑинное; дÑÑгие ÑÑÑоки оÑбÑаÑÑваÑÑÑÑ. ÐÑедложение FILTER допÑÑкаеÑÑÑ ÑолÑко Ð´Ð»Ñ Ð°Ð³ÑегиÑÑÑÑÐ¸Ñ Ð¾ÐºÐ¾Ð½Ð½ÑÑ ÑÑнкÑий.
ÐÑÑÑоеннÑе оконнÑе ÑÑнкÑии опиÑÐ°Ð½Ñ Ð² ТаблиÑе 9-53, но ÑÑÐ¾Ñ Ð½Ð°Ð±Ð¾Ñ Ð¼Ð¾Ð¶Ð½Ð¾ ÑаÑÑиÑиÑÑ, ÑÐ¾Ð·Ð´Ð°Ð²Ð°Ñ ÑобÑÑвеннÑе ÑÑнкÑии. ÐÑоме Ñого, в каÑеÑÑве оконнÑÑ ÑÑнкÑий можно иÑполÑзоваÑÑ Ð»ÑбÑе вÑÑÑоеннÑе или полÑзоваÑелÑÑкие обÑÑнÑе агÑегаÑнÑе ÑÑнкÑии (ÑоÑÑиÑÑÑÑие агÑегаÑнÑе ÑÑнкÑии иÑполÑзоваÑÑ Ð² каÑеÑÑве оконнÑÑ Ð½ÐµÐ»ÑзÑ).
ÐапиÑÑ Ñо звÑздоÑкой (*) пÑименÑеÑÑÑ Ð¿Ñи вÑзове агÑегаÑнÑÑ ÑÑнкÑий в каÑеÑÑве оконнÑÑ , напÑÐ¸Ð¼ÐµÑ count(*) OVER (PARTITION BY x ORDER BY y). ÐвÑздоÑка (*) обÑÑно не пÑименÑеÑÑÑ Ð´Ð»Ñ Ð½Ðµ агÑегаÑнÑÑ Ð¾ÐºÐ¾Ð½Ð½ÑÑ ÑÑнкÑий. ÐгÑегаÑнÑе оконнÑе ÑÑнкÑии, в оÑлиÑие Ð¾Ñ Ð¾Ð±ÑÑнÑÑ Ð°Ð³ÑегаÑнÑÑ ÑÑнкÑий, не допÑÑкаÑÑ Ð¸ÑполÑÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ DISTINCT и ORDER BY в ÑпиÑке аÑгÑменÑов.
ÐÑÐ·Ð¾Ð²Ñ Ð¾ÐºÐ¾Ð½Ð½ÑÑ ÑÑнкÑий ÑазÑеÑÐµÐ½Ñ Ð² запÑоÑÐ°Ñ ÑолÑко в ÑпиÑке SELECT и в пÑедложении ORDER BY.
ÐополниÑелÑно об оконнÑÑ ÑÑнкÑиÑÑ Ð¼Ð¾Ð¶Ð½Ð¾ ÑзнаÑÑ Ð² Разделе 3.5, Разделе 9.21 и ÐодÑазделе 7.2.4.
4.2.9. ÐÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñипов
ÐÑиведение Ñипа опÑеделÑÐµÑ Ð¿ÑеобÑазование даннÑÑ Ð¸Ð· одного Ñипа в дÑÑгой. PostgreSQL воÑпÑÐ¸Ð½Ð¸Ð¼Ð°ÐµÑ Ð´Ð²Ðµ ÑавноÑилÑнÑе запиÑи пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñипов:
CAST ( вÑÑажение AS Ñип ) вÑÑажение::Ñип
ÐапиÑÑ Ñ CAST ÑооÑвеÑÑÑвÑÐµÑ ÑÑандаÑÑÑ SQL, Ñогда как ваÑÐ¸Ð°Ð½Ñ Ñ :: — иÑÑоÑиÑеÑкое наÑледие PostgreSQL.
Ðогда пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð²ÐµÑгаеÑÑÑ Ð·Ð½Ð°Ñение вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¸Ð·Ð²ÐµÑÑного Ñипа, пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð¿ÑеобÑазование Ñипа во вÑÐµÐ¼Ñ Ð²ÑполнениÑ. ÐÑо пÑиведение бÑÐ´ÐµÑ ÑÑпеÑнÑм, ÑолÑко еÑли опÑеделÑн Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑий опеÑаÑÐ¾Ñ Ð¿ÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ Ñипов. ÐбÑаÑиÑе внимание на неболÑÑое оÑлиÑие Ð¾Ñ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ ÐºÐ¾Ð½ÑÑанÑ, опиÑанного в ÐодÑазделе 4.1.2.7. ÐÑиведение ÑÑÑоки в ÑиÑÑом виде пÑедÑÑавлÑÐµÑ Ñобой наÑалÑное пÑиÑваивание ÑÑÑоковой конÑÑанÑÑ Ð¸ оно бÑÐ´ÐµÑ ÑÑпеÑнÑм Ð´Ð»Ñ Ð»Ñбого Ñипа (конеÑно, еÑли ÑÑÑока ÑодеÑÐ¶Ð¸Ñ Ð·Ð½Ð°Ñение, пÑиемлемое Ð´Ð»Ñ Ð´Ð°Ð½Ð½Ð¾Ð³Ð¾ Ñипа даннÑÑ ).
ÐеÑвное пÑиведение Ñипа можно опÑÑÑиÑÑ, еÑли возможно однознаÑно опÑеделиÑÑ, какой Ñип должно имеÑÑ Ð²ÑÑажение (напÑимеÑ, когда оно пÑиÑваиваеÑÑÑ ÐºÐ¾Ð»Ð¾Ð½ÐºÐµ ÑаблиÑÑ); в ÑÐ°ÐºÐ¸Ñ ÑлÑÑаÑÑ ÑиÑÑема авÑомаÑиÑеÑки пÑеобÑазÑÐµÑ Ñип. Ðднако авÑомаÑиÑеÑкое пÑеобÑазование вÑполнÑеÑÑÑ ÑолÑко Ð´Ð»Ñ Ð¿Ñиведений Ñ Ð¿Ð¾Ð¼ÐµÑкой "допÑÑкаеÑÑÑ Ð½ÐµÑвное пÑименение" в ÑиÑÑемнÑÑ ÐºÐ°ÑÐ°Ð»Ð¾Ð³Ð°Ñ . ÐÑе оÑÑалÑнÑе пÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð·Ð°Ð¿Ð¸ÑÑваÑÑÑÑ Ñвно. ÐÑо огÑаниÑение позволÑÐµÑ Ð¸Ð·Ð±ÐµÐ¶Ð°ÑÑ ÑÑÑпÑизов Ñ Ð½ÐµÑвнÑм пÑеобÑазованием.
Также можно запиÑаÑÑ Ð¿Ñиведение Ñипа как вÑзов ÑÑнкÑии:
имÑ_Ñипа ( вÑÑажение )
Ðднако ÑÑо бÑÐ´ÐµÑ ÑабоÑаÑÑ ÑолÑко Ð´Ð»Ñ Ñипов, имена коÑоÑÑÑ ÑвлÑÑÑÑÑ Ñакже допÑÑÑимÑми именами ÑÑнкÑий. ÐапÑимеÑ, double precision Ñак иÑполÑзоваÑÑ Ð½ÐµÐ»ÑзÑ, а float8 (алÑÑеÑнаÑивное название Ñого же Ñипа) — можно. ÐÑоме Ñого, имена Ñипов interval, time и timestamp из-за ÑинÑакÑиÑеÑкого конÑликÑа можно иÑполÑзоваÑÑ Ð² Ñакой запиÑи ÑолÑко в кавÑÑÐºÐ°Ñ . Таким обÑазом, запиÑÑ Ð¿ÑÐ¸Ð²ÐµÐ´ÐµÐ½Ð¸Ñ Ñипа в виде вÑзова ÑÑнкÑии пÑовоÑиÑÑÐµÑ Ð½ÐµÑооÑвеÑÑÑÐ²Ð¸Ñ Ð¸, возможно, лÑÑÑе бÑÐ´ÐµÑ ÐµÑ Ð½Ðµ пÑименÑÑÑ.
ÐамеÑание: ÐÑиведение Ñипа, пÑедÑÑавленное в виде вÑзова ÑÑнкÑии, на Ñамом деле ÑооÑвеÑÑÑвÑÐµÑ Ð²Ð½ÑÑÑÐµÐ½Ð½ÐµÐ¼Ñ Ð¼ÐµÑ Ð°Ð½Ð¸Ð·Ð¼Ñ. Ðаже пÑи иÑполÑзовании двÑÑ ÑÑандаÑÑнÑÑ Ñипов запиÑи внÑÑÑи пÑоиÑÑ Ð¾Ð´Ð¸Ñ Ð²Ñзов заÑегиÑÑÑиÑованной ÑÑнкÑии, вÑполнÑÑÑей пÑеобÑазование. Ðо ÑоглаÑÐµÐ½Ð¸Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ Ñакой ÑÑнкÑии пÑеобÑÐ°Ð·Ð¾Ð²Ð°Ð½Ð¸Ñ ÑвлÑеÑÑÑ Ð¸Ð¼Ñ Ð²ÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ Ñипа, и Ñаким обÑазом запиÑÑ "в виде вÑзова ÑÑнкÑии" еÑÑÑ Ð½Ðµ ÑÑо иное, как пÑÑмой вÑзов нижележаÑей ÑÑнкÑии пÑеобÑазованиÑ. ÐÑи Ñоздании пеÑеноÑимого пÑÐ¸Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ Ð½Ð° ÑÑо поведение, конеÑно, не ÑледÑÐµÑ ÑаÑÑÑиÑÑваÑÑ. ÐодÑобнее ÑÑо опиÑано в ÑпÑавке CREATE CAST.
4.2.10. ÐÑименение пÑавил ÑоÑÑиÑовки
ÐÑедложение COLLATE пеÑеопÑеделÑÐµÑ Ð¿Ñавило ÑоÑÑиÑовки вÑÑажениÑ. Ðно добавлÑеÑÑÑ Ð¿Ð¾Ñле вÑÑажениÑ:
вÑÑажение COLLATE пÑавило_ÑоÑÑиÑовки
где пÑавило_ÑоÑÑиÑовки — иденÑиÑикаÑÐ¾Ñ Ð¿Ñавила, возможно дополненнÑй именем ÑÑ ÐµÐ¼Ñ. ÐÑедложение COLLATE ÑвÑзÑÐ²Ð°ÐµÑ Ð²ÑÑажение ÑилÑнее, Ñем опеÑаÑоÑÑ, Ñак ÑÑо пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи ÑледÑÐµÑ Ð¸ÑполÑзоваÑÑ Ñкобки.
ÐÑли пÑавило ÑоÑÑиÑовки не опÑеделено Ñвно, ÑиÑÑема либо вÑбиÑÐ°ÐµÑ ÐµÐ³Ð¾ по колонкам, коÑоÑÑе иÑполÑзÑÑÑÑÑ Ð² вÑÑажении, либо, еÑли ÑÐ°ÐºÐ¸Ñ ÐºÐ¾Ð»Ð¾Ð½Ð¾Ðº неÑ, пеÑеклÑÑаеÑÑÑ Ð½Ð° ÑÑÑановленное Ð´Ð»Ñ Ð±Ð°Ð·Ñ Ð´Ð°Ð½Ð½ÑÑ Ð¿Ñавило ÑоÑÑиÑовки по ÑмолÑаниÑ.
ÐÑедложение COLLATE Ð¸Ð¼ÐµÐµÑ Ð´Ð²Ð° ÑаÑпÑоÑÑÑанÑннÑÑ Ð¿ÑименениÑ: пеÑеопÑеделение поÑÑдка ÑоÑÑиÑовки в пÑедложении ORDER BY, напÑимеÑ:
SELECT a, b, c FROM tbl WHERE ... ORDER BY a COLLATE "C";
и пеÑеопÑеделение пÑавил ÑоÑÑиÑовки пÑи вÑзове ÑÑнкÑий или опеÑаÑоÑов, возвÑаÑаÑÑÐ¸Ñ ÑзÑкозавиÑимÑе ÑезÑлÑÑаÑÑ, напÑимеÑ:
SELECT * FROM tbl WHERE a > 'foo' COLLATE "C";
ÐамеÑÑÑе, ÑÑо в поÑледнем ÑлÑÑае пÑедложение COLLATE добавлено к аÑгÑменÑÑ Ð¾Ð¿ÐµÑаÑоÑа, на дейÑÑвие коÑоÑого Ð¼Ñ Ñ Ð¾Ñим повлиÑÑÑ. ÐÑи ÑÑом не Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°ÑениÑ, к ÐºÐ°ÐºÐ¾Ð¼Ñ Ð¸Ð¼ÐµÐ½Ð½Ð¾ аÑгÑменÑÑ Ð¾Ð¿ÐµÑаÑоÑа или ÑÑнкÑии добавлÑеÑÑÑ COLLATE, Ñак как пÑавило ÑоÑÑиÑовки, пÑименÑемое к опеÑаÑоÑÑ Ð¸Ð»Ð¸ ÑÑнкÑии, вÑбиÑаеÑÑÑ Ð¿Ñи ÑаÑÑмоÑÑении вÑÐµÑ Ð°ÑгÑменÑов, а Ñвное пÑедложение COLLATE пеÑеопÑеделÑÐµÑ Ð¿Ñавила ÑоÑÑиÑовки Ð´Ð»Ñ Ð²ÑÐµÑ Ð´ÑÑÐ³Ð¸Ñ Ð°ÑгÑменÑов. (Ðднако добавление ÑазнÑÑ Ð¿Ñедложений COLLATE к неÑколÑким аÑгÑменÑам бÑÐ´ÐµÑ Ð¾Ñибкой. ÐодÑобнее об ÑÑом Ñм. Раздел 22.2.) Таким обÑазом, ÑÑа команда вÑдаÑÑ ÑÐ¾Ñ Ð¶Ðµ ÑезÑлÑÑаÑ:
SELECT * FROM tbl WHERE a COLLATE "C" > 'foo';
Ðо ÑÑо бÑÐ´ÐµÑ Ð¾Ñибкой:
SELECT * FROM tbl WHERE (a > 'foo') COLLATE "C";
здеÑÑ Ð¿Ñавило ÑоÑÑиÑовки нелÑÐ·Ñ Ð¿ÑимениÑÑ Ðº ÑезÑлÑÑаÑÑ Ð¾Ð¿ÐµÑаÑоÑа >, коÑоÑÑй Ð¸Ð¼ÐµÐµÑ Ð½ÐµÑÑавниваемÑй Ñип даннÑÑ boolean.
4.2.11. СкалÑÑнÑе подзапÑоÑÑ
СкалÑÑнÑй подзапÑÐ¾Ñ — ÑÑо обÑÑнÑй запÑÐ¾Ñ SELECT в ÑÐºÐ¾Ð±ÐºÐ°Ñ , коÑоÑÑй возвÑаÑÐ°ÐµÑ Ñовно Ð¾Ð´Ð½Ñ ÑÑÑÐ¾ÐºÑ Ð¸ Ð¾Ð´Ð½Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÑ. (ÐапиÑание запÑоÑов оÑвеÑаеÑÑÑ Ð² Ðлаве 7.) ÐоÑле вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð·Ð°Ð¿ÑоÑа SELECT его единÑÑвеннÑй ÑезÑлÑÑÐ°Ñ Ð¸ÑполÑзÑеÑÑÑ Ð² окÑÑжаÑÑем его вÑÑажении. РкаÑеÑÑве ÑкалÑÑного подзапÑоÑа нелÑÐ·Ñ Ð¸ÑполÑзоваÑÑ Ð·Ð°Ð¿ÑоÑÑ, возвÑаÑаÑÑие более одной ÑÑÑоки или колонки. (Ðо еÑли в ÑезÑлÑÑаÑе вÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑÐ¾Ñ Ð½Ðµ веÑнÑÑ ÑÑÑок, ÑкалÑÑнÑй ÑезÑлÑÑÐ°Ñ ÑÑиÑаеÑÑÑ ÑавнÑм NULL.) РподзапÑоÑе можно ÑÑÑлаÑÑÑÑ Ð½Ð° пеÑеменнÑе из окÑÑжаÑÑего запÑоÑа; в пÑоÑеÑÑе одного вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑоÑа они бÑдÑÑ ÑÑиÑаÑÑÑÑ ÐºÐ¾Ð½ÑÑанÑами. ÐÑÑгие вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ñ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑоÑами опиÑÐ°Ð½Ñ Ð² Разделе 9.22.
ÐапÑимеÑ, ÑледÑÑÑий запÑÐ¾Ñ Ð½Ð°Ñ Ð¾Ð´Ð¸Ñ ÑамÑй наÑелÑннÑй гоÑод в каждом ÑÑаÑе:
SELECT name, (SELECT max(pop) FROM cities WHERE cities.state = states.name)
FROM states;4.2.12. ÐонÑÑÑÑкÑоÑÑ Ð¼Ð°ÑÑивов
ÐонÑÑÑÑкÑÐ¾Ñ Ð¼Ð°ÑÑива — ÑÑо вÑÑажение, коÑоÑое ÑоздаÑÑ Ð¼Ð°ÑÑив, опÑеделÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÐµÐ³Ð¾ ÑлеменÑов. ÐонÑÑÑÑкÑÐ¾Ñ Ð¿ÑоÑÑого маÑÑива ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· клÑÑевого Ñлова ARRAY, оÑкÑÑваÑÑей квадÑаÑной Ñкобки [, ÑпиÑка вÑÑажений (ÑазделÑннÑÑ Ð·Ð°Ð¿ÑÑÑми), задаÑÑÐ¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ ÑлеменÑов маÑÑива, и закÑÑваÑÑей квадÑаÑной Ñкобки ]. ÐапÑимеÑ:
SELECT ARRAY[1,2,3+4];
array
---------
{1,2,7}
(1 row)Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ñипом ÑлеменÑов маÑÑива ÑÑиÑаеÑÑÑ Ð¾Ð±Ñий Ñип Ð´Ð»Ñ Ð²ÑÐµÑ Ð²ÑÑажений, опÑеделÑннÑй по пÑавилам, дейÑÑвÑÑÑим и Ð´Ð»Ñ ÐºÐ¾Ð½ÑÑÑÑкÑий UNION и CASE (Ñм. Раздел 10.5). ÐÑ Ð¼Ð¾Ð¶ÐµÑе пеÑеопÑеделиÑÑ ÐµÐ³Ð¾ Ñвно, пÑÐ¸Ð²ÐµÐ´Ñ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¾Ñ Ð¼Ð°ÑÑива к ÑÑебÑÐµÐ¼Ð¾Ð¼Ñ ÑипÑ, напÑимеÑ:
SELECT ARRAY[1,2,22.7]::integer[];
array
----------
{1,2,23}
(1 row)ÐÑо ÑавноÑилÑно ÑомÑ, ÑÑо пÑивеÑÑи к нÑÐ¶Ð½Ð¾Ð¼Ñ ÑÐ¸Ð¿Ñ ÐºÐ°Ð¶Ð´Ð¾Ðµ вÑÑажение по оÑделÑноÑÑи. ÐодÑобнее пÑиведение Ñипов опиÑано в ÐодÑазделе 4.2.9.
ÐногомеÑнÑе маÑÑÐ¸Ð²Ñ Ð¼Ð¾Ð¶Ð½Ð¾ обÑазовÑваÑÑ, вкладÑÐ²Ð°Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑÑ Ð¼Ð°ÑÑивов. ÐÑи ÑÑом во внÑÑÑÐµÐ½Ð½Ð¸Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑÐ°Ñ Ñлово ARRAY можно опÑÑкаÑÑ. ÐапÑимеÑ, ÑезÑлÑÑÐ°Ñ ÑабоÑÑ ÑÑÐ¸Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑов одинаков:
SELECT ARRAY[ARRAY[1,2], ARRAY[3,4]];
array
---------------
{{1,2},{3,4}}
(1 row)
SELECT ARRAY[[1,2],[3,4]];
array
---------------
{{1,2},{3,4}}
(1 row)ÐногомеÑнÑе маÑÑÐ¸Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÑÑмоÑголÑнÑми, и поÑÑÐ¾Ð¼Ñ Ð²Ð½ÑÑÑенние конÑÑÑÑкÑоÑÑ Ð¾Ð´Ð½Ð¾Ð³Ð¾ ÑÑÐ¾Ð²Ð½Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ ÑоздаваÑÑ Ð²Ð»Ð¾Ð¶ÐµÐ½Ð½Ñе маÑÑÐ¸Ð²Ñ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾Ð¹ ÑазмеÑноÑÑи. ÐÑбое пÑиведение Ñипа, пÑименÑнное к внеÑÐ½ÐµÐ¼Ñ ÐºÐ¾Ð½ÑÑÑÑкÑоÑÑ ARRAY, авÑомаÑиÑеÑки ÑаÑпÑоÑÑÑанÑеÑÑÑ Ð½Ð° вÑе внÑÑÑенние.
ÐлеменÑÑ Ð¼Ð½Ð¾Ð³Ð¾Ð¼ÐµÑного маÑÑива можно ÑоздаваÑÑ Ð½Ðµ ÑолÑко вложеннÑми конÑÑÑÑкÑоÑами ARRAY, но и дÑÑгими ÑпоÑобами, позволÑÑÑими полÑÑиÑÑ Ð¼Ð°ÑÑÐ¸Ð²Ñ Ð½Ñжного Ñипа. ÐапÑимеÑ:
CREATE TABLE arr(f1 int[], f2 int[]);
INSERT INTO arr VALUES (ARRAY[[1,2],[3,4]], ARRAY[[5,6],[7,8]]);
SELECT ARRAY[f1, f2, '{{9,10},{11,12}}'::int[]] FROM arr;
array
------------------------------------------------
{{{1,2},{3,4}},{{5,6},{7,8}},{{9,10},{11,12}}}
(1 row)ÐÑ Ð¼Ð¾Ð¶ÐµÑе ÑоздаÑÑ Ð¸ пÑÑÑой маÑÑив, но Ñак как маÑÑив не Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð½Ðµ ÑипизиÑованнÑм, Ð²Ñ Ð´Ð¾Ð»Ð¶Ð½Ñ Ñвно пÑивеÑÑи пÑÑÑой маÑÑив к нÑÐ¶Ð½Ð¾Ð¼Ñ ÑипÑ. ÐапÑимеÑ:
SELECT ARRAY[]::integer[];
array
-------
{}
(1 row)Также возможно ÑоздаÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¸Ð· ÑезÑлÑÑаÑов подзапÑоÑа. Ð ÑÑом ÑлÑÑае конÑÑÑÑкÑÐ¾Ñ Ð¼Ð°ÑÑива запиÑÑваеÑÑÑ Ñак же Ñ ÐºÐ»ÑÑевÑм Ñловом ARRAY, за коÑоÑÑм в кÑÑглÑÑ ÑÐºÐ¾Ð±ÐºÐ°Ñ ÑледÑÐµÑ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑоÑ. ÐапÑимеÑ:
SELECT ARRAY(SELECT oid FROM pg_proc WHERE proname LIKE 'bytea%');
array
-----------------------------------------------------------------------
{2011,1954,1948,1952,1951,1244,1950,2005,1949,1953,2006,31,2412,2413}
(1 row)Такой подзапÑÐ¾Ñ Ð´Ð¾Ð»Ð¶ÐµÐ½ возвÑаÑаÑÑ Ð¾Ð´Ð½Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÑ. РезÑлÑÑиÑÑÑÑий одномеÑнÑй маÑÑив бÑÐ´ÐµÑ Ð²ÐºÐ»ÑÑаÑÑ ÑлеменÑÑ Ð´Ð»Ñ ÐºÐ°Ð¶Ð´Ð¾Ð¹ ÑÑÑоки-ÑезÑлÑÑаÑа подзапÑоÑа и Ñипом ÑлеменÑа бÑÐ´ÐµÑ Ñип колонки ÑезÑлÑÑаÑа.
ÐндекÑÑ Ð¼Ð°ÑÑива, Ñозданного конÑÑÑÑкÑоÑом ARRAY, вÑегда наÑинаÑÑÑÑ Ñ Ð¾Ð´Ð½Ð¾Ð³Ð¾. ÐодÑобнее о маÑÑÐ¸Ð²Ð°Ñ Ð²Ñ ÑзнаеÑе в Разделе 8.15.
4.2.13. ÐонÑÑÑÑкÑоÑÑ ÑаблиÑнÑÑ ÑÑÑок
ÐонÑÑÑÑкÑÐ¾Ñ ÑаблиÑной ÑÑÑоки — ÑÑо вÑÑажение, ÑоздаÑÑее ÑÑÑÐ¾ÐºÑ Ð¸Ð»Ð¸ коÑÑеж (или ÑоÑÑавное знаÑение) из знаÑений его аÑгÑменÑов-полей. ÐонÑÑÑÑкÑÐ¾Ñ ÑÑÑоки ÑоÑÑÐ¾Ð¸Ñ Ð¸Ð· клÑÑевого Ñлова ROW, оÑкÑÑваÑÑей кÑÑглой Ñкобки, нÑÐ»Ñ Ð¸Ð»Ð¸ неÑколÑÐºÐ¸Ñ Ð²ÑÑажений (ÑазделÑннÑÑ Ð·Ð°Ð¿ÑÑÑми), опÑеделÑÑÑÐ¸Ñ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¿Ð¾Ð»ÐµÐ¹, и закÑÑваÑÑей Ñкобки. ÐапÑимеÑ:
SELECT ROW(1,2.5,'this is a test');
ÐÑли в ÑпиÑке более одного вÑÑажениÑ, клÑÑевое Ñлово ROW можно опÑÑÑиÑÑ.
ÐонÑÑÑÑкÑÐ¾Ñ ÑÑÑоки поддеÑÐ¶Ð¸Ð²Ð°ÐµÑ Ð·Ð°Ð¿Ð¸ÑÑ ÑоÑÑавное_знаÑение.*, пÑи ÑÑом данное знаÑение бÑÐ´ÐµÑ ÑазвÑÑнÑÑо в ÑпиÑок ÑлеменÑов, Ñак же, как в запиÑи .* на веÑÑ Ð½ÐµÐ¼ ÑÑовне ÑпиÑка SELECT. ÐапÑимеÑ, еÑли ÑаблиÑа t ÑодеÑÐ¶Ð¸Ñ ÐºÐ¾Ð»Ð¾Ð½ÐºÐ¸ f1 и f2, ÑÑи запиÑи ÑквиваленÑнÑ:
SELECT ROW(t.*, 42) FROM t; SELECT ROW(t.f1, t.f2, 42) FROM t;
ÐамеÑание: Ðо веÑÑии PostgreSQL 8.2 запиÑÑ .* не ÑазвоÑаÑивалаÑÑ, Ñак ÑÑо вÑÑажение ROW(t.*, 42) Ñоздавало ÑоÑÑавное знаÑение из двÑÑ Ð¿Ð¾Ð»ÐµÐ¹, в коÑоÑом пеÑвое поле Ñак же бÑло ÑоÑÑавнÑм. Ðовое поведение обÑÑно более полезно. ÐÑли вам нÑжно ÑоздаÑÑ ÑÑÑÐ¾ÐºÑ Ð¸Ð· двÑÑ Ð¿Ð¾Ð»ÐµÐ¹ Ñак, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑвое поле ÑодеÑжало ÑÑÑокÑ, напиÑиÑе внÑÑÑеннее знаÑение без .*, напÑÐ¸Ð¼ÐµÑ ROW(t, 42).
Ðо ÑмолÑÐ°Ð½Ð¸Ñ Ð·Ð½Ð°Ñение, Ñозданное вÑÑажением ROW, Ð¸Ð¼ÐµÐµÑ Ñип анонимной запиÑи. ÐÑли Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾, его можно пÑивеÑÑи к Ð¸Ð¼ÐµÐ½Ð¾Ð²Ð°Ð½Ð½Ð¾Ð¼Ñ ÑоÑÑÐ°Ð²Ð½Ð¾Ð¼Ñ ÑÐ¸Ð¿Ñ — либо к ÑÐ¸Ð¿Ñ ÑÑÑоки ÑаблиÑÑ, либо ÑоÑÑÐ°Ð²Ð½Ð¾Ð¼Ñ ÑипÑ, ÑÐ¾Ð·Ð´Ð°Ð½Ð½Ð¾Ð¼Ñ Ð¾Ð¿ÐµÑаÑоÑом CREATE TYPE AS. Явное пÑиведение Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ Ð´Ð»Ñ Ð´Ð¾ÑÑÐ¸Ð¶ÐµÐ½Ð¸Ñ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°ÑноÑÑи. ÐапÑимеÑ:
CREATE TABLE mytable(f1 int, f2 float, f3 text);
CREATE FUNCTION getf1(mytable) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- ÐÑиведение не ÑÑебÑеÑÑÑ, Ñак как ÑÑÑеÑÑвÑÐµÑ ÑолÑко одна getf1()
SELECT getf1(ROW(1,2.5,'this is a test'));
getf1
-------
1
(1 row)
CREATE TYPE myrowtype AS (f1 int, f2 text, f3 numeric);
CREATE FUNCTION getf1(myrowtype) RETURNS int AS 'SELECT $1.f1' LANGUAGE SQL;
-- ТепеÑÑ Ð¿Ñиведение необÑ
одимо Ð´Ð»Ñ Ð¾Ð´Ð½Ð¾Ð·Ð½Ð°Ñного вÑбоÑа ÑÑнкÑии:
SELECT getf1(ROW(1,2.5,'this is a test'));
ÐШÐÐÐÐ: ÑÑнкÑÐ¸Ñ getf1(record) не ÑникалÑна
SELECT getf1(ROW(1,2.5,'this is a test')::mytable);
getf1
-------
1
(1 row)
SELECT getf1(CAST(ROW(11,'this is a test',2.5) AS myrowtype));
getf1
-------
11
(1 row)ÐÑполÑзÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¾Ñ ÑÑÑок (коÑÑежей), можно ÑоздаваÑÑ ÑоÑÑавное знаÑение Ð´Ð»Ñ ÑÐ¾Ñ ÑÐ°Ð½ÐµÐ½Ð¸Ñ Ð² колонке ÑоÑÑавного Ñипа или Ð´Ð»Ñ Ð¿ÐµÑедаÑи ÑÑнкÑии, пÑинимаÑÑей ÑоÑÑавной паÑамеÑÑ. Также Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе ÑÑавниÑÑ Ð´Ð²Ð° ÑоÑÑавнÑÑ Ð·Ð½Ð°ÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ пÑовеÑиÑÑ Ð¸Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ IS NULL или IS NOT NULL, напÑимеÑ:
SELECT ROW(1,2.5,'this is a test') = ROW(1, 3, 'not the same'); -- вÑбÑаÑÑ Ð²Ñе ÑÑÑоки, ÑодеÑжаÑие ÑолÑко NULL SELECT ROW(table.*) IS NULL FROM table;
ÐодÑобнее Ñм. Раздел 9.23. ÐонÑÑÑÑкÑоÑÑ ÑÑÑок Ñакже могÑÑ Ð¸ÑполÑзоваÑÑÑÑ Ð² ÑоÑеÑании Ñ Ð¿Ð¾Ð´Ð·Ð°Ð¿ÑоÑами, как опиÑано в Разделе 9.22.
4.2.14. ÐÑавила вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð²ÑÑажений
ÐоÑÑдок вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð¿Ð¾Ð´Ð²ÑÑажений не опÑеделÑн. Ð ÑаÑÑноÑÑи, аÑгÑменÑÑ Ð¾Ð¿ÐµÑаÑоÑа или ÑÑнкÑии не обÑзаÑелÑно вÑÑиÑлÑÑÑÑÑ Ñлева напÑаво или в лÑбом дÑÑгом ÑикÑиÑованном поÑÑдке.
Ðолее Ñого, еÑли ÑезÑлÑÑÐ°Ñ Ð²ÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ, вÑÑиÑлÑÑ ÑолÑко некоÑоÑÑе его ÑаÑÑи, Ñогда дÑÑгие подвÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð½Ðµ бÑдÑÑ Ð²ÑÑиÑлÑÑÑÑÑ Ð²Ð¾Ð²Ñе. ÐапÑимеÑ, еÑли напиÑаÑÑ:
SELECT true OR somefunc();
Ñогда ÑÑнкÑÐ¸Ñ somefunc() не бÑÐ´ÐµÑ Ð²ÑзÑваÑÑÑÑ (возможно). То же Ñамое ÑпÑаведливо Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи:
SELECT somefunc() OR true;
ÐамеÑÑÑе, ÑÑо ÑÑо оÑлиÑаеÑÑÑ Ð¾Ñ "опÑимизаÑии" вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð»Ð¾Ð³Ð¸ÑеÑÐºÐ¸Ñ Ð¾Ð¿ÐµÑаÑоÑов Ñлева напÑаво, Ñеализованной в некоÑоÑÑÑ ÑзÑÐºÐ°Ñ Ð¿ÑогÑаммиÑованиÑ.
Ðак ÑледÑÑвие, в ÑложнÑÑ Ð²ÑÑажениÑÑ Ð½Ðµ ÑÑÐ¾Ð¸Ñ Ð¸ÑполÑзоваÑÑ ÑÑнкÑии Ñ Ð¿Ð¾Ð±Ð¾ÑнÑми ÑÑÑекÑами. ÐÑобенно опаÑно ÑаÑÑÑиÑÑваÑÑ Ð½Ð° поÑÑдок вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ побоÑнÑе ÑÑÑекÑÑ Ð² пÑедложениÑÑ WHERE и HAVING, Ñак как ÑÑи пÑÐµÐ´Ð»Ð¾Ð¶ÐµÐ½Ð¸Ñ ÑÑаÑелÑно опÑимизиÑÑÑÑÑÑ Ð¿Ñи поÑÑÑоении плана вÑполнениÑ. ÐогиÑеÑкие вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ (ÑоÑеÑÐ°Ð½Ð¸Ñ AND/OR/NOT) в ÑÑÐ¸Ñ Ð¿ÑедложениÑÑ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð²Ð¸Ð´Ð¾Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ñ Ð»ÑбÑм ÑпоÑобом, допÑÑÑимÑм законами ÐÑлевой алгебÑÑ.
Ðогда поÑÑдок вÑÑиÑÐ»ÐµÐ½Ð¸Ñ Ð²Ð°Ð¶ÐµÐ½, его можно заÑикÑиÑоваÑÑ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑии CASE (Ñм. Раздел 9.17). ÐапÑимеÑ, Ñакой ÑпоÑоб избежаÑÑ Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð° Ð½Ð¾Ð»Ñ Ð² пÑедложении WHERE ненадÑжен:
SELECT ... WHERE x > 0 AND y/x > 1.5;
ÐезопаÑнÑй ваÑианÑ:
SELECT ... WHERE CASE WHEN x > 0 THEN y/x > 1.5 ELSE false END;
ÐÑименÑÐµÐ¼Ð°Ñ Ñак конÑÑÑÑкÑÐ¸Ñ CASE заÑиÑÐ°ÐµÑ Ð²ÑÑажение Ð¾Ñ Ð¾Ð¿ÑимизаÑии, поÑÑÐ¾Ð¼Ñ Ð¸ÑполÑзоваÑÑ ÐµÑ Ð½Ñжно ÑолÑко пÑи Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи. (Рданном ÑлÑÑае бÑло Ð±Ñ Ð»ÑÑÑе ÑеÑиÑÑ Ð¿ÑоблемÑ, пеÑепиÑав ÑÑловие как y > 1.5*x.)
Ðднако, CASE не вÑегда ÑпаÑÐ°ÐµÑ Ð² подобнÑÑ ÑлÑÑаÑÑ . ÐоказаннÑй вÑÑе пÑиÑм Ð¿Ð»Ð¾Ñ Ñем, ÑÑо не пÑедоÑвÑаÑÐ°ÐµÑ Ñаннее вÑÑиÑление конÑÑанÑнÑÑ Ð¿Ð¾Ð´Ð²ÑÑажений. Ðак опиÑано в Разделе 35.6, ÑÑнкÑии и опеÑаÑоÑÑ, помеÑеннÑе как IMMUTABLE, могÑÑ Ð²ÑÑиÑлÑÑÑÑÑ Ð¿Ñи планиÑовании, а не вÑполнении запÑоÑа. ÐоÑÑÐ¾Ð¼Ñ Ð² пÑимеÑе
SELECT CASE WHEN x > 0 THEN x ELSE 1/0 END FROM tab;
, ÑкоÑее вÑего, пÑоизойдÑÑ Ð´ÐµÐ»ÐµÐ½Ð¸Ðµ на Ð½Ð¾Ð»Ñ Ð¸Ð·-за Ñого, ÑÑо планиÑовÑик попÑÑаеÑÑÑ ÑпÑоÑÑиÑÑ ÐºÐ¾Ð½ÑÑанÑное подвÑÑажение, даже еÑли во вÑÐµÑ ÑÑÑÐ¾ÐºÐ°Ñ Ð² ÑаблиÑе x > 0, а знаÑÐ¸Ñ Ð²Ð¾ вÑÐµÐ¼Ñ Ð²ÑÐ¿Ð¾Ð»Ð½ÐµÐ½Ð¸Ñ Ð²ÐµÑÐ²Ñ ELSE никогда не бÑÐ´ÐµÑ Ð²ÑполнÑÑÑÑÑ.
ХоÑÑ ÑÑÐ¾Ñ ÐºÐ¾Ð½ÐºÑеÑнÑй пÑÐ¸Ð¼ÐµÑ Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑÑÑ Ð½Ð°Ð´ÑманнÑм, Ð¿Ð¾Ñ Ð¾Ð¶Ð¸Ðµ ÑиÑÑаÑии, в коÑоÑÑÑ Ð½ÐµÑвно поÑвлÑÑÑÑÑ ÐºÐ¾Ð½ÑÑанÑÑ, могÑÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ°ÑÑ Ð¸ в запÑоÑÐ°Ñ Ð²Ð½ÑÑÑи ÑÑнкÑий, Ñак как знаÑÐµÐ½Ð¸Ñ Ð°ÑгÑменÑов ÑÑнкÑии и локалÑнÑÑ Ð¿ÐµÑеменнÑÑ Ð¿Ñи планиÑовании могÑÑ Ð±ÑÑÑ Ð·Ð°Ð¼ÐµÐ½ÐµÐ½Ñ ÐºÐ¾Ð½ÑÑанÑами. ÐоÑÑÐ¾Ð¼Ñ Ð½Ð°Ð¿ÑимеÑ, в ÑÑнкÑиÑÑ PL/pgSQL гоÑаздо безопаÑнее Ð´Ð»Ñ Ð·Ð°ÑиÑÑ Ð¾Ñ ÑиÑкованнÑÑ Ð²ÑÑиÑлений иÑполÑзоваÑÑ ÐºÐ¾Ð½ÑÑÑÑкÑÐ¸Ñ IF-THEN-ELSE, Ñем вÑÑажение CASE.
ÐÑÑ Ð¾Ð´Ð¸Ð½ подобнÑй недоÑÑаÑок ÑÑого Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð° в Ñом, ÑÑо CASE не Ð¼Ð¾Ð¶ÐµÑ Ð¿ÑедоÑвÑаÑиÑÑ Ð²ÑÑиÑление заклÑÑÑнного в нÑм агÑегаÑного вÑÑажениÑ, Ñак как агÑегаÑнÑе вÑÑÐ°Ð¶ÐµÐ½Ð¸Ñ Ð²ÑÑиÑлÑÑÑÑÑ Ð¿ÐµÑед вÑеми оÑÑалÑнÑми в ÑпиÑке SELECT или пÑедложении HAVING. ÐапÑимеÑ, в ÑледÑÑÑем запÑоÑе Ð¼Ð¾Ð¶ÐµÑ Ð²Ð¾Ð·Ð½Ð¸ÐºÐ½ÑÑÑ Ð¾Ñибка Ð´ÐµÐ»ÐµÐ½Ð¸Ñ Ð½Ð° нолÑ, неÑмоÑÑÑ Ð½Ð° Ñо, ÑÑо он вÑоде Ð±Ñ Ð·Ð°ÑиÑÑн Ð¾Ñ Ð½ÐµÑ:
SELECT CASE WHEN min(employees) > 0
THEN avg(expenses / employees)
END
FROM departments; ÐгÑегаÑнÑе ÑÑнкÑии min() и avg() вÑÑиÑлÑÑÑÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо по вÑем вÑ
однÑм ÑÑÑокам, Ñак ÑÑо еÑли в какой-Ñо ÑÑÑоке поле employees окажеÑÑÑ ÑавнÑм нÑлÑ, деление на Ð½Ð¾Ð»Ñ Ð¿ÑоизойдÑÑ ÑанÑÑе, Ñем ÑÑÐ°Ð½ÐµÑ Ð²Ð¾Ð·Ð¼Ð¾Ð¶Ð½Ñм пÑовеÑиÑÑ ÑезÑлÑÑÐ°Ñ ÑÑнкÑии min(). ÐоÑÑомÑ, ÑÑÐ¾Ð±Ñ Ð¿ÑоблемнÑе вÑ
однÑе ÑÑÑоки изнаÑалÑно не попали в агÑегаÑнÑÑ ÑÑнкÑиÑ, ÑледÑÐµÑ Ð²Ð¾ÑполÑзоваÑÑÑÑ Ð¿ÑедложениÑми WHERE или FILTER.
| ÐÑед. | ÐаÑало | След. |
| ÐекÑиÑеÑÐºÐ°Ñ ÑÑÑÑкÑÑÑа | УÑÐ¾Ð²ÐµÐ½Ñ Ð²ÑÑе | ÐÑзов ÑÑнкÑий |