How to get a value with leading zero's - sql

Table1
ID (NVarchar Column)
01
02
03
...
Query
Select max(id) from table1
Ouput is
3
I want to get maximum id with leading zero, if it is 002 means, the query should return 002
Expected Output is
03
How to do this
Need Query Help

I executed the following piece of code:
DECLARE #TABLE TABLE (
ID nvarchar(10)
)
INSERT #TABLE VALUES ( '003' )
INSERT #TABLE VALUES ( '004' )
SELECT MAX (ID)
FROM #TABLE
The output was
004
When using the data type as int however:
DECLARE #TABLE TABLE (
ID int
)
INSERT #TABLE values ( '003' )
INSERT #TABLE VALUES ( '004')
SELECT MAX (ID )
FROM #TABLE
The output was:
4
I would check you have your data types defined correctly.

To get the idea: Select right('000' + max(id),2) from table1

You can write the query as following:
declare #input int, #len int
set #len = 2
select right(REPLICATE('0',#len)+convert(varchar(5),2),#len ) AS LPAD
I am assuming that you know the length all the time. You can make it a UDF as well.

Related

Assign multiple values to Table variable in SQL

DECLARE #ID INT
SET #ID = (select top 1 USER_REQ_JOB_ID
from T8504_USER_REQ_JOB
where JOB_GRP_ID = 160
order by LST_UPDT_TS desc)
SELECT INPUT_PARM_VAL_TX
from TBL_RPT_JOB_INPUT_PARAM
where USER_REQ_JOB_ID = #ID
This returns these results:
USA
USCC
6
7
2
These five records what I get I want to assign to five different variables to use in stored procedure.
I was trying with table variable like this :
declare #CID table (
Region Char(3)
,Segment Char(3)
,MasterContractId int
,ctcid int
,templateid int)
insert into #CID (Region,Segment,MasterContractId,ctcid,templateid)
But how to insert that 5 rows here?
INSERT INTO #CID
select * from
(
select
'Temp' + convert(char(1), row_number() over (order by (select 0))) as columnName,
INPUT_PARM_VAL_TX as Value
from TBL_RPT_JOB_INPUT_PARAM where USER_REQ_JOB_ID = #ID
) d
pivot
(
max(value)
for columnname in (Temp1, Temp2, Temp3, Temp4, Temp5)
) piv;
See if this helps.
Take a look at this fiddle for an example.
Courtesy:
Add row number to this T-SQL query
Efficiently convert rows to columns in sql server
EDIT: The sql adds an extra column to generate row numbers to use it as an extra column, which is pivoted as column heading.
it's really gross, but one way you could probably do it is this (though you'll need to apply it to your case):
http://sqlfiddle.com/#!6/d41d8/21507
declare #table TABLE (value varchar(50))
INSERT INTO #table
VALUES ('first')
INSERT INTO #table
VALUES ('second')
INSERT INTO #table
VALUES (3)
INSERT INTO #table
VALUES (4)
DECLARE #temp TABLE (id int identity(1,1), value varchar(50))
INSERT INTO #temp
SELECT [value]
FROM #table t
SELECT *
FROM #temp
DECLARE #CID TABLE (Region varchar(50), cont varchar(50), another int, andAnother int)
INSERT INTO #CID
(
Region,
cont,
another,
andAnother
)
VALUES
(
(SELECT value FROM #temp WHERE id = 1), -- Region - varchar
(SELECT value FROM #temp WHERE id = 2), -- cont - varchar
(SELECT value FROM #temp WHERE id = 3), -- another - int
(SELECT value FROM #temp WHERE id = 4) -- andAnother - int
)
SELECT * FROM #cid
note that i assumed you're using mssql, you did not specify

Is there a way to return more than 1 row in select without using existing tables

Simple question, just out of curiosity.
For example select 1,2,3 that will show table with one column and three rows.
Something like this: select values(1),(2),(3)
*with one select statement
An example for my comment in your post.
DECLARE #TABLE TABLE (ONE INT, TWO INT, THREE INT)
INSERT INTO #TABLE VALUES (1,2,3)
SELECT UP.COL, UP.VALUE
FROM #TABLE
UNPIVOT (VALUE FOR COL IN (ONE,TWO,THREE)) UP
Query:
DECLARE #t TABLE (i1 INT, i2 INT, i3 INT)
INSERT INTO #t VALUES (1, 2, 3)
SELECT t.*
FROM #t
CROSS APPLY (
VALUES(i1), (i2), (i3)
) t(value)
Output:
value
-----------
1
2
3
Additional info:
http://blog.devart.com/is-unpivot-the-best-way-for-converting-columns-into-rows.html
As it appears there is a simple code that I've been searching for:
select n from (values (1),(2),(3)) D(c);

SQL scalar variable value between and

'Names' in table 'Data'
"type12pen105A"
"type12pen110A"
"type12pen121B"
Declare #n int;
select Names From Data
where Names ='type12pen'+cast(#n between 100 and 110 as varchar)+'A'
My Required out put is
"type12pen105A"
"type12pen110A"
SELECT Names
FROM Data
WHERE Names LIKE 'type12pen%'
AND CAST(SUBSTRING(Names,10,3) AS INT) BETWEEN 100 AND 110
AND RIGHT(Names,1) = 'A'
Based on the info you provided, this is ugly but it should work:
create table #data
(
names varchar(50)
)
insert into #data values('type12pen105A')
insert into #data values('type12pen101A')
insert into #data values('type12pen112A')
insert into #data values('type12pen120A')
insert into #data values('type12pen110A')
insert into #data values('type12pen106A')
insert into #data values('type12pen110C')
insert into #data values('type12pen110D')
insert into #data values('type12pen110E')
insert into #data values('type12pen121B')
SELECT Names
FROM #Data
WHERE Names LIKE 'type12pen%'
AND RIGHT(Names,1) = 'A'
AND replace(replace(names, 'type12pen', ''), 'A', '') BETWEEN 100 AND 110
drop table #data
results:
type12pen105A
type12pen101A
type12pen110A
type12pen106A
declare #Data table(
name varchar(32)
)
insert into #Data values('type12pen105A')
insert into #Data values('type12pen110A')
insert into #Data values('type12pen121B')
insert into #Data values('book11jil124C')
select name
from #Data
where cast(substring(name, 10, 3) as int) between 100 and 110
and name like 'type12pen%'
and right(name, 1) = 'A'
If this is a large table you'd probably be better served by running a process on the data and splitting the different aspects of the product name out into individual fields and querying on those. Using substring and right means you won't get the benefit of indexes.

distance between given set and some other sets - sql server 2005

I have a table which contains the item and category ids:
create table SomeTable (
ItemId int,
CategoryId int
)
Given some category ids (Set X) I would like to determine all item ids that share at least one category id and some stats for each of these item ids:
A – Number of category ids of item id that are not in set x
B – Number of category ids shared between item id and set x
C – Number of category ids in set x but which are not associated with item id
I have written some tsql code which involves a cross join and several ctes plus left joins. It works but is fairly slow.
I am sure someone must have encountered a similar problem. I would provide the code but the above description is simplified. Thanks.
Here's a couple of ideas. (I don't know how they'll compare performance wise with what you have already. Left for you to benchmark.)
set nocount on;
-- create a sample table
declare #T table ( ItemId int identity(1,1), CategoryId int );
insert #T values ( 100 );
insert #T values ( 100 );
insert #T values ( 100 );
insert #T values ( 100 );
insert #T values ( 100 );
insert #T values ( 200 );
insert #T values ( 200 );
insert #T values ( 300 );
insert #T values ( 300 );
insert #T values ( 300 );
insert #T values ( 300 );
insert #T values ( 500 );
insert #T values ( 500 );
insert #T values ( 500 );
insert #T values ( 600 );
insert #T values ( 700 );
insert #T values ( 800 );
insert #T values ( 800 );
insert #T values ( 800 );
insert #T values ( 900 );
-- grab some CategoryIDs to work with
declare #X table ( CategoryId int );
insert #X
select CategoryID=200 union
select CategoryID=400 union
select CategoryID=600 union
select CategoryID=800
-- A. Number of category ids of item id that are not in set x
select distinct t.CategoryID from #T t
where not exists(select 1 from #X x where t.CategoryID = x.CategoryID)
-- or, using the set difference operator
select CategoryID from #T
except
select CategoryID from #X
-- B. Number of category ids shared between item id and set x
select distinct x.CategoryID from #X x
join #T t on t.CategoryID = x.CategoryID;
-- or, using set intersection
select CategoryID from #T
intersect
select CategoryID from #X
-- C. Number of category ids in set x but which are not associated with item id
select distinct x.CategoryID from #X x
where not exists(select 1 from #T t where t.CategoryID = x.CategoryID)
-- or, using the set difference operator
select CategoryID from #X
except
select CategoryID from #T
The problem with CTE is they are run each time they are referenced and do not have constraints. Load your Set X into a temporary table with primary key on ID. Then run the same joins against the temporary and you should see big performance gain. SQL does much better when joins are based on primary keys.

Combine multiple SQL fields into 1 output row

Having a SQL table like
UserID |Attribute | Value
1 |Username | Marius
1 |Password | Fubar
I want to create an output like:
1 | Marius | Fubar
Maybe I'm just too tired to see it, doesn't sound too complicated, but I just can't seem to figure it out. Any help is appreciated.
Why don't you use self joins, ie. :
select u1.userid, u1.value, u2.value
from yourtable u1
inner join yourtable u2 on u2.userid=u1.userid
where u1.attribute='Username' and u2.attribute='Password';
Would something like...
SELECT userID,
GROUP_CONCAT (Value SEPARATOR '|')
FROM my_table
GROUP BY UserID;
be what you are looking for?
If you keep your data that way, you will need to do a crosstab query and pivot your rows into columns. If you are using Microsoft SQL Server, check out "crosstab query" and the pivot operator in Books Online.
Edited:
One column per result:
If you try to combine multiple Attributes with the same UserID it would be something like this:
Short query (one UserID):
declare #concattedtext varchar(1000)
SELECT #concattedtext=coalesce(#concattedtext + '|', '') + Value
FROM #users WHERE UserID=1
SELECT #concattedtext
RESULT with your example data:
1 | Marius | Fubar
Full query (all UserID's)
-- Your source table
CREATE Table #users (UserID int, Attribute varchar(50), Value varchar(50))
-- some entries
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test1', 'attr1')
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test2', 'attr2')
INSERT into #users (UserID, Attribute, Value)
VALUES (1, 'Test3', 'attr3')
INSERT into #users (UserID, Attribute, Value)
VALUES (2, 'Test4', 'attr4')
-- ids table variable (for distinct UserID's)
DECLARE #ids TABLE
(
rownum int IDENTITY (1, 1) Primary key NOT NULL,
UserID int
)
-- Output table variable
DECLARE #out TABLE
(
rownum int IDENTITY (1, 1) Primary key NOT NULL,
UserID int,
ConcatText varchar(1000)
)
-- get distinct id's
INSERT INTO #ids(UserID)
SELECT DISTINCT(UserID) FROM #users
-- Foreach vars
declare #RowCnt int
declare #MaxRows int
select #RowCnt = 1
select #MaxRows=count(*) from #ids
-- UserID
declare #id int
declare #concattedtext varchar(1000)
-- process each id
while #RowCnt <= #MaxRows
begin
SET #id = 0
SELECT #id=UserID
FROM #ids WHERE rownum=#RowCnt
SET #concattedtext = CONVERT(nvarchar(50), #id)
FROM #ids WHERE rownum=#RowCnt
SELECT #concattedtext=coalesce(#concattedtext + '|', '') + Value
FROM #users WHERE UserID=#id
INSERT INTO #out(UserID, ConcatText)
VALUES (#id, #concattedtext)
-- next UserID
Select #RowCnt = #RowCnt + 1
end
SELECT * FROM #out
DROP TABLE #users
Result:
rownum|UserID|ConcatTex
1 | 1 |1|attr1|attr2|attr3
2 | 2 |2|attr4
DROP TABLE #users
You might need a sort field to get your parameters in your requested order.
Multiple columns
Your data needs to have an equal count of attributes if you like to get a table with multiple columns. And you still need to take care about the ordering.
In this case a hardcoded query with a group by would be your choice.