Postgres-update char column for spesifc string - database

i have something that almost challenging to me that i want to update a column values based on condition.
I have a table called customers that contain the customer name and phone,i have a lot of records on it almost 40K record.
The phone numbers column is char and the records is like this '100445216324.0' but i want to update all the number that in the same way to: 0100445216324 ,,what i did here that i remove the '.0' in the last of the number and i add 0 in font of it.
How could i do this to all records in one simple update statement .
thanks

UPDATE my_table
SET tel = '0' || left(tel, -2)
WHERE right(tel, 2) = '.0';
This only updates telephone numbers that end in '.0'.

Personally, I would be more comfortable with a more general solution, of taking everything before the period and adding a leading zero . . . if there is a period:
update t
set tel = '0' || left(tel, position('.' in tel) - 1)
where tel like '%.%';
The where checks that the change is made only on the rows that have the format suggested in the question.
If you want to insist that all numbers start with a zero, you might then want to do:
update t
set tel = '0' || tel
where tel not like '0%';

Related

How to check if a numeric column value is in ascending or descending order. eg. 12345 or 654321

I need help with a SQL query to check if a numeric column contains a number in ascending or descending order.
eg. 123456 or 654321
This is to avoid people entering some random values in a customer phone number column, users are required to give valid phone number input.
I want to achieve this without using a function.
UPDATE: #LukStorms had kindly answered my question. Many thanks. Thanks to others who looked at my question and left comments. However I would really appreciate if the comment helps solve the problem. My scenario is different, I cannot post the entire use case here. The ask is I must validate the column in the same way.
To check if it's like a sequence of digits?
Then you can simply use LIKE
select num
, cast(case
when '1234567890123456789' like concat('%',num,'%')
then 1
when '9876543210987654321' like concat('%',num,'%')
then 1
else 0 end as bit) as isSequence
from (values
(123456),
(765432),
(797204)
) nums(num)
num
isSequence
123456
True
765432
True
797204
False
Or use CHARINDEX
select num
, cast(case
when 0 < charindex(concat(num,''),'1234567890123456789') then 1
when 0 < charindex(concat(num,''),'9876543210987654321') then 1
else 0 end as bit) as isSequence
from (values
(123456),
(765432),
(797204)
) nums(num)
Demo on db<>fiddle here

Update YEAR data in values like YYYMM for column of Datatype numeric or nchar

I am struggling hard to update the YEAR data in some columns in the Database. The values are like 201201 (year+month). The datatype of this column (month_id) is numeric. I only need to change 201201 to 201501, 201301 to 201601 such that adding +3 to Year.
I have tried using CAST, CONVERT. Tried to write queries as below:
UPDATE Table
SET month_id = SUBSTRING(CAST(month_id as VARCHAR(10)), 1, 4) +3
WHERE month_id = '202011'
It gives result as 2023. Not 202311. Later I tried to CONCAT but it gives arithmetic error.
Can anyone please suggest a proper solution?
Also its same with another column day_desc (datatype - nchar [10]) and values are like 01.01.2012,01.01.2013, etc... Need to change years here as well. But since the data is in different format, I am unable to do it.
How's this:
UPDATE Table
SET month_id = month_id + 300
This will work without you having to do any casting...
UPDATE Table
SET month_id = (((month_id / 100) + 3) * 100) + (month_id % 100)
--(month_id / 100) will return the year part
--(month_id % 100) will return the month part
this should work
UPDATE Table
SET month_id = CONCAT( CAST(LEFT(month_id, 4) + 3 AS NVARCHAR(4)), RIGHT(month_id, 2))
WHERE month_id = '202011'
Edit based on your comment, with inputs like '01.01.2014':
UPDATE MyTable
SET MyColumn = CONCAT(LEFT(MyValue, 6), CONVERT(INT, RIGHT(MyValue, 4))+3)
WHERE MyColumn = '01.01.2014'
Edit2, based on your comments to other posts too:
if your target is to avoid multiple updates to same records, lets say you already updated 201401 to 201701 and you dont want your query make it 202001, so you need to update some other column like UPDATED BIT where 1 = already updated, and 0 = not updated.
More, be careful on where clause: do you really want to update ALL YOUR TABLE RECORDS with new logic (adding 3 years) or maybe you are looking only for some of them.

How do I match a substring of variable length?

I am importing data into my SQL database from an Excel spreadsheet.
The imp table is the imported data, the app table is the existing database table.
app.ReceiptId is formatted as "A" followed by some numbers. Formerly it was 4 digits, but now it may be 4 or 5 digits.
Examples:
A1234
A9876
A10001
imp.ref is a free-text reference field from Excel. It consists of some arbitrary length description, then the ReceiptId, followed by an irrelevant reference number in the format " - BZ-0987654321" (which is sometimes cropped short, or even missing entirely).
Examples:
SHORT DESC A1234 - BZ-0987654321
LONGER DESCRIPTION A9876 - BZ-123
REALLY LONG DESCRIPTION A2345 - B
REALLY REALLY LONG DESCRIPTION A23456
The code below works for a 4-digit ReceiptId, but will not correctly capture a 5-digit one.
UPDATE app
SET
[...]
FROM imp
INNER JOIN app
ON app.ReceiptId = right(right(rtrim(replace(replace(imp.ref,'-',''),'B','')),5)
+ rtrim(left(imp.ref,charindex(' - BZ-',imp.ref))),5)
How can I change the code so it captures either 4 (A1234) or 5 (A12345) digits?
As ughai rightfully wrote in his comment, it's not recommended to use anything other then columns in the on clause of a join.
The reason for that is that using functions prevents sql server for using any indexes on the columns that it might use without the functions.
Therefor, I would suggest adding another column to imp table that will hold the actual ReceiptId and be calculated during the import process itself.
I think the best way of extracting the ReceiptId from the ref column is using substring with patindex, as demonstrated in this fiddle:
SELECT ref,
RTRIM(SUBSTRING(ref, PATINDEX('%A[0-9][0-9][0-9][0-9]%', ref), 6)) As ReceiptId
FROM imp
Update
After the conversation with t-clausen-dk in the comments, I came up with this:
SELECT ref,
CASE WHEN PATINDEX('%[ ]A[0-9][0-9][0-9][0-9][0-9| ]%', ref) > 0
OR PATINDEX('A[0-9][0-9][0-9][0-9][0-9| ]%', ref) = 1 THEN
SUBSTRING(ref, PATINDEX('%A[0-9][0-9][0-9][0-9][0-9| ]%', ref), 6)
ELSE
NULL
END As ReceiptId
FROM imp
fiddle here
This will return null if there is no match,
when a match is a sub string that contains A followed by 4 or 5 digits, separated by spaces from the rest of the string, and can be found at the start, middle or end of the string.
Try this, it will remove all characters before the A[number][number][number][number] and take the first 6 characters after that:
UPDATE app
SET
[...]
FROM imp
INNER JOIN app
ON app.ReceiptId in
(
left(stuff(ref,1, patindex('%A[0-9][0-9][0-9][0-9][ ]%', imp.ref + ' ') - 1, ''), 5),
left(stuff(ref,1, patindex('%A[0-9][0-9][0-9][0-9][0-9][ ]%', imp.ref + ' ') - 1, ''), 6)
)
When using equal, the spaces after is not evaluated

Sum of cost amount calculation

I have attached the screenshot. Most probably that the image itself will explain my logic. Let me paste the code I have used in the fields. Product Info1 field which hold Y & N.
RemainingCosu2=If(Invoice Line Items::Product Info1 = GetAsText ("N"); Sum(Cost Total) - Invoice Line Items::VendPaid_total;0)
RemainingCosu1=If(Vendor Status="Partly Paid"; RemainingCosu2; 0)
What should I do to fix this issue?. Please check the screenshot:
Filemaker has no SumIf() function. You need to create a calculation field in the LineItems table, along the lines of:
If ( Paid = "N" ; Cost )
then sum this field at the invoice level (and/or summarize it at the LineItems table itself), instead of the Cost field.
--
BTW, it is much more convenient to define Boolean (yes/no) fields as Number and use the values of 1 for True, 0 (or empty) for False. Then the calculation can be simply:
If ( not Paid ; Cost )

Delete last N characters from field in a T-SQL Server database

I have table of over 4 million rows and accidentally in one column there is more data than needed.
For example instead of ABC there is ABC DEFG.
How can I remove that N symbols using TSQL? Please note that I want to delete this characters from database, NOT just select substring. Thank you
UPDATE mytable SET column=LEFT(column, LEN(column)-5)
Removes the last 5 characters from the column (every row in mytable)
I got the answer to my own question, ant this is:
select reverse(stuff(reverse('a,b,c,d,'), 1, N, ''))
Where N is the number of characters to remove. This avoids to write the complex column/string twice
You could do it using SUBSTRING() function:
UPDATE table SET column = SUBSTRING(column, 0, LEN(column) + 1 - N)
Removes the last N characters from every row in the column
This should do it, removing characters from the left by one or however many needed.
lEFT(columnX,LEN(columnX) - 1) AS NewColumnName
You can use function RIGHT [https://www.w3schools.com/sql/func_sqlserver_right.asp]
RIGHT( "string" , number_of_chars_from_right_to_left)
That should look like this:
Query: SELECT RIGHT('SQL Tutorial', 3) AS ExtractString;
Result: "ial"

Resources