PostgreSQL compare with substring doesn't work - postgresql

I want to select from 2 table where 2nd id is equal with first 4 character from first id
SELECT a.*, b.*, substring(a.my_id from 1 for 4)::integer as number
FROM table1 as a
INNER Join table2 as b ON(b.id_2=number) where my_id = 101
^
It produces an error here |
ERROR: column "number" does not exist
SQL state: 42703
Character: 189

You can't use an alias like that, you need a derived table:
select *
from (
SELECT t1.*,
substring(t1.my_id::text from 1 for 4)::integer as number
FROM table1 t1
) as a
inner join table2 as b ON (b.id_2 = a.number)
where my_id = 101
Storing a number that is used as a foreign key as a part in a varchar column is a really, really ugly design. That number should be a column of its own in table1.

Related

Remove comma seprated values in postgresql

one table alphabet has column values nvarchar and values are (A,B,C,D,E,F,G,H)
we have another table that is linked with the previous one and this table has one column
which has values (C, H).
so These two values will be deleted from the previous table columns.
ID
values
1
A,B,C,D,E,F,G,H,I,J,K,L,M
2
A,C,F,G,H,J,U,V,W,X,Y,Z
second table.
ID
values
1
C,F
1
A,Z
FINAL OUTPUT .
TABLE A.
ID
values
1
B,D,E,G,H,I,J,K,L,M
2
A,C,F,G,H,J,U,V,W,X,Y,Z
Sample Query:
select
t1.id,
string_agg(t1.val1, ',') as "values"
from
(select "id", unnest(('{' || "values" || '}')::text[]) as val1 from table1
) as t1
left join
(select "id", unnest(('{' || "values" || '}')::text[]) val2 from table2
) t2 on t1.id = t2.id and t1.val1 = t2.val2
where t2.id is null
group by t1.id
-- Return:
id values
---------------------------------
1 B,D,E,G,H,I,J,K,L,M
2 A,C,F,G,H,X,J,U,V,W,Y,Z

Inner join with table that does not contain any record fails?

I have query in which I have applied inner join, it works fine if the joining table on right side has some records, but inner joins return nothing when joining table has 0 (zero) records, and I understand it bcz it has nothing to join on.
I want the records from tbl11 if record has status=1 in tbl11 or if that record exist in tbl12 then it must have status=1, if tbl12.status=0, then that record is not needed.
Table structure
create table tbl11
(
tbl11_id serial primary key,
name character varying,
status integer
)
insert into tbl11(name, status) values('Tony',1),
('Jony',1),
('Sneha',1),
('Aakriti',0)
create table tbl12
(
tbl12_id serial primary key,
tbl11_id integer,
name character varying,
status integer
)
Here is what, I have tried till now
select t1.tbl11_id, t1.name, t1.status from tbl11 t1
inner join tbl12 t2 on t1.tbl11_id = t2.tbl11_id or t1.tbl11_id !=t2.tbl11_id
where t1.status=1 and t2.status=1
It gives no output as tbl12 doesn't have any data.
Then I read about case in postgres and tried this
select case
when
select exists (select 1 from tbl12)
Then
select t1.tbl11_id, t1.name, t1.status from tbl11 t1
inner join tbl12 t2 on t1.tbl11_id = t2.tbl11_id or t1.tbl11_id !=t2.tbl11_id
where t1.status=1 and t2.status=2
else
select tbl11_id, name, status from tbl11 where status=1
But it gives error as
ERROR: syntax error at or near "select"
LINE 3: select exists (select 1 from tbl12)
this is the simple query
select * from tbl11 where status=1 and tbl11_id not in (select tbl11_id from tbl12 where status=0);
DEMO

Postgres join involving tables having join condition defined on an text array

I have two tables in postgresql
One table is of the form
Create table table1(
ID serial PRIMARY KEY,
Type []Text
)
Create table table2(
type text,
sellerID int
)
Now i want to get all the rows from table1 which are having type same that in table2 but the problem is that in table1 the type is an array.
In case the type in the table has an identifiable delimiter like ',' ,';' etc. you can rewrite the query as regexp_split_to_table(type,',') or versions later than 9.5 unnest function can be use too.
For eg.,
select * from
( select id ,regexp_split_to_table(type,',') from table1)table1
inner join
select * from table2
on trim(table1.type) = trim(table2.type)
Another good example can be found - https://www.dbrnd.com/2017/03/postgresql-regexp_split_to_array-to-split-string-using-different-delimiters/
SELECT
a[1] AS DiskInfo
,a[2] AS DiskNumber
,a[3] AS MessageKeyword
FROM (
SELECT regexp_split_to_array('Postgres Disk information , disk 2 , failed', ',')
) AS dt(a)
You can use the ANY operator in the JOIN condition:
select *
from table1 t1
join table2 t2 on t2.type = any (t1.type);
Note that if the types in the table1 match multiple rows in table2, you would get duplicates (from table1) because that's how a join works. Maybe you want an EXISTS condition instead:
select *
from table1 t1
where exists (select *
from table2 t2
where t2.type = any(t1.type));

PostgreSQL - Append a table to another and add a field without listing all fields

I have two tables:
table_a with fields item_id,rank, and 50 other fields.
table_b with fields item_id, and the same 50 fields as table_a
I need to write a SELECT query that adds the rows of table_b to table_a but with rank set to a specific value, let's say 4.
Currently I have:
SELECT * FROM table_a
UNION
SELECT item_id, 4 rank, field_1, field_2, ...
How can I join the two tables together without writing out all of the fields and without using an INSERT query?
EDIT:
My idea is to join table_b to table_a somehow with the rank field remaining empty, then simply replace the null rank fields. The rank field is never null, but item_id can be duplicated and table_a may have item_id values that are not in table_b, and vice-versa.
I am not sure I understand why you need this, but you can use jsonb functions:
select (jsonb_populate_record(null::table_a, row)).*
from (
select to_jsonb(a) as row
from table_a a
union
select to_jsonb(b) || '{"rank": 4}'
from table_b b
) s
order by item_id;
Working example in rextester.
I'm pretty sure I've got it. The predefined rank column can be inserted into table_b by joining to the subset of itself with only the columns left of the column behind which you want to insert.
WITH
_leftcols AS ( SELECT item_id, 4 rank FROM table_b ),
_combined AS ( SELECT * FROM table_b JOIN _leftcols USING (item_id) )
SELECT * FROM _combined
UNION
SELECT * FROM table_a

Postgresql how to select values in the column from one table that are only available in another table?

I am using Postgresql and need to query two tables like this:
Table1
ID Bill
A 1
B 2
B 3
C 4
Table2
ID
A
B
I want a table with all the columns in Table1 but keeping only the records with IDs that are available in Table2 (A and B in this case). Also, Table2's ID is unique.
ID Bill
A 1
B 2
B 3
Which join I should use or if I can use WHERE statement?
Thanks!
SELECT Table1.*
FROM Table1
INNER JOIN Table2 USING (ID);
or
SELECT *
FROM Table1
WHERE ID IN (SELECT ID FROM Table2);
but the first one is better for performance reason.
SELECT *
FROM Table1
WHERE EXISTS (
SELECT 1 FROM Table2 WHERE Table2.ID = Table1.ID LIMIT 1
)