Vienkāršs SQL Select teikums

Decembris 28, 2007

SELECT teikums

Pārējos rakstus var lasīt SQL pamatos.

SQL Select teikums ir pats izplatītākais SQL teikums un veids kā dabūt ārā datus no datubāzes jūsu programmā, klienta rīkā vai vienalga kur citur. Praktiski visi dati, kur apakšā dziļumā sēž datubāze un jums kaut ko rāda uz ekrāna no šīs datubāzes, ir iegūti izmantojot tādu vai citādu Select teikumu.

Sākumā nedaudz teorija un pāris termini no relāciju algebras.
Iedomājamies tabulu datubāzē, kuru grafiski var attēlot šādi:

       
       
       
       


Tādā gadījumā Projekcija (Projection) ir kolonu izvēle, kuras mums ir nepieciešamas no tabulas.
Grafiski tas izskatās šādi:

       
       
       
       


Atlase (Selection) ir ierakstu izvēle, kuri mums ir nepieciešami no tabulas.
Grafiski tas izskatās šādi:

       
       
       
       

Protams, vispārīgā gadījumā vienā vaicājumā var izmantot gan Projekciju, gan Atlasi, gan citas operācijas, tas viss ir atkarīgs no prasībām un konkrētās nepieciešamības.
Vienkārša Select teikuma (šis ir mans absolūti brīvs un voluntārs termins, tas nav nekas tāds vispārpieņemts) galvenās sastāvdaļas ir šādas:

SELECT <atlases saraksts>
FROM <tabula>
WHERE <nosacījumi>
GROUP BY <grupēšanas izteiksme>
HAVING <nosacījumi>
ORDER BY <kārtošanas izteiksme>

Tagad sīkāk par katru teikuma sadaļu atsevišķi.

SELECT <atlases saraksts>

Bez šī atslēgas vārda nekas nenotiek. Tiesa gan tas var arī nebūt pirmais SELECT teikumā, jo SELECT teikums vispārīgi sākas ar vaicājuma sadalīšanas (query factoring) jeb tabulas kopējās izteiksmes (common table expression) klauzu, t.i. atslēgvārdu WITH. Atlases saraksts nosaka izvēlētās kolonas un atbilst Projekcijai, kas paskaidrota un vizuāli redzama augstāk.

  • <atlases sarakstā> raksta konstantes, izteiksmes un pats galvenais – atlasāmās kolonas, kuras atdala ar komatu.
  • DISTINCT – izmantojot atslēgas vārdu DISTINCT var atlasīt tikai unikālās vērtības.
  • * – Zvaigznītes “*” simbolu var lietot, kā aizstājēju visām kolonām.
  • kolonām var piešķirt citu vārdu izmantojot atslēgvārdu AS vai vienkārši jauno vārdu rakstot aiz pauzes.

FROM <tabula>

Šeit jau sākās pirmās datubāzu atšķirības. Dažās datubāzēs (piemēram, Oracle) šī klauza ir obligāta, dažās (piemēram, MSSQL), ja tiek atlasītas tikai konstantes un izteiksmes, bez tabulu kolonu argumentiem, tad bez šīs klauzas var iztikt, piemēram, vienkārši rakstot
SELECT ‘konstante’

  • <tabula> – raksta tabulas nosaukumu. Tabulai var piešķirt citu nosaukumu gluži tāpat kā kolonai, bet, piemēram, Oraclē AS atslēgas vārds nedrīkst būt.

Daži vaicājumu piemēri. Tabulas definīcija un tās dati ir šādi:

CREATE TABLE personas (
prs_personas_kods VARCHAR2(11) NOT NULL PRIMARY KEY,
prs_vards VARCHAR2(40),
prs_uzvards VARCHAR2(40));
INSERT INTO personas VALUES ('11111112345', 'JĀNIS', 'BĒRZIŅŠ');
INSERT INTO personas VALUES ('12121212345', 'PĒTERIS', 'SŪNIŅŠ');
INSERT INTO personas VALUES ('13131312345', 'RŪDIS', 'BĒRZIŅŠ');
COMMIT;
Piemērs 1. Atlasa konstanti, vārda garumu un vārdu no tabulas.
SQL> SELECT 1, length(prs_vards), prs_vards
  2  FROM personas;
         1 LENGTH(PRS_VARDS) PRS_VARDS
---------- ----------------- ---------------
         1                 5 JĀNIS
         1                 7 PĒTERIS
         1                 5 RŪDIS
Piemērs 2. Atlasa unikālos uzvārdus no tabulas.
SQL> SELECT DISTINCT prs_uzvards FROM personas;
PRS_UZVARDS
----------------------------------------
SŪNIŅŠ
BĒRZIŅŠ
Piemērs 3. Atlasa konstanti un visus laukus no tabulas izmantojot aizstājējvārdu tabulai un zvaigznītes simbolu.
SQL> SELECT 1, p.* FROM personas p;
         1 PRS_PERSONA PRS_VARDS          PRS_UZVARDS
---------- ----------- ------------------ -------------
         1 11111112345 JĀNIS              BĒRZIŅŠ
         1 12121212345 PĒTERIS            SŪNIŅŠ
         1 13131312345 RŪDIS              BĒRZIŅŠ
Piemērs 4. Atlasa personas kodu un uzvārdu no tabulas izmantojot kolonu aizstājējvārdus ar un bez atslēgvārda AS.
SQL> SELECT prs_personas_kods AS pk, prs_uzvards uzvārds
  2  FROM personas;
PK          UZVĀRDS
----------- ----------------------------------------
11111112345 BĒRZIŅŠ
12121212345 SŪNIŅŠ
13131312345 BĒRZIŅŠ

WHERE <nosacījumi>

Šī klauza, kā jau to var redzēt no iepriekšējiem piemēriem, ir neobligāta. Tās uzdevums ir ierobežot atlasāmo datu kopu – tiek atlasīti tikai tie dati, kas atbilst WHERE klauzas nosacījumiem, t.i, kur nosacījumu izpildes rezultāts ir Patiess (True), nevis Aplams (False) vai Null. Ja WHERE klauzas nav, tad atlasa visus ierakstus no tabulas, kas ir minēta FROM klauzā. Nosacījumus var kombinēt izmantojot loģiskos operatorus AND, OR, NOT. Šī klauza nodrošina Atlases implementēšanu, kas paskaidrota un vizuāli redzama augstāk.

Daži piemēri:

Piemērs 5. Atlasa visas kolonas, kam kolona vārds ir JĀNIS.
SQL> SELECT * FROM personas
  2  WHERE prs_vards = 'JĀNIS';
PRS_PERSONA PRS_VARDS               PRS_UZVARDS
----------- ----------------------- -----------------------------------
11111112345 JĀNIS                   BĒRZIŅŠ
Piemērs 6. Atlasa vārdu no tabulas, kur vārda garums ir 5 simboli.
SQL> SELECT prs_vards FROM personas
 2  WHERE length(prs_vards) = 5;
PRS_VARDS
------------------------------------
JĀNIS
RŪDIS

GROUP BY <grupēšanas izteiksme>

Ja tiek izmantota šī klauza, tad vaicājums atgriež datus, kas ir grupēti pa kādām kolonām vai izteiksmēm no šīm kolonām. Parasti līdz ar grupētām kolonām tiek izmantota viena vai vairākas grupēšanas funkcijas. Ja kāda no grupēšanā izmantotajām kolonām ir NULL, tad tā tiek uzskatīta kā atsevišķa rindiņa un visas šādas kolonas tiek uzskatītas kā līdzvērtīgas, t.i., grupētas kopā.
Biežāk izmantojamās grupēšanas funkcijas ir:

  • count(izteiksme) – ierakstu skaits grupā, kur izteiksme atgriež NE NULL rezultātu – parasti vienkāršai saskaitīšanai izmanto count(*).
  • sum(izteiksme) – summa grupai.
  • min(izteiksme) – minimālā vērtība grupā.
  • max(izteiksme) – maksimālā vērtība grupā.
  • avg(izteiksme) – vidējā vērtība grupā.

Daži piemēri:

Piemērs 7. Atlasa tabulas ierakstu skaitu.
SQL> SELECT count(*) FROM personas;
COUNT(*)
----------
         3
Piemērs 8. Atlasa uzvārdus un to izmantošanas reižu skaitu tabulā.
SQL> SELECT count(*), prs_uzvards
  2  FROM personas
  3  GROUP BY prs_uzvards;
COUNT(*)   PRS_UZVARDS
---------- ---------------------------------
         1 SŪNIŅŠ
         2 BĒRZIŅŠ
Piemērs 9. Atlasa visu vārdu garumu summu.
SQL> SELECT sum(length(prs_vards)) FROM personas;
SUM(LENGTH(PRS_VARDS))
----------------------
                    17

HAVING <nosacījumi>

Lai uzliktu nosacījumus tālāk uz jau sagrupētajiem datiem, var izmantot HAVING klauzu. Tā tiek pielietota vaicājumam pēc GROUP BY klauzas izpildes. Ja šī klauza netiek lietota, tad vaicājums atgriež visus grupētos datus, kas ir iegūti GROUP BY rezultātā. Gluži tāpat kā WHERE klauzai arī šeit, protams, nosacījumus ir iespējams kombinēt izmantojot loģiskos operatorus.
Piemērs:

Piemērs 10. Atlasa uzvārdus un to izmantošanas reižu skaitu tabulā, ja to izmantošanas reižu skaits ir lielāks nekā 1.
SQL> SELECT count(*), prs_uzvards
  2  FROM personas
  3  GROUP BY prs_uzvards
  4  HAVING count(*) > 1
  5  /
COUNT(*)   PRS_UZVARDS
---------- ----------------------
         2 BĒRZIŅŠ

ORDER BY <kārtošanas izteiksme>

Ar šo izteiksmi, kā to vēsta jau pats nosaukums, dati tiek sakārtoti noteiktā secībā.

  • <kārtošanas izteiksme> var sastāvēt no vienas vai vairākām gan atlasītajām, gan neatlasītājām kolonām.
  • Atlasītās kolonas var aizvietot arī ar to kārtas numuriem atlases sarakstā, tomēr ja kolonu skaits ir liels, tad ir jāpārdomā vai vaicājums tādā gadījumā būs lasāms un saprotams.
  • Katru atsevišķo izteiksmi vai kolonu var kārtot augošā (noklusētais variants) vai dilstošā secībā. To norāda ar atslēgas vārdu ASC (augošā secībā) vai DESC (dilstošā secībā) aiz katras konkrētās izteiksmes. Kā jau teikts ASC var nerakstīt.

Daži piemēri.

Piemērs 11. Atlasa visas kolonas un ierakstus no tabulas tos sakārtojot pēc uzvārda un vārda.
SQL> SELECT * FROM personas
  2  ORDER BY prs_uzvards, prs_vards;
PRS_PERSONA PRS_VARDS                                PRS_UZVARDS
----------- ---------------------------------------- -------------
11111112345 JĀNIS                                    BĒRZIŅŠ
13131312345 RŪDIS                                    BĒRZIŅŠ
12121212345 PĒTERIS                                  SŪNIŅŠ
Piemērs 12. Atlasa personas kodu no tabulas sākārtojot pēc atlases sarakstā neesošām kolonām uzvārda dilstošā secība un vārda augošā secībā.
SQL> SELECT prs_personas_kods pk FROM personas
  2  ORDER BY prs_uzvards desc, prs_vards;
PK
-----------
12121212345
11111112345
13131312345

Dažas piezīmes ar uzturamību, ātrdarbību un funkcionalitāti

  • Izvēlieties savas SQL objektu nosaukšanas un SQL teikumu rakstīšanas vadlīnijas. Un pielietojiet tās. Ir ļoti grūti saprast SQL teikumus, kas ir rakstīti haotiski, tiek dinamiski kaut kādā haotiskā veidā uzkonstruēti kodā vai paslēpti tajā kā teksta mainīgie, kas nekādi neizceļas uz pārējo mainīgo vērtību piešķiršanas fona.
  • Ar uzmanību jālieto *. Laika gaitā tabulu struktūra mēdz mainīties un jāsaprot, ka pieliekot klāt kolonu, * attēlos arī to. No ātrdarbības viedokļa jācenšas atlasīt tikai tās kolonas, kas patiesi ir nepieciešams, nevis visas, kaut gan tā it kā ir ērtāk.
  • DISTINCT jālieto tikai tad, ja patiešām tas ir nepieciešams. Unikālo vērtību atrašana prasa liekus resursus, laiku un maldina uzturētājus, ja patiesībā visas vērtības jau tāpat ir unikālas.
  • Kolonām vai tabulām piešķirot aizstājvārdu (alias) arī būtu jāseko kaut kādām saprātīgām vadlīnijām, jo tabulas aizstājot ar a, b, c un kolonas ar col1, col2 rezultātā var iegūt absolūti nelasāmu SQL teikumu.
  • Rakstot WHERE klauzu, vienmēr jādomā par potenciālo ātrdarbību, jo tā ir primārā vieta, kas iespaidos jūsu vaicājuma izpildes ātrumu. Vai jūsu vaicājums vispār atlasa to, ko vajag? Vai jūsu vaicājums vienmēr skatīs cauri visu tabulu? Vai uz atlases kritērijos biežāk izmantotajām kolonām ir indeksi? Vai atlases nosacījumi ir tādi, ka indeksus ir iespējams izmantot? Piemēram, datu tipu (ne)sakritība; daži salīdzināšanas operatori (<>, =>, =<); LIKE ‘%teksta fragments%’; kritēriji nevis uz kolonām pa tiešo, bet izmantojot funkcijas ir tikai dažas no šaubīgajām lietām.
  • Jāsaprot, ka GROUP BY, lai gan parasti atgriež relatīvi mazu ierakstu skaitu, vairumā gadījumu skanē cauri visu tabulu vai vismaz lielu daļu no tās (atbilstoši WHERE klauzas nosacījumiem, protams). Attiecīgi jāsaprot, ka, lai iegūtu skaitu, summu vai jebko tamlīdzīgu, VISI atbilstošie ieraksti ir arī jāatrod un jāizpilda prasītā grupēšana funkcija.
  • Ja dati ir nepieciešami noteiktā kārtībā, tad vienmēr ir jālieto ORDER BY klauza. SQL standarts nosaka, ka bez šīs klauzas atgrieztā kopa ir sakārtojumā, kas ir implementācijas specifisks. Tas nozīmē, ka sakārtojums ir patvaļīgs un piedevām var mainīties no vienas un tās pašas datubāzes versijas uz versiju. Piemēram Oracle negarantē nekādu sakārtojumu bez ORDER BY klauzas un izpildot vienreiz vaicājumu tas var būt vienā sakārtojumā, bet nākošajā reizē pavisam citā sakārtojumā.

Tālākā lasāmviela

Pilna SELECT sintakses dokumentācija:


Galvenie datubāzu objekti un jēdzieni

Decembris 3, 2007

1. Datubāze (Database)

Datu/informācijas kopums, kas tiek uzskatīts kā viena loģiska vienība. Kā jau tas parasti – pats pirmais, kas darbā ar datubāzēm jāatceras - tās ir dažādas. Lai gan formālajā definīcijā īpašas atšķirības nav, tomēr, piemēram, Oraclē datubāze sastāv no loģiskās un fiziskās struktūras, tas ir viss failu kopums, kas pastāvīgi glabājas serverī un ko instance (procesi un atmiņa uz servera) startējoties atver. Savukārt, SQL Serverī Datubāze ir vairāk kā viens loģisks lietotājs, kam pieder noteikti objekti, piemēram, tabulas un skatījumi un Oraclē, tam atbilst jēdziens shēma (Schema).

2. Tabulas (Table)

Tabulas ir relāciju datubāzes pamatvienība, kurā glabā datus. Katrai tabulai ir nosaukums. Katrai tabulai ir fiksēts skaits kolonu (vismaz viena) un parasti neierobežots skaits ierakstu. Tabulu piemēri – Organizācijas, Personas, Adreses.

3. Kolonas (Column)

Kolona ir kādas tabulas vai skatījuma atribūts, kam ir savs nosaukums un noteikts datu tips. Vienā kolonā parasti tiek glabāti dati, kuri pēc sava mērķa un sūtības ir vieni un tie paši. Kolonu piemēri Personu tabulai – Vārds, Uzvārds, Personas kods.

4. Ieraksti (Row)

Ieraksts ir loģiski saistīta datu kopa tabulā, kur visi ieraksti sastāv no vienām un tām pašām kolonām. Ieraksta piemērs Personas tabulā Jānis, Bērziņš, 01010112345.

5. Skatījumi (View)

Skatījums ir virtuāla vai loģiska tabula datubāzē, kas nesatur datus, bet ir balstīts uz vaicājumu. Izmainot datus tabulā, attiecīgi mainās arī dati skatījumā. Skatījumus veido dažādu iemeslu dēļ, no kuriem populārākie varētu būt, lai nebūtu jāraksta vienmēr bieži izmantots vaicājums, bet tā vietā izmantot skatījumu, un ierobežot pieejas tiesības lietotājiem izmantojot skatījumus, kas ierobežo pieejamo datu kopu. Skatījuma piemērs Personas adreses, kas kombinē (join) datus no Personu un Adrešu tabulām.

6. Indeksi (Index)

Indeksi ir datu struktūras, kuru primārais uzdevums ir ātri atlasīt noteiktus datus tabulā. Indeksi parasti tiek veidoti uz vienas vai vairākām kolonām tabulā. Gluži kā terminu indekss grāmatā, kas norāda kurā(-s) lappusē(-s) ir atrodams noteiktais termins, tā arī datubāzē indekss norāda kurā ierakstā ir atrodama Persona ar Vārdu Jānis. Bez indeksa nāktos skanēt cauri visu tabulu. Piemērs – indekss uz kolonu Vārds tabulā Persona, ļauj ātri atrast visu personu ierakstus ar noteiktu vārdu. Vairāk par indeksiem, to uzbūvi un pielietojumu lasīt šeit.

7. Ierobežojumi (Constraint)

Ierobežojumi nodrošina biznesa prasību un datu integritātes īstenošanu datubāzē. Ierobežojumi ir vairāku veidu, parastākie ir šādi:
Nav null (Not null) – pārbaudes ierobežojuma speciālgadījums, kolonai ir jābūt netukšai.
Primārā atslēga (Primary key) – unikāls veids kā identificēt ierakstu, sastāv no vienas vai vairākām kolonām. Piemēram, Personas kods Personai.
Unikālā atslēga (Unique key) – atšķirībā no Primārās atslēgas kolona var būt tukša, bet visām, netukšajām vērtībām (vērtību kombinācijām) ir jābūt unikālām, piemēram, Vārds, Uzvārds, Dzimšanas datums un Dzimšanas vieta personai.
Ārējās atslēgas (Foreign key) – vērtību kopa ir ierobežota ar citas tabulas primārās vai unikālās atslēgas vērtību kopu, piemēram, adreses identifikators Personu tabulā, kas norāda personas adresi.
Pārbaudes ierobežojums (Check constraint) – vienai vai vairākām kolonām jāatbilst noteiktai loģiskai izteiksmei, piemēram, personas dzimšanas datums nedrīkst būt mazāks kā 1900. gada 1. janvāris.

8. Saglabātās procedūras, funkcijas, pakotnes (Stored procedure, function, package)

SQL teikumu un procedurālu elementu (nosacījumi, cikli, mainīgie, to definēšana, vērtību piešķiršana utt.) kopums, kas tiek saglabāts datubāzē un kam tiek piešķirts noteikts nosaukums. Tādējādi šādu saglabātu procedūru ir iespējams izpildīt datubāzē to izsaucot no jebkura klienta. Saglabātas procedūras piemērs – mēnešalgas aprēķins uzņēmuma darbiniekam balstoties uz mēneša laikā ievadīto informāciju par nostrādātajām stundām.

9. Trigeri (Trigger)

SQL teikumu un procedurālu elementu kopums, kas tiek automātiski izpildīts, pēc vai pirms kāda noteikta notikuma. Notikumi pamatā ir divu veidu – datu manipulācijas valodas teikums (Insert, Update, Delete), kas veic izmaiņas noteiktā tabulā vai Datu definēšanas valodas teikums. Dažādās datubāzēs iespējamie trigeru veidi ir dažādi. Trigera piemērs – katrai rindiņai, kas tiek pievienota tabulai, automātiski atsevišķā kolonā tiek saglabāts lietotāja vārds, kas to izdarījis.

10. Transakcijas (Transaction)

Izmaiņu kopums datubāzē, kur tām ir jāatbilst četrām (ACID, no angļu valodas pazīmju pirmajiem burtiem) pazīmēm:
1) Atomitāte, atomaritāte (Atomicity)  – visām izmaiņām ir vai nu jātiek izpildītām, vai arī jātiek atceltām, piemēram, naudas pārskaitīšana no viena konta otrā nozīmē naudas izņemšanu no pirmā konta un naudas pieskaitīšanu otrajam kontam, ja tiks izpildīta tikai viena no šīm darbībām, tad iegūtais rezultāts būs nekorekts.
2) Konsistence, saskanīgums (Consistency) – transakcijas sākumā un beigās netiek pārkāpti ierobežojumi, piemēram, ja konta stāvoklim vienmēr jābūt lielākam par 0), tad naudas pārskaitījums, kas konta stāvokli pazeminās zem nulles, netiks pieļauts.
3) Izolētība (Isolation) – transakcijas izmaiņas nav redzamas citās operācijās, piemēram, naudas pārskaitīšanas laikā citi lietotāji nekad neredzēs stāvokli, kad nauda ir abos kontos, vai tieši otrādi tā nav nevienā kontā.
4) Ilgstamība, paliekamība (Durability) – garantija, ka tiklīdz, kā transakcija ir pabeigta, tās izmaiņas netiks zaudētas pat datubāzes avārijas rezultātā.

11. Tiesības (Permission, Privilege)

Atļauja veikt noteiktu operāciju. Pamatā dalās divās daļās – tiesības veikt noteiktu darbību datubāzē, piemēram, izveidot tabulu, vai tiesības veikt noteiktas datu manipulācijas ar esošiem objektiem, piemēram, dot lasīšanas tiesības uz tabulu Personas citiem datubāzes lietotājiem.

12. Lomas (Role)

Tiesību kopums, kam piešķirts vārds.

13. Bloķēšana (Locking)

Tiesību aizliegums vienlaicīgi darboties ar vieniem un tiem pašiem ierakstiem. Parasti darbības dalās divās daļās – lasīšanā (DML Select teikums) un rakstīšanā (DML Insert, Delete, Update). Tas par ko parasti interesējas vai datubāzes lasītāji bloķē rakstītājus un rakstītāji bloķē lasītājus, t.i. vai vienas tabulas rindu vienlaicīgi var viens vai vairāki lietotāji lasīt un viens lietotājs rakstīt. Parasti, lasītāji citus lasītājus nebloķē, un rakstītāji savukārt citus rakstītājus bloķē, t.i. vienlaicīgi vienas tabulas vienu rindu var lasīt no vairākiem pieslēgumiem, bet rakstīt var tikai viens. Bez tam mehānisms cik lielā līmenī notiek bloķēšana arī ir atšķirīgs (ierakstu, datu bāzes bloku, tabulu).

14. Strukturēta vaicājumu valoda (SQL)

Īss apraksts paskaidrots šeit.

SQL elementu un konstrukciju indekss ir šeit.

15. Datu manipulēšanas, definēšanas, kontroles un transakciju kontroles valoda (DML, DDL, DCL, TCl)

Paskaidrota šeit.

16. Tālākā lasāmviela