34
пайдаланушы белгілі бір сақтау нүктесіне қайта оралмайтынына сенімді болса,
онда жүйе қорын босату үшін нүктені жоюға болады. Еске сақтайтын нәрсе:
жоюда немесе сақтау нүктесіне қайтарымда одан кейін анықталған барлық
сақтау нүктелері автоматты түрде жойылады. Осының бәрі транзакция
блогында жұмыс жасайды, сол себептен басқа деректер қорымен жұмыс
сеанстарында ол көрінбейді. Барлық жасалған амалдар барлығы бірден көріне
бастайды тек транзакцияны бекіткен жағдайда, ал күшін жойған амалдар
ешқашан көрінбейді. Банк деректер қорына қайтадан келіп, Алиса шотынан
100 доллар сомасын есептен шығарып, Боб шотына қосылады деп болжанады.
Және кенеттен сомасы Уоллиға ауыстыру керек болып шықты. Осы жағдайда
сақтау нүктесін қолдануға болады:
BEGIN;
UPDATE accounts SET balance = balance - 100.00
WHERE name = 'Alice';
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00
WHERE name = 'Bob';
-- қате амал... Уолли шотын қолдану
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00
WHERE name = 'Wally';
COMMIT;
Бұл мысал, әрине, ойдан шығарылған, алайда ол сақтау нүктелерін
қолдана отырып транзакция блогында командалар орындалуын қалай басқару
керектігін көрсетеді. Cонымен қатар ROLLBACK TO – бұл, толық күшін
жойып және қайта бастауды санамағанда, жүйе қателігі себебінен үзілген
жағдайда болып қалған транзакция блогының бақылауын қайтаруының
жалғыз тәсілі.
4.4 Терезелік функциялар
Терезелік функция қатарлар жиынтығын үшін есептеулер орындайды,
кейбір түрде ағымдағы қатармен байланысты. Агрегаттық фунциямен
салыстыруға болады, алайда әдіттегі агрегаттық фунциямен қарағанда,
терезелік
функцияны
қолданғанда
бірнеше
қатарлар
бір
қатаға
жинақталмайды, олар жеке тұра береді. Ал ішінде қараса, терезелік
функция,агрегаттыө сияқты, тек сұраныс нәтижесінің ағымдағы қатарына ғана
қатынасып қоймайды. Мысалыға, бөлімдегі әрбір орташа жалақылы
жұмысшыларының жалақыларынан салыстыру:
SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname)
FROM empsalary;
depname | empno | salary | avg
-----------+-------+--------+-----------------------
develop | 11 | 5200 | 5020.0000000000000000
35
develop | 7 | 4200 | 5020.0000000000000000
develop | 9 | 4500 | 5020.0000000000000000
develop | 8 | 6000 | 5020.0000000000000000
develop | 10 | 5200 | 5020.0000000000000000
personnel | 5 | 3500 | 3700.0000000000000000
personnel | 2 | 3900 | 3700.0000000000000000
sales | 3 | 4800 | 4866.6666666666666667
sales | 1 | 5000 | 4866.6666666666666667
sales | 4 | 4800 | 4866.6666666666666667
(10 rows)
Алғашқы үш баған тура empsalary кестесіден алынады, сонымен қатар
кестенің әрбір қатары үшін нәтиже қатары бар. Төртінші бағанда, ағымдағы
қатар секіліді depname мағынасы бар, барлық қатардан есептелген орташасы
орналасқан. Орташаны есептеуді негізі, агрегаттық функция деп білетін, avg
функциясы орындайды, бірақ OVER сөйлемі оны терезелік функцияға
айналдырады, өйткені ол тек берілген қатарлар жиынтығын өңдейді.
Терезелік функцияны шақыру әрдайым аты мен терезелік фунцияның
аргументтерінен кейін OVER сөйлемін қосады. OVER сөйлемі терезелік
функция арқылы өңдеуге сұраныс үшін қатарларды қалай бөлу керектігін
анықтайды. OVER сөйлемін толықтыратын PARTITION BY сөйлемі
көрсетеді: қатарларды топтар немесе бөлімдер бойынша бөлу және бірдей
мағыналарды PARTITION BY өрнегіне біріктіру керектігін. Терезелік
функция ағымдағы қатармен бір бөлімге түскен қатарлар арқылы есептеледі.
Сонымен қатар пайдаланушы OVER ішінде ORDER BY қолдану арқылы
терезелік функциямен қатарлар қай ретте өңделетінін анықтай алады. Терезе
үшін ORDER BY реті қатарлар көрсетілген ретпен сәйкес келмеуі мүмкін.
Мысалы:
SELECT depname, empno, salary,
rank() OVER (PARTITION BY depname ORDER BY salary DESC)
FROM empsalary;
depname | empno | salary | rank
-----------+-------+--------+------
develop | 8 | 6000 | 1
develop | 10 | 5200 | 2
develop | 11 | 5200 | 2
develop | 9 | 4500 | 4
develop | 7 | 4200 | 5
personnel | 2 | 3900 | 1
personnel | 5 | 3500 | 2
sales | 1 | 5000 | 1
sales | 4 | 4800 | 2
sales | 3 | 4800 | 2
(10 rows)
36
Жоғарыда көрсетілгендей, rank функциясы ағымдағы қатар бөлімінде,
ORDER BY сөйлемінің сорттауы орындалатын, әр бірегей мән үшін реттік
нөмір береді. rank функциясының параметрлері жоқ, өйткені оның
мінез
құлқы OVER сөйлемімен анықталады.
Терезелік функциямен өңделетін қатарлар, FROM сөйлемінен жасалған,
одан кейін WHERE және GROUP BY арқылы фильтрация мен топтаудан
өткен, және, мүмкін, HAVING шартынан да өткен «виртуалды кестелер»
ретінде алынады. Мысалы, WHERE шартын бұзғаны үшін фильтрацияланған
қатар терезелік функция үшін көрінбейді. Терезелік функция әр түрлі OVER
сөйлемдері арқылы мәліметтерді әр қалай бөледі, бірақ олардың бәрі осы
виртуалды кестенің бірдей қатар жиынтығын өңдейді. Қатар реті маңызды
болмаса ORDER BY жазу қажет еместігі айтылып қойған. Сол сияқты
PARTITION BY жазу қажет емес, осы жағдайда барлық қатаралар болатын тек
бір бөлім болады. Терезелік фукциялармен байланысты тағы бір маңызды
түсінік бар: әрбір қатар үшін терезе жақтауы деп аталатын бөлімінде
қатарлар жиыны бар. Әдепкі бойынша, ORDER BY белгілеуімен жақтау
құрамы: бөлім бастауынан ағымдағы қатарға дейінгі барлық қатарлар және
ORDER BY ағымдағы мәніне тең қатарлар. ORDER BY болмаса жақтау,
әдепкі бойынша, бөлімдегі барлық қатарлардан тұрады.
sum қолдану мысалы:
SELECT salary, sum(salary) OVER () FROM empsalary;
salary | sum
--------+-------
5200 | 47100
5000 | 47100
3500 | 47100
4800 | 47100
3900 | 47100
4200 | 47100
4500 | 47100
4800 | 47100
6000 | 47100
5200 | 47100
(10 rows)
Осы мысалда ORDER BY сөйлемінде нұсқаулар болмағандықтан, терезе
жақтауы бөлімнің барлық қатары болады, ал ол, өз кезегінде, PARTITION BY
сөйлемінсіз кестенің барлық қатарларын қосады; басқаша айтқанда, барлық
кесте бойынша сомасы есептеледі және басқа нәтижелер алынады. Алайда
ORDER BY қосылса, мүлдем басқа нәтижелер шығады:
SELECT salary, sum(salary) OVER (ORDER BY salary) FROM empsalary;
salary | sum
--------+-------
3500 | 3500
3900 | 7400
Достарыңызбен бөлісу: |