Press "Enter" to skip to content

Sql Json veriler üzeridne çalisma

Selahaddin Erdoğan 0

1. JSON ve JSONB Farkı

  • JSON: Ham JSON string saklar. (Daha yavaş, ama orijinal format korunur.)

  • JSONB: Binary formda saklar. (Daha hızlı arama, indexleme yapılır, genelde tercih edilen bu.)

CREATE TABLE users (
id SERIAL PRIMARY KEY,
profile JSONB
);

Örnek kayıt:

INSERT INTO users (profile) VALUES
('{"name": "Ahmet", "age": 25, "skills": ["SQL","JS"], "address": {"city": "İstanbul", "zip": 34000}}');

2. JSON Veri Erişimi

  • -> : JSON objesi/dizisine erişir (JSON döner)

  • ->> : Text olarak döner

  • #> : Derin JSON objesine erişim (JSON döner)

  • #>> : Derin JSON objesine erişim (Text döner)

Örnekler:

-- name alanını text olarak çek
SELECT profile->>'name' AS isim FROM users;
— address objesinin city değerini al
SELECT profile>‘address’>>‘city’ AS sehir FROM users;— skills arrayinin ilk elemanını al
SELECT profile>‘skills’>>0 AS ilk_skill FROM users;

3. JSON Filtreleme (WHERE şartı)

-- Yaşı 25 olan kullanıcıları getir
SELECT * FROM users
WHERE profile->>'age' = '25';
— Şehri İstanbul olanlar
SELECT * FROM users
WHERE profile>‘address’>>‘city’ = ‘İstanbul’;
(
SELECT addr->>’city’
FROM jsonb_array_elements(u.profile->’adresses’) addr
WHERE (addr->>’primary’)::boolean = true
LIMIT 1
) AS primary_city

FROM users u
WHERE EXISTS (
SELECT 1
FROM books o
WHERE o.user_id = u.id
AND o.created_at >= now() – interval ’30 days’
);

 

 

 

 


4. JSON İçinde Arama (Exist / Contain)

  • @> : İçeriyor mu? (contain)

  • ? : Key var mı?

  • ?| : Bu keylerden biri var mı?

  • ?& : Bu keylerin hepsi var mı?

-- address içinde "city":"İstanbul" olan kullanıcılar
SELECT * FROM users
WHERE profile @> '{"address": {"city":"İstanbul"}}';
— profile içinde “name” key’i var mı?
SELECT * FROM users
WHERE profile ? ‘name’;

5. JSON Güncelleme

PostgreSQL 9.5+ sürümlerinde jsonb_set var:

-- age değerini 30 yap
UPDATE users
SET profile = jsonb_set(profile, '{age}', '30'::jsonb)
WHERE profile->>'name' = 'Ahmet';
— address içindeki zip güncelle
UPDATE users
SET profile = jsonb_set(profile, ‘{address,zip}’, ‘34010’::jsonb);

 

SELECT
u.id AS user_id,

— En çok okunan kitap—–?
(
SELECT product_name
FROM (
SELECT
(item->>’product_name’) AS product_name,
SUM((item->>’ktp’)::int) AS total_ktp,
ROW_NUMBER() OVER (ORDER BY SUM((item->>’ktp’)::int) DESC) AS rn
FROM books o
CROSS JOIN LATERAL jsonb_array_elements(o.items->’items’) AS item
WHERE o.user_id = u.id
AND o.created_at >= now() – interval ’30 days’
GROUP BY item->>’product_name’
) t
WHERE rn = 1
) AS top_product,

 

 


6. JSON Dizileriyle Çalışma

-- skills dizisini patlat (unnest)
SELECT jsonb_array_elements(profile->'skills') AS skill
FROM users;
— Dizide “SQL” olan kullanıcıları getir
SELECT * FROM users
WHERE profile>‘skills’ @> ‘[“SQL”]’;
———–

SELECT
u.id AS user_id,

— En çok okunan kitap—–?
(
SELECT product_name
FROM (
SELECT
(item->>’product_name’) AS product_name,
SUM((item->>’ktp’)::int) AS total_ktp,
ROW_NUMBER() OVER (ORDER BY SUM((item->>’ktp’)::int) DESC) AS rn
FROM orders o
CROSS JOIN LATERAL jsonb_array_elements(o.items->’items’) AS item
WHERE o.user_id = u.id
AND o.created_at >= now() – interval ’30 days’
GROUP BY item->>’product_name’
) t
WHERE rn = 1
) AS top_product,

— Kullanıcının primary_city’si
(
SELECT addr->>’city’
FROM jsonb_array_elements(u.profile->’adresses’) addr
WHERE (addr->>’primary’)::boolean = true
LIMIT 1
) AS primary_city

FROM users u
WHERE EXISTS (
SELECT 1
FROM orders o
WHERE o.user_id = u.id
AND o.created_at >= now() – interval ’30 days’
);

—————


7. JSONB Indexleme (Performans için)

Büyük verilerde mutlaka index kullan:

CREATE INDEX idx_users_profile ON users USING gin (profile jsonb_path_ops);

8. JSON Path (PostgreSQL 12+)

XPath benzeri sorgular yazabilirsin:

-- $.address.city değerini çek
SELECT profile #>> '{address,city}' FROM users;
— JSON Path ile filtre
SELECT * FROM users
WHERE profile @? ‘$.address.city ? (@ == “İstanbul”)’;

Comments are closed.