How to UPDATE column1 based on a string in column2? - sql

I seem to have a small problem with updating a column within my database (postgres). I am trying to update column1, based on the string which is in column2. The logic behind it is; IF string contains "rail", then column 2 = "rail". IF string contains "air", then column 2 = "air".
I am trying to use CASE to make this work, and would eventually like to put this in a trigger.
I have searched through stackoverflow to find the solution, I see many similar problems but none of them worked for me.
UPDATE table1
SET column1 = CASE
WHEN column2 LIKE '%rail%' THEN 'rail'
WHEN column2 LIKE '%air%' THEN 'air'
ELSE 'other'
END;
I expect column 1 to output either rail, air or other. But it is only printing "other".
(UPDATE) - Solved problem, turns out case sensitivity within the '%%' field is important!

Related

Adding column to table based on whether another column = a specific string

I want to add a column called "Sweep" that contains bools based on whether the "Result" was a sweep or not. So I want the value in the "Sweep" column to be True if the "Result" is '4-0' or '0-4' and False if it isn't.
This is a part of the table:
I tried this:
ALTER TABLE "NBA_finals_1950-2018"
ADD "Sweep" BOOL;
UPDATE "NBA_finals_1950-2018"
SET "Sweep" = ("Result" = '4-0' OR "Result" = '0-4');
But for some reason, when I run this code...:
SELECT *
FROM "NBA_finals_1950-2018"
ORDER BY "Year";
...only one of the rows (last row) has the value True even though there are other rows where the result is a sweep ('4-0' or '0-4') as shown in the picture below.
I don't know why this is happening but I guess there is something wrong with the UPDATE...SET code. Please help.
Thanks in advance.
NOTE: I am using PostgreSQL 13
This would occur if the strings are not really what they look like -- this is often due to spaces at the beginning or end. Or perhaps to hyphens being different, or other look-alike characters.
You just need to find the right pattern. So so with a select. This returns no values:
select *
from "NBA_finals_1950-2018"
where "Result" in ('4-0', '0-4');
You can try:
where "Result" like '%0-4%' or
"Result" like '%4-0%'
But, this should do what you want:
where "Result" like '%4%' and
"Result" like '%0%'
because the numbers are all single digits.
You can incorporate this into the update statement.
Note: double quotes are a bad idea. I would recommend creating tables and columns without escaping the names.

Multiple value in a column sql

I'm working on an SSIS package. This package loads information from a form a verdure files. the package works perfectly, however my issue is in one of the column called 'SpecialUnit'.
On the form the customer can select 23 values and all this values get recorded as a comma separated. In my SSIS I have created different fields for all 23 values I wanted all this values to show 1 when the person selects them.
Example.
CASE WHEN sp.CodeText = 'Transit Dept.'
THEN 1
ELSE 0
END AS FollowUpByTransit,
I have a table that separates the comma delimiter, but when loading I do not have a value I want which is 1 or 0.
Can you make your 23 fields as calculated fields, then on the equation for each field you can use something like the below
As case when CodeText like '%Transit Dept%' then 1 else 0 end as FollowUpByTransit
So you would need to use the like operator, so you ignore the commas and other values.
If your code words may be a bit similar to each other, you can go with the idea HABO presented and thats somthing like the below
As case when (','+CodeText+',') like '%,Transit Dept,%' then 1 else 0 end as FollowUpByTransit
Hope this helps.

PostgreSQL - Assign integer value to string in case statement

I need to select one and only 1 row of data based on an ID in the data I have. I thought I had solved this (For details, see my original question and my solution, here: PostgreSQL - Select only 1 row for each ID)
However, I now still get multiple values in some cases. If there is only "N/A" and 1 other value, then no problem.. but if I have multiple values like: "N/A", "value1" and "value2" for example, then my case statement is not sufficient and I get both "value1" and "value2" returned to me. This is the case statement in question:
CASE
WHEN "PQ"."Value" = 'N/A' THEN 1
ELSE 0
END
I need to give a unique integer value to each string value and then the problem will be solved. The question is: how do I do this? My first thought is to somehow convert the character values to ASCII and sum them up.. but I am not sure how to do that and also worried about performance. Is there a way to very simply assign a value to each string so that I can choose 1 value only? I don't care which one actually... just that it's only 1.
EDIT
I am now trying to create a function to add up the ASCII values of each character so I can essentially change my case statement to something like this:
CASE
WHEN "PQ"."Value" = 'N/A' THEN 9999999
ELSE SumASCII("PQ"."Value")
END
Having a small problem with it though.. I have added it as a separate question, here: PostgreSQL - ERROR: query has no destination for result data
EDIT 2
Thanks to #Bohemian, I now have a working solution, which is as follows:
CASE
WHEN "PQ"."Value" = 'N/A' THEN -1
ELSE ('x'||LPAD(MD5("PQ"."Value"),16,'0'))::bit(64)::bigint
END DESC
This will produce a "unique" number for each value:
('x'||substr(md5("PQ"."Value"),1,8))::bit(64)::bigint
Strictly speaking, there is a chance of a collision, but it's very remote.
If the result is "too big", you could try modulus:
<above-calculation> % 10000
Although collisions would then be a 0.01% chance, you should try this formula against all known values to ensure there are no collisions.
If you don't care which value gets picked, change RANK() to ROW_NUMBER(). If you do care, do it anyway, but also add another term after the CASE statement in ORDER BY, separated by a comma, with the logic you want - for example if you want the first value alphabetically, do this:
...
ORDER BY CASE...END, "PQ"."Value")
...

SQL - Conditionally joining two columns in same table into one

I am working with a table that contains two versions of stored information. To simplify it, one column contains the old description of a file run while another column contains the updated standard for displaying ran files. It gets more complicated in that the older column can have multiple standards within itself. The table:
Old Column New Column
Desc: LGX/101/rpt null
null Home
Print: LGX/234/rpt null
null Print
null Page
I need to combine the two columns into one, but I also need to delete the "Print: " and "Desc: " string from the beginning of the old column values. Any suggestions? Let me know if/when I'm forgetting something you need to know!
(I am writing in Cache SQL, but I'd just like a general approach to my problem, I can figure out the specifics past that.)
EDIT: the condition is that if substr(oldcol,1,5) = 'desc: ' then substr(oldcol,6)
else if substr(oldcol,1,6) = 'print: ' then substr(oldcol,7) etc. So as to take out the "desc: " and the "print: " to sanitize the data somewhat.
EDIT2: I want to make the table look like this:
Col
LGX/101/rpt
Home
LGX/234/rpt
Print
Page
It's difficult to understand what you are looking for exactly. Does the above represent before/after, or both columns that need combining/merging.
My guess is that COALESCE might be able to help you. It takes a bunch of parameters and returns the first non NULL.
It looks like you're wanting to grab values from new if old is NULL and old if new is null. To do that you can use a case statement in your SQL. I know CASE statements are supported by MySQL, I'm not sure if they'll help you here.
SELECT (CASE WHEN old_col IS NULL THEN new_col ELSE old_col END) as val FROM table_name
This will grab new_col if old_col is NULL, otherwise it will grab old_col.
You can remove the Print: and Desc: by using a combination of CharIndex and Substring functions. Here it goes
SELECT CASE WHEN CHARINDEX(':',COALESCE(OldCol,NewCol)) > 0 THEN
SUBSTRING(COALESCE(OldCol,NewCol),CHARINDEX(':',COALESCE(OldCol,NewCol))+1,8000)
ELSE
COALESCE(OldCol,NewCol)
END AS Newcolvalue
FROM [SchemaName].[TableName]
The Charindex gives the position of the character/string you are searching for.
So you get the position of ":" in the computed column(Coalesce part) and pass that value to the substring function. Then add +1 to the position which indicates the substring function to get the part after the ":". Now you have a string without "Desc:" and "Print:".
Hope this helps.

add record in SQL based on last character of a field

I have a field in sql that contains a 1 or 0 at the end. What I am trying to do is if the field has a 1 at the end but no corresponding 0 I would like to add that record.
3 different examples
Field value
Data1 ( I would like to add another record containing Data0)
Data0 ( I would like to add another record containing Data1)
Data0 and Data1 both exists in table ( Do nothing )
insert into test(col, another_column_1,...,another_column_n)
select substr(col,1, length(col)-1) || --this is the base value
max(mod(substr(col,length(col),length(col))+1,2)) --this is the termination (0 or 1)
as col ,
max(another_column_1),
...
max(another_column_n)
from test
where substr(col,length(col),length(col)) between '0' and '1'
group by substr(col,1, length(col)-1)
having count(*)=1;
you can see test here
Updated for Oracle
If I understood your question correctly, you can use the LIKE operator.
You can do something like:
(field like '%1' or field like '%0') and not field like '%0%1'
But generally, SQL is not suitable for text processing. This LIKE thing is pretty much the most advanced text processing feature in SQL.