19 Mayıs 2019 Pazar

GROUP BY + HAVING

Giriş
Having 'in uygulanma sırası şöyle.
FROM -> WHERE -> GROUP BY -> HAVING -> SELECT -> ORDER BY
Açıklaması şöyle.
The HAVING statement is used to filter data after it has been grouped by the GROUP BY statement. 
Açıklaması şöyle.
The HAVING clause always applies to aggregated fields, which is all remaining columns post-aggregation.
Şeklen şöyle

COUNT
Örnek - count > 1
Elimizde şöyle bir tablo olsun.. 
ID_a | ID_b | VAL
1    | 1    | 'a'
1    | 2    | 'b'
1    | 3    | 'a'
2    | 1    | 'a'
2    | 2    | 'c'
3    | 1    | 'c'
4    | 1    | 'c'
5    | 1    | 'b'
6    | 1    | 'e'
Aynı ID_a değerine sahip birden fazla olan ve farklı VAL değeri birden fazla olan sütunları bulmak isteyelim. Şöyle yaparız. Aggregate olarak count() kullanılıyor.
select  ID_a from my_table group by ID_a
  having count(*)>1 
and count(distinct VAL) > 1 
Örnek - count = 6
Şöyle yaparız
SELECT institution_no 
FROM table 
WHERE cred_type in (1,2,3,4,5,6)
GROUP BY institution_no
HAVING COUNT(distinct cred_type) = 6;
Örnek - CTE ile count
CTE ile şöyle yaparız
WITH CTE as ( 
             SELECT DISTINCT institution_no, 
                    cert_type 
             FROM credentialing 
             WHERE cert_type IN (1,2)
             ) 
SELECT institution_no, 
       COUNT(institution_no) 
FROM cte 
GROUP BY institution_no 
HAVING COUNT(institution_no) = 2;
SUM
Örnek
Şöyle yaparız. Aggregate olarak sum() kullanılıyor.
SELECT customer_id,SUM (amount) FROM payment GROUP BY customer_id
HAVING SUM (amount) > 200;
Örnek
Şöyle yaparız
SELECT customer_id, SUM(quantity) AS total_quantity
FROM orders GROUP BY customer_id HAVING SUM(quantity) >= 50;

WHERE yerine HAVING
Şu iki cümle farklı şeylerdir. Bu örnekte her şey aggregate edildikten sonra HAVING ile süzme işlemi yapılıyor.
SELECT id, filedate, SUM(amount)
FROM Sales
GROUP BY id, filedate
HAVING id = 123 AND filedate = '1/1/2018'
Bu örnekte ise önce WHERE ile süzme işlemi yapılıyor ve daha sonra gruplama yapılıyor.
SELECT id, filedate, SUM(amount)
FROM Sales
WHERE id = 123 AND filedate = '1/1/2018'
GROUP BY id, filedate

14 Şubat 2019 Perşembe

pg_restore komutu

Giriş
pg_dump komutu ile alına yedekleri geri yüklemek içindir. Dump dosyası formatının text olmaması gerekir. Yoksa şu hatayı verir
$ pg_restore -U mypostgresqldumpplanet 
  -d myjhipsterplanet \
  -c \
  /var/lib/postgresql/data/2023-04-01-plaintext.sql 
pg_restore: error: input file appears to be a text format dump. Please use psql.
-c seçeneği
Restore işleminden önce veri tabanını temizler. 
Örnek - file restore
Şöyle yaparız
$ pg_restore \
  -U mypostgresqldumpplanet \
  -d myjhipsterplanet \
  -c \
  /var/lib/postgresql/data/2023-04-01-custom.dum
Örnek - directory restore
Şöyle yaparız
$ pg_restore 
  -U mypostgresqldumpplanet 
  -d myjhipsterplanet 
  -c
  /var/lib/postgresql/data/2023-04-01-directory/
Örnek - tar restore
Şöyle yaparız
$ pg_restore 
  -U mypostgresqldumpplanet 
  -d myjhipsterplanet 
  -c 
  /var/lib/postgresql/data/2023-04-01-tar.tar
-d seçeneği
Örnek
Şöyle yaparız. Burada parametreler şöyle
-U admin kullanıcı ismi 
-d veri tabanı ismi. postgres veri tabanı her zaman vardır
-C ile CREATE belirtiliyor
Restore işlemi başarısız çünkü myjhipsterplanet isimli role yok
$ pg_restore \
  -U mypostgresqldumpplanet \
  -d postgres \
  -C  \ 
  /var/lib/postgresql/data/2023-04-01-original.dump

pg_restore: while PROCESSING TOC:
pg_restore: from TOC entry 3382; 1262 16384 DATABASE myjhipsterplanet myjhipsterplanet
pg_restore: error: could not execute query: ERROR:  role "myjhipsterplanet" does not exist
Command was: ALTER DATABASE myjhipsterplanet OWNER TO myjhipsterplanet;
...
-l seçeneği
Sanırım dump dosyasının içini gösteriyor.
Örnek
Şöyle yaparız.
pg_restore -l <custom_dump_file>
Komutu başlatınca çıktı olarak şunu alırız
;
; Archive created at 2019-02-13 22:59:59 UTC
;     dbname: <database_name>
;     TOC Entries: 2615
;     Compression: -1
;     Dump Version: 1.13-0
;     Format: CUSTOM
;     Integer: 4 bytes
;     Offset: 8 bytes
;     Dumped from database version: 10.6 (Ubuntu 10.6-1.pgdg16.04+1)
;     Dumped by pg_dump version: 11.1 (Ubuntu 11.1-3.pgdg16.04+1)
;
Veri Tabanı Restore İçin
Örnek
Şöyle yaparız
[root@blt ~]# su - postgres
[postgres@blt ~]$ pg_dump -Fc TestDB> TestDB.dump
...
[postgres@blt ~]$ pg_restore -C -d postgres TestDB.dump
Tablo Restore İçin
Örnek
Şöyle yaparız
[root@blt ~]# su - postgres
[postgres@blt ~]$ pg_dump -Fc — data-only -W -dpostgres -tt1 > t1.dump
...
[postgres@blt ~]$ pg_restore — data-only -W -dpostgres -tt1new t1.dump

3 Şubat 2019 Pazar

GRANT

Giriş
Grant kelimesinden sonra ALL, INSERT, SELECT, UPDATE, DELETE, CONNECT kelimeleri gelir daha sonra ON TABLE X , ON ALL TABLES, ON DATABASE, ON ALL SEQUENCES kelimeleri gelir.

CONNECT Hakkı
Şöyle yaparız.
GRANT CONNECT ON DATABASE my_db TO my_user;
USAGE Hakkı
Şöyle yaparız.
GRANT USAGE ON SCHEMA public TO my_user;
ALL PRIVILEGES Hakkı
Örnek
Şöyle yaparız. springbootjpa veri tabanındaki tüm hakları jpatutorial kullanıcısına verir.
GRANT ALL PRIVILEGES ON DATABASE springbootjpa TO jpatutorial;
Örnek
Şöyle yaparız.
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO my_user;
Örnek
Şöyle yaparız.
GRANT ALL ON TABLE public.user_info TO "postgre-core-owneer";
ALL TABLES ve ALL SEQUENCES genellikle birlikte verilir. 
Örnek
Şöyle yaparız.
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA my_schema TO MY_GROUP;
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA my_schema TO MY_GROUP;
Örnek
Şöyle yaparız. Burada ALL TABLE kullanılıyor ama ALL PRIVILEGES yerine SELECT... vs. şeklinde haklar ayrı ayrı belirtiliyor
CREATE ROLE web_anon NOLOGIN;
GRANT USAGE ON SCHEMA public TO web_anon;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO web_anon;
ALL SEQUENCES Hakkı
Şöyle yaparız.
GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO my_user;