How to take values from a column and assign them to other columns - sql

Here's what I have:
DECLARE #keyString2 nvarchar(500)
SET #keyString2 =
(SELECT TOP (1) Key_analysis
FROM testing.dbo.[nameWIthoutSpecialChars])
IF CHARINDEX('Limit of Insurance Relativity Factors' , #keyString2) > 0
EXEC sp_rename 'testing.dbo.nameWIthoutSpecialChars.Key2',
'Limit of Insurance Relativity Factors',
'COLUMN';
Basically what I'm doing with that code is renaming column names
with values that are from a different column. Though, if you see, there's a hardcoded string in CHARINDEX, I'd have to already know what's inside of that variable which makes it a real manual process. I could essentially just hardcode the EXEC and run it over and over without even needing the IF statement.
What I'm trying to accomplish is to rename columns based off of values inside of another.
To make it more clear I have a table like this:
+--------------------------------+---------+---------+
| Description | Column2 | Column3 |
+--------------------------------+---------+---------+
| string value 1, string value2 | | |
+--------------------------------+---------+---------+
| string value 1, string value2 | | |
+--------------------------------+---------+---------+
| string value 1, string value 2 | | |
+--------------------------------+---------+---------+
The values in the "Description" column will be the same throughout the table. What I want to have happen is that those values replace the other columns like so
+--------------------------------+----------------+----------------+
| Description | string value 1 | string value 2 |
+--------------------------------+----------------+----------------+
| string value 1, string value2 | | |
+--------------------------------+----------------+----------------+
| string value 1, string value2 | | |
+--------------------------------+----------------+----------------+
| string value 1, string value 2 | | |
+--------------------------------+----------------+----------------+
The only other caveat here is that there may be more or less string values than the 2 shown, I want to run this through multiple tables. Every table has 10 columns that are just like "Column1" and "Column2" in the example, meaning 10 potential columns that need to be renamed considering how many values are in the "Description" column

Experimental table,I didn't use #temporary table or table variable.
create TABLE bbbb (
Description VARCHAR(30) NOT NULL
,column2 VARCHAR(30)
,column3 VARCHAR(30)
);
INSERT INTO bbbb(Description,column2,column3) VALUES
('string value 1,string value2',NULL,NULL),
('string value 1,string value2',NULL,NULL),
('string value 1,string value2',NULL,NULL);
final query
declare #a varchar(100);
declare #b varchar(100);
set #a=(select distinct PARSENAME(REPLACE(Description,',','.'),1) from bbbb)
set #b=(select distinct PARSENAME(REPLACE(Description,',','.'),2) from bbbb)
EXEC sp_rename '[bbbb].[column2]', #a, 'COLUMN';
EXEC sp_rename '[bbbb].[column3]', #b, 'COLUMN';
select * from bbbb

Related

Replace values in a column for all rows

I have a column with entries like:
column:
156781
234762
780417
and would like to have the following:
column:
0000156781
0000234762
0000780417
For this I use the following query:
Select isnull(replicate('0', 10 - len(column)),'') + rtrim(column) as a from table)
However, I don't know how to replace the values in the whole column.
I already tried with:
UPDATE table
SET column= (
Select isnull(replicate('0', 10 - len(column)),'') + rtrim(column) as columnfrom table)
But I get the following error.
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
The answer to your question is going to depend on the data type of your column. If it is a text column for example VARCHAR then you can modify the value in the table. If it is a number type such as INT it is the value and not the characters which is stored.
We can also express this by saying that "0" + "1" = "01" whilst 0 + 1 = 1.
In either case we can format the value in a query.
create table numberz(
val1 int,
val2 varchar(10));
insert into numberz values
(156781,'156781'),
(234762,'234762'),
(780417,'780417');
/* required format
0000156781
0000234762
0000780417
*/
select * from numberz;
GO
val1 | val2
-----: | :-----
156781 | 156781
234762 | 234762
780417 | 780417
UPDATE numberz
SET val1 = isnull(
replicate('0',
10 - len(val1)),'')
+ rtrim(val1),
val2 = isnull(
replicate('0',
10 - len(val2)),'')
+ rtrim(val2);
GO
3 rows affected
select * from numberz;
GO
val1 | val2
-----: | :---------
156781 | 0000156781
234762 | 0000234762
780417 | 0000780417
select isnull(
replicate('0',
10 - len(val1)),'')
+ rtrim(val1)
from numberz
GO
| (No column name) |
| :--------------- |
| 0000156781 |
| 0000234762 |
| 0000780417 |
db<>fiddle here
Usually, when we need to show values in specificity format these processes are performed using the CASE command or with other functions on the selection field list, mean without updating. In such cases, we can change our format to any format and anytime with changing functions. As dynamic fields.
For example:
select id, lpad(id::text, 6, '0') as format_id from test.test_table1
order by id
Result:
id format_id
-------------
1 000001
2 000002
3 000003
4 000004
5 000005
Maybe you really need an UPDATE, so I wrote a sample query for an UPDATE command too.
update test.test_table1
set
id = lpad(id::text, 6, '0');

How to write SQL Query to remove a given set of special characters from a selected column? [duplicate]

This question already has answers here:
How do you strip a character out of a column in SQL Server?
(4 answers)
Closed 4 years ago.
I have a table [ABCTable]
When I query with
SELECT [XYZ] from [ABCTable]
there is a possibility that [XYZ] set of rows returned might contain - [~], [!], [#], [#], [$], [%], [^], [&], [*], [,], [.] , [?].
Is there a way to write just a SQL Query (not stored procedure or sub routines) to ensure these characters are removed while selecting the needed data ?
Do you want something like
CREATE TABLE T(
ID INT IDENTITY(1,1),
Value VARCHAR(45)
);
INSERT INTO T(Value) VALUES
('.A*B$C#'),
('D#E$,F'),
('.G,H*I#$');
DECLARE #Chars VARCHAR(45) = '#$.,*#';
SELECT *, REPLACE(TRANSLATE(Value, #Chars, REPLICATE(' ', LEN(#Chars))), ' ', '') Result
FROM T;
Returns:
+----+----------+--------+
| ID | Value | Result |
+----+----------+--------+
| 1 | .A*B$C# | ABC |
| 2 | D#E$,F | DEF |
| 3 | .G,H*I#$ | GHI |
+----+----------+--------+
Demo
Note: If you have WhiteSpaces there I suggest that you use CHAR(9) instead as
REPLACE(TRANSLATE(Value, #Chars, REPLICATE(CHAR(9), LEN(#Chars))), CHAR(9), '')

Datetime data type in a CASE expression impacts all other values on SQL Server 2016

I'm attempting to insert a few rows into a table in SQL Server 2016 using the SQL query below. A temp table is used to store the data being inserted, then a loop is used to insert multiple rows into the table.
--Declare temporary table and insert data into it
DECLARE #fruitTransactionData TABLE
(
Category VARCHAR (30),
Species VARCHAR (30),
ArrivalDate DATETIME
)
INSERT INTO #fruitTransactionData ([Category], [Species], [ArrivalDate])
VALUES ('Fruit', 'Apple - Fuji', '2017-06-30')
--Go into loop for each FieldName (there will be 3 rows inserted)
DECLARE #IDColumn INT
SELECT #IDColumn = MIN(ID) FROM FieldNames
WHILE #IDColumn IS NOT NULL
BEGIN
--Insert data into Transactions
INSERT INTO [dbo].[Transactions] ([FieldName], [Result])
SELECT
(SELECT Name FROM FieldNames WHERE ID = #IDColumn),
CASE
WHEN #IDColumn = 1 THEN 1 --Result insert for FieldName 'Category' where ID=1 refers to 'Fruits'
WHEN #IDColumn = 2 THEN 99 --Result insert for FieldName 'Species' where ID=99 refers to 'Apple - Fuji'
WHEN #IDColumn = 3 THEN [data].[ArrivalDate] --Result insert for FieldName 'Date'
ELSE NULL
END
FROM
#fruitTransactionData [data]
--Once a row has been inserted for one FieldName, then move to the next one
SELECT #IDColumn = MIN(ID)
FROM FieldNames
WHERE ID > #IDColumn
END
When inserting the data, the data is inserted, but all the results show dates, when some data weren't meant to be dates.
+-----+------------+---------------------+
| ID | FieldName | Result |
+-----+------------+---------------------+
| 106 | Category | Jan 2 1900 12:00AM |
| 107 | Species | Apr 10 1900 12:00AM |
| 108 | Date | Jun 30 2017 12:00AM |
+-----+------------+---------------------+
If I comment out the row insert of the date, the columns display correctly.
+-----+------------+--------+
| ID | FieldName | Result |
+-----+------------+--------+
| 109 | Category | 1 |
| 110 | Species | 99 |
+-----+------------+--------+
It seems like the insertion of the date converts all the result values to datetime format (eg. Jan 2 1900 12:00 is a conversion of the number 1).
The result I'm trying to get as opposed to the above results is this:
+-----+------------+---------------------+
| ID | FieldName | Result |
+-----+------------+---------------------+
| 106 | Category | 1 |
| 107 | Species | 99 |
| 108 | Date | Jun 30 2017 12:00AM |
+-----+------------+---------------------+
Just for clarification, the Transaction table schema is as follows:
[ID] INT IDENTITY(1, 1) CONSTRAINT [PK_Transaction_ID] PRIMARY KEY,
[FieldName] VARCHAR(MAX) NULL
[Result] VARCHAR(MAX) NULL
SQL Server is making a guess at the data type for the CASE statement. It does this based on its internal precedence order for data types and the following case statement return type rule:
the highest precedence type from the set of types in
result_expressions and the optional else_result_expression.
Since int has a lower precedence order than datetime SQL Server is choosing to use a datetime return type.
Ultimately explicitly normalizing the data types of your case statement to varchar will solve the issue:
CASE WHEN #IDColumn = 1 THEN '1'
WHEN #IDColumn = 2 THEN '99'
WHEN #IDColumn = 3 THEN FORMAT([data].[ArrivalDate]), 'Mon d yyyy h:mmtt')
ELSE NULL
END
In case you are interested SQL Server uses the following precedence order for data types:
user-defined data types (highest)
sql_variant
xml
datetimeoffset
datetime2
datetime
smalldatetime
date
time
float
real
decimal
money
smallmoney
bigint
int
smallint
tinyint
bit
ntext
text
image
timestamp
uniqueidentifier
nvarchar (including nvarchar(max) )
nchar
varchar (including varchar(max) )
char
varbinary (including varbinary(max) )
binary (lowest)
It is converting the format because all types in a CASE should have the same format. I think you want to convert the date as a string (and the numbers too).
SELECT
,(SELECT Name FROM FieldNames WHERE ID=#IDColumn)
,CASE WHEN #IDColumn=1 THEN '1' --Result insert for FieldName 'Category' where ID=1 refers to 'Category Fruits'
WHEN #IDColumn=2 THEN '99' --Result insert for FieldName 'Species' where ID=99 refers to 'Apple - Fuji'
WHEN #IDColumn=3 THEN convert(varchar(MAX), [data].[ArrivalDate], 23) --Result insert for Field Name 'Date'
ELSE null
END
FROM #fruitTransactionData [data]
This is too long for a comment.
What you are trying to do just doesn't make sense. The columns you are inserting into are defined by:
INSERT INTO [dbo].[Transactions]([FieldName], [Result])
---------------------------------^ -----------^
The INSERT is inserting rows with two values, one for "FieldName" and the other for "Result".
So the SELECT portion should return two columns, no more, no fewer. Your SELECT appears to have four. Admittedly, the first two are syntactically incorrect CASE expressions, so the count might be off.
It is totally unclear to me what you want to do, so I can't make a more positive suggestion.

Get rows where value is not a substring in another row

I'm writing recursive sql against a table that contains circular references.
No problem! I read that you can build a unique path to prevent infinite loops. Now I need to filter the list down to only the last record in the chain. I must be doing something wrong though. -edit I'm adding more records to this sample to make it more clear why just selecting the longest record doesn't work.
This is an example table:
create table strings (id int, string varchar(200));
insert into strings values (1, '1');
insert into strings values (2, '1,2');
insert into strings values (3, '1,2,3');
insert into strings values (4, '1,2,3,4');
insert into strings values (5, '5');
And my query:
select * from strings str1 where not exists
(
select * from strings str2
where str2.id <> str1.id
and str1.string || '%' like str2.string
)
I'd expect to only get the last records
| id | string |
|----|---------|
| 4 | 1,2,3,4 |
| 5 | 5 |
Instead I get them all
| id | string |
|----|---------|
| 1 | 1 |
| 2 | 1,2 |
| 3 | 1,2,3 |
| 4 | 1,2,3,4 |
| 5 | 5 |
Link to sql fiddle: http://sqlfiddle.com/#!15/7a974/1
My problem was all around the 'LIKE' comparison.
select * from strings str1
where not exists
(
select
*
from
strings str2
where
str2.id <> str1.id
and str2.string like str1.string || '%'
)

How to add a null row in sql server2008r2

I want to add a row that serves like a space between data in sql...
ID num | owner | time in | time out |
<-- space /row
255414 | anne | 7:45 | 6:00 |
<-- space / row
141455 | jane | 8:00 | 5:30 |
If you want to achieve this, you must not set any integrity constraint in your schema definition and declare all the fields as varchar. Then you can insert a null row like this.
INSERT INTO YOUR_TABLE VALUES ('', '', '', '');
This will create a seperator in your database.
If you are using integer in your columns, you must pass all values as NULL while inserting into database. Somthing like this:-
INSERT INTO YOUR_TABLE VALUES (NULL, '', NULL, NULL);
Just Add or Pass null values using insert query. But if you have Identity column it will be incremented. Or Just add a row or separate column which will flag a end of group of rows.