jsonb to record
select fla.offer_id, ans_data.* from fla, jsonb_to_record(answer_data) as ans_data("AE46" text,"AE3" text,"AE16" text,"AE45" date,"AE47" date,"AE55" text,"AE60" text,"AE61" text,"AE73" date,"AE74" date,"AE62" text,"AE27" text,"AE42" text,"AE58" text,"AE25" text,"AE54" text,"AE44" text,"AE17" text,"AE53" text,"AE59" text,"AE19" text,"AE56" text,"AE21" text,"AE57" text,"AE33" text,"AE32" text,"AE41" date,"AE31" date,"AE65" text,"AE66" text,"AE67" text,"AE72" text,"AE52" text,"AE38" text,"AE69" text,"AE70" text,"AE68" text,"AE71" text,"AE39" text);
Accessing record’s key and values
select offer_id, rev, bf.key as business_field, bf.value as business_field_comments from table_name tn, jsonb_each_text((tn.answer_data->>'FI5')::jsonb) as bf;
JSON String agg
-- Data is stored as text within a json. Data itself is of type json
-- The end output is comma separted string from json keys
select string_agg(bf, e', ') from fact_logbook_ae fla, json_object_keys((fla.answer_data->>'AE54')::json) bf where offer_id= 'SECD-20230013';
UPSERTS: Update record on conflict while inserting
Syntax:
INSERT INTO table_name (column1, column2, ...)
VALUES (value1, value2, ...)
ON CONFLICT (conflict_column)
DO NOTHING | DO UPDATE SET column1 = value1, column2 = value2, ...;
Example
insert into scd_logbook.fact_logbook_ae (offer_id,rev,answer_data,created_by_gid,last_saved_by_gid,created_ts,last_saved_ts)
values(?,?,?,?,?,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)
on conflict (offer_id, rev) do update set answer_data=excluded.answer_data, last_saved_ts=CURRENT_TIMESTAMP, last_saved_by_gid=excluded.last_saved_by_gid ;
Notice the excluded
keyword.
The SET and WHERE clauses in ON CONFLICT DO UPDATE have access to the existing row using the table’s name (or an alias), and to the row proposed for insertion using the special excluded table.
On conflict clause in inserts from postgresql docs
Getting max of a revision
select * from
(select fla.offer_id, rank() over (partition by fla.offer_id order by fla.rev desc) as rank_rev, fla.rev
from fla_table fla) as cd
where rank_rev = 1
Validate Booking using Functions
CREATE OR REPLACE FUNCTION validate_booking_date()
RETURNS TRIGGER AS $$
DECLARE
max_booking_end_date DATE;
BEGIN
SELECT MAX(booking_end) INTO max_booking_end_date
FROM your_table
WHERE toolset_id = NEW.toolset_id;
IF NEW.booking_start <= max_booking_end_date THEN
RAISE EXCEPTION 'Booking start date must be greater than the maximum booking end date.';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Create a trigger that calls the validate_booking_date function
CREATE TRIGGER check_booking_date_trigger
BEFORE INSERT ON your_table
FOR EACH ROW
EXECUTE FUNCTION validate_booking_date();
Control access when creating a dashboard
-- as admin
create user app_owner with password '';
create schema app authorization app_owner;
create role app_readers;
-- run following as schema owner
grant usage on schema app to app_readers;
alter default privileges in schema app grant select on tables to app_readers;
grant select on all tables in schema app to app_readers;
Get column names of a table
SELECT *
FROM information_schema.columns
WHERE table_schema = 'your_schema'
AND table_name = 'your_table';
Update inline
-- Update the consumer names
update evaluation.lkp_consumer set consumer_name = t.new_consumer from
(values
('SE GS C ME', 'SE GS C RSO ME'),
('SE GS C CD ME', 'SE GS C RSO CD ME'),
('SE GS D ME', 'SE GS D RSO ME'),
('SE GT ME', 'SE GT RSO ME'),
('SE GS C REU', 'SE GS C RSO EU&AF')
) as t(prev_consumer, new_consumer) where t.prev_consumer = consumer_name;
Random sampling
Scenario : Let’s say you are working as SQL Developer and you are asked to provide some sample data from a table. You need to provide 10 rows or 100 rows but they should be selected random from table.
Solution :
You can use random()
function with Limit to get RANDOM ROWS from table. By using Limit you will restrict the number of rows you want to return.
select * from YourTableName order by random() limit count;
-- Example
select * from customer order by random limit 10;
Inserting unique rows from one table to another table
insert into shop_tbl(name, shop_location) select distinct shop_name, shop_location from expenses_tbl;