I have a question about SQL Server: how to add leading three 000 (zeros) while id does not have leading zeros in SQL Server?
CREATE TABLE [dbo].[ids]
(
[id] [VARCHAR](50) NULL,
[name] [VARCHAR](50) NULL
) ON [PRIMARY]
GO
INSERT INTO [dbo].[ids] ([id], [name]) VALUES (N'09', N'abc')
GO
INSERT INTO [dbo].[ids] ([id], [name])
VALUES (N'0098', N'de'), (N'987', N'j'), (N'00056', N'i'),
(N'6', N'z'), (N'0908', N'u'),
(N'99999999', N'u'), (N'7522323838483', N'i')
GO
Based on above data I want output like below :
name | id
--------+-----------
abc | 0009
de | 00098
j | 000987
i | 00056
z | 0006
u | 000908
u | 00099999999
i | 0007522323838483
I tried like this:
SELECT
RIGHT('000' + id, 3) id, [name]
FROM
[dbo].[ids]
but above query is not returning the expected result.
Can you please tell me how to write a query to achieve this task in SQL Server?
You could try stripping leading zeroes, then concatenating three zeroes to the front, e.g.
SELECT
id,
'000' + SUBSTRING(id, PATINDEX('%[^0]%', id + '.'), LEN(id)) AS id_out,
name
FROM ids;
Demo
Just another thought is to use try_convert() if your ID strings are are numeric
Example
Select *
,NewValue = '000'+left(try_convert(bigint,id),25)
From ids
Returns
id name NewValue
09 abc 0009
0098 de 00098
987 j 000987
00056 i 00056
6 z 0006
0908 u 000908
99999999 u 00099999999
7522323838483 i 0007522323838483
You can use format(), with '0' as a custom specifier to do this very simply.
select NOPER, FORMAT( NOPER, '000000') as NOPER_formatted
from mytable
NOPER NOPER_formatted
----------- ------------------------------------
100 000100
101 000101
102 000102
10334 010334
10335 010335
10336 010336
For more information see the link below :
https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings
Related
I need help understanding how to add a hyphen to a column where the values are as follows,
8601881, 9700800,2170
The hyphen is supposed to be just before the last digit. There are multiple such values in the column and the length of numbers could be 5,6 or more but the hyphen has to be before the last digit.
Any help is greatly appreciated.
The expected output should be as follows,
860188-1,970080-0,217-0
select concat(substring(value, 1, len(value)-1), '-', substring(value, len(value), 1)) from data;create table data(value varchar(100));
Here is the full example:
create table data(value varchar(100));
insert into data values('6789567');
insert into data values('98765434');
insert into data values('1234567');
insert into data values('876545');
insert into data values('342365');
select concat(substring(value, 1, len(value)-1), '-', substring(value, len(value), 1)) from data;
| (No column name) |
| :--------------- |
| 678956-7 |
| 9876543-4 |
| 123456-7 |
| 87654-5 |
| 34236-5 |
In case OP meant there can be multiple numbers in the column value here is the solution:
create table data1(value varchar(100));
insert into data1 values('6789567,5467474,846364');
insert into data1 values('98765434,6474644,76866,68696');
insert into data1 values('1234567,35637373');
select t.value, string_agg(concat(substring(token.value, 1, len(token.value)-1), '-',
substring(token.value, len(token.value), 1)), ',') as result
from data1 t cross apply string_split(value, ',') as token group by t.value;
value | result
:--------------------------- | :-------------------------------
1234567,35637373 | 123456-7,3563737-3
6789567,5467474,846364 | 678956-7,546747-4,84636-4
98765434,6474644,76866,68696 | 9876543-4,647464-4,7686-6,6869-6
Using SQL SERVER 2017, you can leverage STRING_SPLIT, STUFF, & STRING_AGG to handle this fairly easily.
DECLARE #T TABLE (val VARCHAR(100)) ;
INSERT INTO #T (val) VALUES ('8601881,9700800,2170') ;
SELECT t.val,
STRING_AGG(STUFF(ss.value, LEN(ss.value), 0, '-'), ',') AS Parsed
FROM #T AS t
CROSS APPLY STRING_SPLIT(t.val, ',') AS ss
GROUP BY t.val ;
Returns
8601881,9700800,2170 => 860188-1,970080-0,217-0
STRING_SPLIT breaks them into individual values, STUFF inserts the hyphen into each individual value, STRING_AGG combines them back into a single row per original value.
You can use LEN and LEFT/RIGHT method to get your desired output. Logic are given below:
Note: this will work for any length's value.
DECLARE #T VARCHAR(MAX) = '8601881'
SELECT LEFT(#T,LEN(#T)-1)+'-'+RIGHT(#T,1)
If you have "dash/hyphen" in your data, and you have to store it in varchar or nvarchar just append N before the data.
For example:
insert into users(id,studentId) VALUES (6,N'12345-1001-67890');
I have created a map table to find various unique strings within a large list of unique hostnames.
The initial code works if I enter the various lengths i.e. varchar(2), varchar(11), etc. It's trying to reference the variable lengths is where my issues began.
I have tried several different combinations before attempting to use a variable.
For example in the where clause, substituting the varchar(2) with the m.[HostNameAlias_IDLength]
I am also having difficulty using variables.
Any thoughts would be much appreciated.
TM
P.S. A listing of the code and sample tables are listed below.
Table1
HostNameAlias_id (pk, varchar(5), not null)
ProjectName_ID (int, not null)
HostnameAlias_IDLength (computed, int, null)
Data
HostNameAlias_ID ProjectName_ID HostNameAlias_IDLength
----------------------------------------------------------
H123456789023456 16009 16
B123456789023 16005 13
C1234567890 16009 11
d12345678 16009 9
e123456 16009 8
f12345 16003 6
g1234 16035 5
h123 16035 4
j12 16005 3
k1 16007 2
Table2
[host name] (pk, nvarchar(50), not null
Projectname_id (int, not null)
Sample data:
Host name Title projectname_ID
--------------------------------------------------
C1234567890a1 vp 16009
C1234567890a2 avp 16009
h12335 student 16009
h12356 teacher 16009
h12357 prof 16009
Query
DECLARE #len = INT()
DECLARE #slen = VARCHAR(2);
SELECT DISTINCT
#len = m.[HostNameAlias_IDLength],
#slen = CONVERT(varchar(2), m.[HostNameAlias_ID]),
c.[Host Name],
m.[projectname_id]
FROM
[table1] c
JOIN
[table2] m ON c.[projectname_id] = m.[projectname_id]
WHERE
CONVERT(varchar(2), [Host Name]) IN (SELECT [HostNameAlias_ID]
FROM [table2])
The length of a result cannot be known in the where clause used to discover that length, so I fail to see why you are attempting this. In addition the column [Host Name] is a varchar(16) so you could encounter up to 16 characters, so just use that maximum ... if the conversion is needed at all.
Below I have just used LIKE instead of IN, perhaps that will assist.
SQL Fiddle
MS SQL Server 2014 Schema Setup:
CREATE TABLE Table1
([HostNameAlias_ID] varchar(16), [ProjectName_ID] int, [HostNameAlias_IDLength] int)
;
INSERT INTO Table1
([HostNameAlias_ID], [ProjectName_ID], [HostNameAlias_IDLength])
VALUES
('H123456789023456', 16009, 16),
('B123456789023', 16005, 13),
('C1234567890', 16009, 11),
('d12345678', 16009, 9),
('e123456', 16009, 8),
('f12345', 16003, 6),
('g1234', 16035, 5),
('h123', 16035, 4),
('j12', 16005, 3),
('k1', 16007, 2)
;
CREATE TABLE Table2
([HostName] varchar(13), [Title] varchar(7), [projectname_ID] int)
;
INSERT INTO Table2
([HostName], [Title], [projectname_ID])
VALUES
('C1234567890a1', 'vp', 16009),
('C1234567890a2', 'avp', 16009),
('h12335', 'student', 16009),
('h12356', 'teacher', 16009),
('h12357', 'prof', 16009)
;
Query 1:
SELECT
m.[HostName]
, c.[HostNameAlias_ID]
, m.[projectname_id]
, c.[HostNameAlias_IDLength]
FROM [table1] c
JOIN [table2] m ON c.[projectname_id] = m.[projectname_id]
WHERE [HostName] LIKE ([HostNameAlias_ID] + '%')
Results:
| HostName | HostNameAlias_ID | projectname_id | HostNameAlias_IDLength |
|---------------|------------------|----------------|------------------------|
| C1234567890a1 | C1234567890 | 16009 | 11 |
| C1234567890a2 | C1234567890 | 16009 | 11 |
re: [Host name] including spaces in column names is a complication that can and should be avoided, so I have used [HostName] instead.
I have a table Table which have some columns and I want to convert column values as columns for another table.
I am attaching one screen shot of my requirement.
The upper table is my main table say Table1 and the below is my required table.
Thanks
Whilst the suggested duplicate will get you part of the way there, you actually need to unpivot then pivot, like this.
(Oh and please don't post images. DDL is appreciated and saves us typing and/or guessing.)
CREATE TABLE #Test( Action char, [Key] INT, Old varchar(5), OldValue varchar(5), New varchar(5), NewValue varchar(5));
INSERT INTO #Test VALUES
('U', 123, 'Col1','Dog','Col1','Dog'),
('U', 123, 'Col2','Cat','Col2','Mouse'),
('U', 123, 'Col3','Honey','Col3','Bee'),
('I', 123, NULL,NULL,'Col45','Sun');
SELECT PVT.Action
,PVT.[Key]
,PVT.OldCol1
,PVT.OldCol2
,PVT.OldCol3
,PVT.NewCol1
,PVT.NewCol2
,PVT.NewCol3
,PVT.NewCol45 FROM (
SELECT [Action]
,[Key]
,Label
,Value
FROM #Test
CROSS APPLY (VALUES ('Old'+Old, OldValue), ('New'+New, NewValue)) c(label, value)
)src
PIVOT
(
MAX(VALUE) FOR Label IN (OldCol1, NewCol1, OldCol2, NewCol2, OldCol3, NewCol3, NewCol45)
)PVT
ORDER BY PVT.Action Desc
Action Key OldCol1 OldCol2 OldCol3 NewCol1 NewCol2 NewCol3 NewCol45
------ ----------- ------- ------- ------- ------- ------- ------- --------
U 123 Dog Cat Honey Dog Mouse Bee NULL
I 123 NULL NULL NULL NULL NULL NULL Sun
(2 row(s) affected)
I guess pivoting will be enough:
SELECT *
FROM (
SELECT [Action], [Key], 'Old' + Old as [a], OldValue as [Value]
FROM Table1
UNION ALL
SELECT [Action], [Key], 'New' + New, NewValue
FROM Table1
) as p
PIVOT (
MAX([Value]) FOR [a] IN ([OldCol1],[OldCol2],[OldCol3],[NewCol1],[NewCol2],[NewCol3],[NewCol45])
) as pvt
Output:
Action Key OldCol1 OldCol2 OldCol3 NewCol1 NewCol2 NewCol3 NewCol45
I 123 NULL NULL NULL NULL NULL NULL Sun
U 123 Dog Cat Honey Dog Mouse Bee NULL
If there are MANY Old and 'New` values then you need dynamic SQL
I'm working on a stored procedure, and it's not working as I would expect. Looking for a fresh set of eyes to see what I am missing. I am populating a table with some distinct values, and if those values don't exist in the table I'm inserting into, then do it. Don't want dupes. The list of values has rows, but it is not inserting into the target table.
declare #DistinctTable table (tableName varchar(30))
insert into #DistinctTable (tableName) (SELECT DISTINCT Reference FROM dbo.Tmp_Import_Rows)
INSERT INTO [dbo].[TargetTable]
(RowID
,A
,B
,C
,D
,E
,F
,G
,User
,Machine
,Date
,TableRef)
(SELECT NEWID(),
0,
0,
0,
0,
0,
0,
0,
#pUserName,
HOST_NAME(),
getdate(),
tableName
FROM #DistinctTable
WHERE (tableName NOT IN (select [TableRef] from [TargetTable] )))
As I said, I'm getting rows into #DistinctTable, but they won't insert into [TargetTable]. I feel like I'm overlooking something small. Any advice would be great, thank you.
Edit: Sample data
dbo.TargetTable
RowId, TableReferecne| Inches | Volume | Unused | Unused | Unused | Unused | UserName | MACHINE | DATE | Table#
897e0a1f-f139-4c1d-9bac-0a64518cd56a, Table50, 12,20,0,0,0,0,someuser, somemachine, 4-24-15, Table50
dbo.Tmp_Import_Rows
TableReference | Inches| Volume | Table #
Table60 | 60 | 1000 | Table 60
Table70 | 70 | 1100 | Table 70
#DistinctTable is populated with unique values, On [Table #]
tableName
Table60
Table70
What I want it to do, is Get Distinct values from Tmp_Import_rows, and if those values don't exist in TargetTable, Insert it.
Try WHERE NOT EXISTS instead of NOT IN and see if you get anything in return:
SELECT *
FROM #DistinctTable t1
WHERE NOT EXISTS (
SELECT 1
FROM [dbo].[TargetTable] t2
WHERE t1.tableName = t2.tableRef
);
Don't you need the keyword VALUES in there?
e.g. insert into table (col1,col2,col3...) values (val1,val2,val3...) etc?
I tried to use the GROUP_CONCAT function in SQL Server 2000 but it returns an error:
'group_concat' is not a recognized function name"
So I guess there is an other function for group_concat in SQL Server 2000? Can you tell me what it is?
Unfortunately since you are using SQL Server 2000 you cannot use FOR XML PATH to concatenate the values together.
Let's say we have the following sample Data:
CREATE TABLE yourtable ([id] int, [name] varchar(4));
INSERT INTO yourtable ([id], [name])
VALUES (1, 'John'), (1, 'Jim'),
(2, 'Bob'), (3, 'Jane'), (3, 'Bill'), (4, 'Test'), (4, '');
One way you could generate the list together would be to create a function. A sample function would be:
CREATE FUNCTION dbo.List
(
#id int
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #r VARCHAR(8000)
SELECT #r = ISNULL(#r+', ', '') + name
FROM dbo.yourtable
WHERE id = #id
and Name > '' -- add filter if you think you will have empty strings
RETURN #r
END
Then when you query the data, you will pass a value into the function to concatenate the data into a single row:
select distinct id, dbo.list(id) Names
from yourtable;
See SQL Fiddle with Demo. This gives you a result:
| ID | NAMES |
-------------------
| 1 | John, Jim |
| 2 | Bob |
| 3 | Jane, Bill |
| 4 | Test |