1

I have got follow data base schema:

CREATE TABLE "public"."regions" ( 
    "id" Integer DEFAULT nextval('regions_id_seq'::regclass) NOT NULL,
    "ru_name" Character Varying( 100 ),
    "translite_name" Character Varying( 100 ),
    PRIMARY KEY ( "id" ) );
 ;


CREATE TABLE "public"."tokens" ( 
    "user_id" BigInt NOT NULL,
    "token_start_date" Timestamp Without Time Zone NOT NULL,
    "token_end_date" Timestamp Without Time Zone NOT NULL,
    "regions" JSON,
    "id" Character( 1 ) NOT NULL,
    "access_token" Character Varying( 50 ) NOT NULL,
    PRIMARY KEY ( "id" ) );
 ;

CREATE TABLE "public"."users" ( 
    "id" BigInt DEFAULT nextval('user_id_sequence'::regclass) NOT NULL,
    "registration_date" Timestamp Without Time Zone NOT NULL,
    "name" Character Varying( 50 ) NOT NULL,
    "lastname" Character Varying NOT NULL,
    "email" Character Varying NOT NULL,
    PRIMARY KEY ( "id" ),
    CONSTRAINT "unique_users_email" UNIQUE( "email" ) );
 ;

I need to display for every user date of expiring token and regions names for this token. Something like:

user_id token_end_date region_as_json_object
5 "2021-12-27" [{id: 1, ru_name:"Region1"}, {id: 2, ru_name:"Region2"}]

I wrote next code:

SELECT 
  ru_name 
FROM "tokens" 
JOIN regions ON regions.id = ANY (json_array_elements_text(regions) )
WHERE user_id = 5 ;

But it does not work.

enter image description here

sample data:

--
-- PostgreSQL database dump
--

-- Dumped from database version 13.1
-- Dumped by pg_dump version 13.1

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', '', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;

SET default_tablespace = '';

SET default_table_access_method = heap;

--
-- Name: regions; Type: TABLE; Schema: public; Owner: postgres
--

CREATE TABLE public.regions (
    id integer NOT NULL,
    ru_name character varying(100),
    fz223_name character varying(100),
    fz44_name character varying(100),
    translite_name character varying(100)
);


ALTER TABLE public.regions OWNER TO postgres;

--
-- Name: regions_id_seq; Type: SEQUENCE; Schema: public; Owner: postgres
--

CREATE SEQUENCE public.regions_id_seq
    AS integer
    START WITH 1
    INCREMENT BY 1
    NO MINVALUE
    NO MAXVALUE
    CACHE 1;


ALTER TABLE public.regions_id_seq OWNER TO postgres;

--
-- Name: regions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: postgres
--

ALTER SEQUENCE public.regions_id_seq OWNED BY public.regions.id;


--
-- Name: tokens; Type: TABLE; Schema: public; Owner: postgres
--

CREATE TABLE public.tokens (
    id character(1) NOT NULL,
    user_id bigint NOT NULL,
    token_start_date timestamp without time zone NOT NULL,
    token_end_date timestamp without time zone NOT NULL,
    access_token character varying(50) NOT NULL,
    regions json
);


ALTER TABLE public.tokens OWNER TO postgres;

--
-- Name: users; Type: TABLE; Schema: public; Owner: postgres
--

CREATE TABLE public.users (
    id bigint DEFAULT nextval('public.user_id_sequence'::regclass) NOT NULL,
    name character varying(50) NOT NULL,
    lastname character varying NOT NULL,
    email character varying NOT NULL,
    registration_date timestamp without time zone NOT NULL
);


ALTER TABLE public.users OWNER TO postgres;

--
-- Name: regions id; Type: DEFAULT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.regions ALTER COLUMN id SET DEFAULT nextval('public.regions_id_seq'::regclass);


--
-- Data for Name: regions; Type: TABLE DATA; Schema: public; Owner: postgres
--

INSERT INTO public.regions VALUES
    (1, 'Адыгейская республика', 'Adygeya_Resp', 'Adygeja_Resp', 'Adygejskaya_respublika'),
    (2, 'Алтайский край', 'Altayskii__krai', 'Altajskij_kraj', 'Altajskij_kraj'),
    (3, 'Алтайская республика', 'Altay_Resp', 'Altaj_Resp', 'Altajskaya_respublika'),
    (4, 'Амурская область', 'Amurskaya_obl', 'Amurskaja_obl', 'Amurskaya_oblast'),
    (5, 'Архангельская область', 'Arhangelskaya_obl', 'Arkhangelskaja_obl', 'Arhangelskaya_oblast'),
    (6, 'Астраханская область', 'Astrahanskaya_obl', 'Astrakhanskaja_obl', 'Astrahanskaya_oblast'),
    (7, 'Байконур', 'Baikonur_g', 'Bajkonur_g', 'Bajkonur'),
    (8, 'Башкортостан', 'Bashkortostan_Resp', 'Bashkortostan_Resp', 'Bashkortostan'),
    (9, 'Белгородская область', 'Belgorodskaya_obl', 'Belgorodskaja_obl', 'Belgorodskaya_oblast'),
    (10, 'Брянская область', 'Brianskaya_obl', 'Brjanskaja_obl', 'Bryanskaya_oblast'),
    (11, 'Бурятская область', 'Buryatiya_Resp', 'Burjatija_Resp', 'Buryatskaya_oblast');


--
-- Data for Name: tokens; Type: TABLE DATA; Schema: public; Owner: postgres
--

INSERT INTO public.tokens VALUES
    ('1', 3, '2020-03-05 00:00:00', '2020-03-08 00:00:00', 'sdfa78saaf4', NULL),
    ('2', 3, '2020-04-08 00:00:00', '2020-04-18 00:00:00', 'asasdfgkfaf4', NULL),
    ('3', 3, '2020-05-15 00:00:00', '2020-09-25 00:00:00', '934rfeasfsad', '[1,2,4]'),
    ('4', 3, '2020-05-15 00:00:00', '2020-09-25 00:00:00', '934rfeasfsad', '[4,5,7]'),
    ('5', 5, '2021-05-15 00:00:00', '2021-12-25 00:00:00', '934rfeasfsad', '[1,4,6,8]'),
    ('6', 5, '2021-06-15 00:00:00', '2022-01-25 00:00:00', '934rfeasfsad', '[12]');


--
-- Data for Name: users; Type: TABLE DATA; Schema: public; Owner: postgres
--

INSERT INTO public.users VALUES
    (3, 'Mike', 'Klinton', '[email protected]', '2010-01-02 00:00:00'),
    (5, 'Piter', 'Miklson', '[email protected]', '2011-01-02 00:00:00');


--
-- Name: regions_id_seq; Type: SEQUENCE SET; Schema: public; Owner: postgres
--

SELECT pg_catalog.setval('public.regions_id_seq', 1, false);


--
-- Name: regions regions_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.regions
    ADD CONSTRAINT regions_pkey PRIMARY KEY (id);


--
-- Name: tokens tokens_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.tokens
    ADD CONSTRAINT tokens_pkey PRIMARY KEY (id);


--
-- Name: users unique_users_email; Type: CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.users
    ADD CONSTRAINT unique_users_email UNIQUE (email);


--
-- Name: users users_pkey; Type: CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.users
    ADD CONSTRAINT users_pkey PRIMARY KEY (id);


--
-- Name: tokens userr_id_fk; Type: FK CONSTRAINT; Schema: public; Owner: postgres
--

ALTER TABLE ONLY public.tokens
    ADD CONSTRAINT userr_id_fk FOREIGN KEY (user_id) REFERENCES public.users(id) MATCH FULL ON UPDATE CASCADE ON DELETE CASCADE;


--
-- PostgreSQL database dump complete
--

2
  • Pls. provide sample data as DDL and insert scripts. Commented Dec 8, 2021 at 9:10
  • @Stefanov.sm done Commented Dec 8, 2021 at 9:21

3 Answers 3

1
select user_id, token_end_date::date, 
       json_agg(json_build_object('id',region_id,'ru_name',ru_name)) as regions_json_object
from
(
  select user_id, token_end_date, 
         json_array_elements_text(regions)::integer as region_id 
  from tokens
) as t
join regions on t.region_id = regions.id
group by user_id, token_end_date;
Sign up to request clarification or add additional context in comments.

Comments

1

Try this :

SELECT 
  ru_name 
FROM 
( SELECT json_array_elements_text(regions) AS r
    FROM public.tokens
   WHERE user_id = 5
) AS r
JOIN public.regions
ON regions.id = r :: integer ;

see the result in dbfiddle

2 Comments

I am getting error about wrong syntax. I've added sample data
Well it's better with the sample data ! see my updated answer and the tet result in dbfiddle
0

You can use CROSS JOIN and after collecting, data use JOIN for combine data.

Demo

with data as (
  select
    t.*,
    (ej.value ->> 'id')::int as region_id
  from
    "public"."tokens" t
    cross join json_array_elements(t.regions) ej
  where
    user_id = 5
)
select
  r.ru_name
from
  "public"."regions" r
  inner join data d on d.region_id = r.id

2 Comments

I checked and got empty result. I've added sample data
imgur.com/7xSYaZL empty result. What I am doing wrong?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.