Postgres. Concatenate fields without fixed length - sql

I have two columns (A and B) on table 1, and I want to concatenate them into another column (C) only if the beginning of B is not A, and if that is not the case, just copy B into C.
The key point here is that A and B do not have a fixed length, so I don't think I can use left(), since it needs a specific length.
For example:
ID A B
1 5 48721
2 98 98555
3 98 136
4 841 8417740313
5 841 133889
In this case, column C should include:
For ID=1: 548721
For ID=2: 98555
For ID=3: 98136
For ID=4: 8417740313
For ID=5: 841133889
I was trying:
UPDATE 1
SET C = B
WHERE LEFT (B) = A
UPDATE 1
SET C = concat(A,B)
WHERE LEFT(B) <> A
But it doesn't work, since I need to give left() a fixed length. What would you guys do?

You seem to want something like this:
UPDATE t
SET C = (CASE WHEN B LIKE A || '%' THEN B ELSE A || B END);
That is, you can use LIKE for the comparison.

Step1:
update table
set col_c = col_a||substr(col_b,length(col_a))
where
substr(col_b,1,length(col_a))=col_a;
Step2:
update table
set col_c = col_a||col_b
where
substr(col_b,1,length(col_a))<>col_a;
you can try this and let us know,
the earlier given solution is also correct; but what if the same eg: 98 in col_a is present in the middle of col_b instead of in the start ?

Related

create view case based in sql

I have a table of 3 columns A,B,C
initially column C is completely empty and for every entry either A has a number or B has a number (never both in the same row)
I want to create a view that checks for every row if A=x and B is null or 0 then write the value of A in col.
EXAMPLE:
Can someone help guide me, I am still new to sql
You can'z use a VIEW for that but an UPDATE
UPDATE mytable
SET C = CASE WHEN A > 0 AND (B IS NULL OR B = 0) THEN A
ELSE B END
Thsi will not include what happens wehen A > 0 and B > 0 as you haven't specify what to do so this query will always take A before B
Let's assume a table ABC with column A, B and C as you mentioned
create table abc (a int ,b int ,c int )
And you want to display column C as value of either A or B based upon value
then you can create View by two methods to achieve the desired result
Using CASE
create view abc_v1
as
select a, b, case when isnull(a,0)=0 then b else a end "c"
from
abc
using Coalesce: considering the values would be either 0 or some value, we can mark column A/B as NULL when value is zero and use Coalesce
create view abc_v2
as
select a,b, coalesce(nullif(a,0),nullif(b,0)) as "c"
from abc
Or else,
If you want to update Column C with Value of col A/B then
Update ABC
set c = coalesce(nullif(a,0),nullif(b,0))
Try this view. It spells out your requirement.
CREATE OR REPLACE VIEW abc_with_c AS
SELECT a, b,
CASE WHEN a = 0 OR a IS NULL THEN b
WHEN b = 0 OR b IS NULL THEN a
ELSE NULL
END AS c
FROM abc;
It's a good idea in SQL to write statements so they're easy to read and reason about.

SQL tuple/lexicographic comparison with multiple directions

I need to return elements from a database query based on an inequality using the lexicographic ordering on multiple columns. As described in this question this is straightforward if I'm comparing all the columns in the same direction. Is there a straigtforward way to do this if I want to reverse the direction of the sort on some columns.
For instance, I might have columns A, B and C and values 5, 7, and 23 and I'd like to return something like:
WHERE A < 5 OR (A = 5 AND B > 7) OR (A = 5 AND B = 7 AND C < 23)
Is there any easier way to do this using tuples (I have to construct in a function without knowing the number of columns beforehand)? Note that, some columns are DateTime columns so I can't rely on tricks that apply only to integers (e.g. negating both sides). I'm happy to use postgresql specific tricks.
And, if not, is there a specific way/order I should build expressions like the above to best use multicolumn indexes?
Just thinking if going the CTE route and creating a column which stores 0 or 1 for whether the data passes the specific filter criteria or not.
WITH CTE AS
(
SELECT
..,
...,
CASE
WHEN A < 5 THEN 1
WHEN A = 5 AND B > 7 THEN 1
WHEN A = 5 AND B = 7 AND C < 23 THEN 1
ELSE 0
END AS filter_criteria
)
SELECT
..,
..
FROM
CTE
WHERE filter_criteria = 1
OR, directly applying the CASE statement in the WHERE clause. This reduces the extra step of CTE
WHERE 1 = CASE
WHEN A < 5 THEN 1
WHEN A = 5 AND B > 7 THEN 1
WHEN A = 5 AND B = 7 AND C < 23 THEN 1
ELSE 0
END
Referring to the thread you mentioned, can you try the idea WHERE (col_a, 'value_b') > ('value_a', col_b)

SQL Update table with all corresponding data from another table concatenated?

Running PostgreSQL 12.4. I am trying to accomplish this but the syntax given there doesn't seem to be working on psql, and I could not find another approach.
I have the following data:
Table 1
ID Trait
1 X
1 Y
1 Z
2 A
2 B
Table 2
ID Traits, Listed
1
2
3
4
I would like to create the following result:
Table 2
ID Traits, Listed
1 X + Y + Z
2 A + B
Concatenating with + would be ideal, as some traits have inherent commas.
Thank you for any help!
Try something like:
update table2
SET traits = agg.t
FROM
(select id,string_agg(trait, ',') t from table1 group by id) agg
where
table2.id = agg.id;
dbfiddle
Concatenating with + would be ideal, as some traits have inherent commas.
You can use whatever delimiter you like (just change the second argument to string_agg).

Add string to existing row separated by comma in sql

id value
1 a
2 b
3 c
How do i add second value 'z' to id=1 (separated by comma)?
id value
1 a,z
2 b
3 c
and how to remove the 'z' now if i have that final table?
You can use update:
update t
set value = concat(value, ',z')
where id = 1;
To answer your secondary question, yes.
If you run Select value from table where id = 1 it will return a,z. that means that if you are going to use it again in queries, you will quite possibly need to utilize a Split() type function, dependent on what you're doing with it.
The best and simplest way to do this is the following query according to me :
update table1 set value = concat(value,'z') where id = 1
where : Table1 is the name of your table.

Update Command with Case in SQLite

I want to update table A in such a way that if the attribute of the table column is desired then only it will change otherwise it wont change..
Update table A set B="abcd" ,C= (case when C="abc" then C="abcd" else C end) where column =1;
means C should be only change when in column=1 and C value is abc otherwise C should not be update ..it should be dropped and only B changes. but if the C
value get matched i.e abc give me the output 0 .. not changing to the abcd
Inside the THEN part, C="abcd" compares C with the value, and returns either 1 or 0.
The entire CASE expression should just return a value that then gets written into the C column, so you want just 'abcd' in this place:
UPDATE tableA
SET B = 'abcd',
C = CASE
WHEN C = 'abc' THEN 'abcd'
ELSE C
END
WHERE column = 1;
If I understand you correctly, you're trying to do two separate things:
UPDATE A set B = 'abcd' WHERE column = 1
UPDATE A set C = 'abcd' WHERE C = 'abc' AND column = 1
Is that right? If so, can you do it as two simple statements instead of one complicated statement?