Přidání názvů sloupců do selectu v SQL Developer

Do SQL selektu je někdy nutné (místo *) nadefinovat sloupce, které se mají vracet. Těchto sloupců může být docela hodně a jejich vypisování je zdlouhavé a náchylné na chyby. Oracle SQL Developer tuto práci zjednodušuje. Napište si select.

select * from SYS.ALL_TAB_COLUMNS where column_name like 'ID'

Kurzor umístěte do názvu tabulky (v tomto případě ALL_TAB_COLUMNS). Klikněte Shift + F4 (nebo pravým tlačítkem myši a „Popup Describe“). Chvíli počkejte a otevře se vám okno. V záložce „Columns“ vyberte požadované sloupce (pomocí Shift nebo Ctrl).

oracle_sql_developer_adding_column_names

Hvězdičku ze selektu smažte a na její místo myší přetáhněte označené sloupce. Názvy sloupců, oddělené čárkami, se vloží do selektu.

select TABLE_NAME,COLUMN_NAME,DATA_TYPE,COLUMN_ID from SYS.ALL_TAB_COLUMNS where column_name like 'ID'

Zdroj: thatjeffsmith.com/…/more-column-copy-tricks-in-oracle-sql-developer/

Nastavení zobrazování okna s doplňováním kódu v SQL Developer

Oracle SQL Developer umožňuje zobrazování vyskakovacího okna s možnostmi pro doplňování kódu při psaní SQL. Stručně řečeno umožňuje zobrazování nápovědy při psaní. Okno se může zobrazovat hned při psaní nebo po stisknutí Ctrl + mezerník.

oracle_sql_developer_popup_window_with_code_completion

To, zda se má okno zobrazovat, rychlost jeho zobrazení nebo pro kolik záznamů maximálně se má zobrazit, se nastaví v Tools -> Preferences -> Code Editor -> Completion Insight.

oracle_sql_developer_popup_window_with_code_completion_02

Pokud vás vyskakovací okno obtěžuje, můžete Auto-Popup vypnout a nápovědu si zobrazit pomocí Ctrl + mezerník jen když budete potřebovat.

ROWNUM v Oracle

ROWNUM není skutečný sloupec, ale pseudo sloupec, který je k dispozici v dotazu. ROWNUM je číslo od jedničky po N, kde N je počet záznamů vrácených dotazem a toto číslo je přidáno záznamu ještě předtím, než proběhne část ORDER BY. ROWNUM je pouze dočasné číslo. ROWNUM je navýšeno teprve poté, co je přiřazeno záznamu a vyhodnocena podmínka v WHERE části.

select * from table_name where rownum > 1

Nevrátí žádný záznam. První zázname má ROWNUM 1. Vyhodnocení WHERE ROWNUM > 1 je tedy false. ROWNUM se nenavýší a tím pádem tato podmínka nebude nikdy splněna.

select * from table_name where rownum >= 1

Vrátí všechny záznamy.

select * from table_name where rownum < 5

Vrátí první 4 záznamy.

select t.*, rownum from table_name t order by t.column_name

Nejdříve přiřadí ROWNUM jednotlivým řádkům a teprve poté seřadí výstup. Je pravděpodobné, že ROWNUM budou rozházená a případná podmínka WHERE ROWNUM < cislo by vrátila sice správný počet záznamů, ale neseřazeně. Řešením je následující select.

select rownum, t.* from (
 select * from table_name order by column_name) t
where rownum <= 5

Vrátí prvních pět výsledků dle řazení.

Pomocí ROWNUM je možné výsledek dotazu stránkovat, avšak je třeba použít ještě jeden select.

select * from (
  select rownum as cisla_radku, t.* from (
    select * from table_name order by column_name) t
  )
where cisla_radku between 10 and 15;

Vrátí desátý až patnáctý záznam (dle řazení) včetně. Podmínku WHERE je možné samozřejmě použít i ve vnořeném selectu.

select * from (
  select rownum as cisla_radku, t.* from (
    select * 
    from table_name
    where nejaka_podminka 
    order by column_name) t
  )
where cisla_radku between 10 and 15;

Zdroje:

Pole v PostgreSQL

PostgreSQL umožňuje nastavit sloupec jako několika rozměrné pole. V tomto příspěvku ukážu vytvoření sloupců, které budou obsahovat jednorozměrné pole.

Vytvoření tabulky favorite a naplnění daty.

create table favorite (
	id serial not null,
	person_id int not null,
	favorite_names varchar(15)[],
	favorite_numbers int[],

	primary key(id)
);

insert into favorite (person_id, favorite_names, favorite_numbers) values
	(4, '{"Petr", "Anna"}', '{7, 11, 23, 999}'),
	(5, array['Alena'], '{1}'),
	(7, '{"Marie", "Aneta", "Petr"}', array[17, 24]),
	(9, array['Pankrác', 'Servác', 'Bonifác'], array[111, 13, 9, 2]);

Třetí sloupec obsahuje pole řetězců a čtvrtý sloupec pole celých čísel. Pole je možné vytvořit pomocí složených závorek a nebo pomocí konstruktoru ARRAY.


Zobrazení tabulky favorite.

select * from favorite;

postgresql_arrays_01


Vypsání záznamů, které mají první záznam v poli favorite_numbers větší, než druhý záznam.

select * from favorite where favorite_numbers[1] > favorite_numbers[2];

Vypíše třetí oblíbené jméno a druhé oblíbené číslo pro každý záznam.

select favorite_names[3] as "Třetí oblíbené jméno", favorite_numbers[2] as "Druhé oblíbené číslo" from favorite;

postgresql_arrays_02


Zobrazí pro každý záznam počet položek v poli favorite_names (počet oblíbených jmen).

select array_length(favorite_names, 1) as pocet_oblibenych_jmen from favorite;

Zdroje:

View tables v PostgreSQL

Databáze v PostgreSQL obsahuje informační schéma (information_schema) ve kterém jsou různé pohledy (view), ze kterých lze získat informace o objektech v databázi. View information_schema.tables obsahuje informace o všech tabulkách (tables) a pohledech (views) v aktuální databázi.

select * from information_schema.tables;

Výpis celého pohledu information_schema.tables.

select * from information_schema.tables where table_schema = 'public';

Výpis všech informací o tabulkách a pohledech ve schématu public.

select * from information_schema.tables where table_schema = 'nazev_schematu';

Výpis všech informací o tabulkách a pohledech ve schématu s názvem nazev_schematu.

select table_name from information_schema.tables where table_type = 'VIEW';

Výpis všech pohledů (názvů pohledů) v aktuální databázi.

select table_name from information_schema.tables where table_type = 'BASE TABLE';

Výpis všech tabulek (názvů tabulek) v aktuální databázi.

Jak najít tabulky obsahující určité sloupce v PostgreSQL

Může se stát, že víte název sloupce, ale nevíte, v jaké tabulce se tento sloupec nachází. Informace o objektech databáze lze v PostgreSQL nalézt ve schématu information_schema.

Informační schéma (information schema) je množina pohledů (views), které obsahují informace o objektech v databázi. Informace o sloupcích lze nalézt v information_schema.columns view. Zdroj: postgresql.org/…/information-schema.html

Následující select vrátí názvy tabulek, které obsahují sloupce s názvem nazev_sloupce.

select table_name from information_schema.columns where column_name like 'nazev_sloupce'

Daný pohled (information_schema.columns) obsahuje řadu dalších informací např. datový typ sloupce.

Zrádný LEFT JOIN

V SQL je JOIN klauzule používána pro spojení tabulek. Klauzule LEFT JOIN spojí všechny záznamy z tabulky uvedené nalevo od klauzule se záznamy v tabulce uvedené napravo.

SELECT * FROM tabulka_jedna LEFT JOIN tabulka_dve

Zrádností LEFT JOINu (to samé platí i pro RIGHT JOIN) je to, že vezme všechny záznamy z levé tabulky a přiřadí je k (spojí je s) záznamům v pravé tabulce. Pokud ale v pravé tabulce není záznam, bude sloupec obsahovat null. Takhle to vypadá zřejmě, pojďme se ale podívat na následující příklad (v PostgreSQL).

Vytvoříme si schéma ZLJ (Zrádný Left Join) a v něm si vytvoříme tři tabulky. Tabulka USER bude obsahovat údaje o uživateli jako je jeho id, číslo, jméno. Tabulku AUTH_TYPE bude číselník s typy autorizací (sms, pin, heslo). Jako poslední vytvoříme tabulku AUTHENTCATION, která bude uchovávat údaje týkající se authentikace (typ, kdy byla vytvořena,) a bude provázána s tabulkou USER pomocí cizího klíče. Tabulky si rovnou naplníme daty.

DROP SCHEMA IF EXISTS ZLJ CASCADE;
CREATE SCHEMA ZLJ;

CREATE TABLE ZLJ.USER (
	user_id	serial not null,
	user_number varchar(10) not null,
	username varchar(10) not null,

	primary key(user_id)
);

CREATE TABLE ZLJ.AUTH_TYPE (
	auth_type_id serial not null,
	type varchar(10) not null,

	primary key(auth_type_id)
);

CREATE TABLE ZLJ.AUTHENTICATION (
	authentication_id serial not null,
	user_id int not null,
	auth_type_id int not null,
	created timestamp not null,

	primary key(authentication_id),
	foreign key(user_id) references ZLJ.USER(user_id),
	foreign key(auth_type_id) references ZLJ.AUTH_TYPE(auth_type_id)
);

INSERT INTO ZLJ.USER (user_number, username) VALUES
	('9954258641', 'fnovotny'),
	('9865662384', 'franta03'),
	('9932652322', 'mariem');

INSERT INTO ZLJ.AUTH_TYPE (type) VALUES
	('pin'),
	('sms'),
	('password');

INSERT INTO ZLJ.AUTHENTICATION (user_id, auth_type_id, created) VALUES
	(1, 2, '2016-01-05 21:11:58'),
	(3, 3, '2016-01-05 22:03:17');

Všimněte si jedné věci. Všechny sloupce mají definované omezení NOT NULL. To znamená, že do každého sloupce záznamu je nutné vložit hodnotu. Neexistuje sloupec, ve kterém by mohla být NULL hodnota.

Naši databázi voláme z nějaké aplikace. Tato aplikace požaduje následující údaje: authentication_id (id záznamu v tabulce AUTHENTICATION) a auth_type_id (foreign key na záznam v číselníku). Tyto údaje potřebuje pro určitého uživatele. Jelikož chceme mít ve výsledku obsaženy všechny uživatele, použijem LEFT JOIN.

SELECT authentication_id, auth_type_id 
FROM 
ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)
WHERE user_number = ?

Za otazník se v prepared statementu dosadí user_number. Jelikož mají všechny sloupce omezení NOT NULL, vždy dostaneme nějakou hodnotu. Chyba. Aplikace začne občas padat. Přesněji řečeno začne padat v momentě, kdy se pokusíme v tabulce AUTH_TYPE dohledat záznam type dle auth_type_id, které získáme  z předchozího selectu. Pokud totiž budeme hledat záznam auth_type_id pro user_number 9865662384, dostaneme NULL.

Dotaz:

SELECT * 
FROM 
ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)

Výsledek:

postgresql_zradny_left_join

Dotaz:

select * from 
	(SELECT * FROM ZLJ.USER LEFT JOIN ZLJ.AUTHENTICATION ON (ZLJ.USER.user_id = ZLJ.AUTHENTICATION.user_id)) as SEL 
where auth_type_id is null;

Vrátí záznamy, které mají ve sloupci auth_type_id NULL.

postgresql_zradny_left_join_02