SQL - Select like string - sql

I have the following table:
create table #tbl
(
PartNumber varchar(20)
)
insert into #tbl values ('003A-I00-1')
insert into #tbl values ('003A-INT-1')
insert into #tbl values ('003A-I1')
insert into #tbl values ('003A-I2')
insert into #tbl values ('003A-I3')
I need to select the highest PartNumber where PartNumber is equal to 003A-I followed only by a number (or numbers). In other words, I need 003A-I3.
What I've tried:
select top 1 partnumber
from #tbl
where partnumber like '003A-I%' + '%[0-9]'
order by partnumber desc
But it doesn't work. It returns 003A-INT-1. I need 003A-I3.
I'm using MS SQL Server 2005.

select top 1 partnumber
from tbl
where partnumber like '003A-I[0-9]%'
order by partnumber desc
SQLFiddle
Update (in response to #Nicarus's comment:
SELECT top 1 partnumber
FROM tbl
WHERE partnumber LIKE '003A-I[0-9]%'
ORDER BY convert(varbinary(200), partnumber) DESC

If you want to get the numeric values, you can use the ISNUMERIC() function of the SQL
The code will be:
select * from #tbl
where isnumeric(replace(partnumber, '003A-I', '')) = 1
order by partnumber desc
REVISE:
ISNUMERIC() function returns Boolean value either true or false (1 or 0).
REPLACE() function replaces a certain pattern in an expression or string
For more information:
http://technet.microsoft.com/en-us/library/ms186862.aspx
http://technet.microsoft.com/en-us/library/ms186272.aspx
UPDATE (2):
You can use the following if you don't want to match a specific word, but as long as you know the text size which would be replaced
select top 1 * from #tbl
where isnumeric(substring(partnumber, 7, LEN(partnumber))) = 1
order by partnumber desc
The link on the SQLFiddle

Related

select string between 3rd and 4th pipe delimiter

I have a column that contains values such as
Column
Asset|Class1|Category1|Group1|Account1
Expense|Class23|Category23|Group23|Account23
I want to select the string between 3rd and 4th occurrence of my pipe delimiter, how can I achieve this?
I've tried the PARSENAME and charindex+stuff function, but they have limitations, like max 128 characters. Also our SQL server has limited regex support. Any ideas?
SELECT REVERSE(PARSENAME(REVERSE(replace(LTRIM(Column), '|', '.')), 3))
My select need to return:
Group1
Group23
Perhaps this will help
Example
Declare #YourTable table (ID int,[Column] varchar(max))
Insert Into #YourTable values
(1,'Asset|Class1|Category1|Group1|Account1')
,(2,'Expense|Class23|Category23|Group23|Account23')
Select ID
,SomeValue = convert(xml,'<x>' + replace([Column],'|','</x><x>')+'</x>').value('/x[3]','varchar(100)')
From #YourTable
Returns
ID SomeValue
1 Category1
2 Category23
You can also use STRING_SPLIT() if you have 2016+
CREATE TABLE T(
ID INT IDENTITY(1,1),
Str VARCHAR(45)
);
INSERT INTO T(Str) VALUES
('Asset|Class1|Category1|Group1|Account1'),
('Expense|Class23|Category23|Group23|Account23');
SELECT V Str
FROM (
SELECT Value V,
ROW_NUMBER() OVER(PARTITION BY ID ORDER BY ID) RN
FROM T CROSS APPLY STRING_SPLIT(Str, '|')
) TT
WHERE RN = 3;
Returns:
Str
---------
Category1
Category23

Tally Table in SQL

I want to create a bunch of data with Tally table in SQL (sql2008) and definitely need help.
First of all, I have this table which contains 2 columns.
{
AcctNum (nchar(30), null),
DataInfo (nchar(745), null)
}
While I don't care the data in the DataInfo column, I do want to add about 10k of row into the table with unique AcctNum on each row.
The problem though is I need to keep the length of the data in both column. For example, AcctNum column looks like "400000000000001 ". how do I increment the number while keep the "blank space"?
Not sure if I make much sense here, but please let me know and I will try to explain more, thanks!
Using a recursive common table expression :
-- set up a table variable for demo purpose
declare #t table (AcctNum nchar(30) null, DataInfo nchar(745) null);
-- insert the starting value
insert #t values ('400000000000001', null);
-- run the cte to generate the sequence
with cte (acctnum, num) as (
select acctnum, cast(acctnum as bigint) + 1 num -- starting value
from #t
union all
select acctnum, num+1 from cte
where num < cast(acctnum as bigint) + 10000 -- stopping value
)
-- insert data sequence into the table
insert #t (AcctNum, DataInfo)
select num, null from cte
option (maxrecursion 10000);
select * from #t;
The table variable #t will now contain acctnum 400000000000001 -> 400000000010001 as a contiguous sequence.

Get the Records as per the given OrderId only

I have a table with Primary key and auto incremented column lets say "HeaderFieldID".
Now i want to get the records as per the HeaderFieldID values.
Ex:
select *
from tblHeaderField
where HeaderFieldID in (2,1,3,4,6,5)
But,by default I am getting the records by HeaderFieldID asc order. But I want records as per the given HeaderFieldID's only.
Original Table
HeaderFieldID HFName DisplayName
1 OrgName1 disp1
2 OrgName2 disp2
3 OrgName3 disp3
4 OrgName4 disp4
5 OrgName5 disp5
6 OrgName6 disp6
Thanks in Advance
I don't know if you can order by IN, because you don't know order.
So first I would split data into rows from IN and then join it to your table.
DECLARE #table TABLE (ID INT IDENTITY(1,1) NOT NULL, NR INT)
--Prodvide data to lookup
DECLARE #givenText VARCHAR(100) = '2,1,3,4,5,6,7,8,9,10,11,12,13,14,15'
-- Split requested string into rows and add unique number
;WITH xmlData (xmlData) AS (
SELECT CAST('<x>'+REPLACE(#givenText, ',', '</x><x>')+'</x>' AS XML) AS xmlData
)
INSERT INTO #table (NR)
SELECT x.value('.','INT') AS NR
FROM xmlData
CROSS APPLY xmlData.xmlData.nodes('//x') AS func(x)
--Join tables to get result
SELECT tHF.*
FROM tblHeaderField AS tHF
INNER JOIN #table AS T
ON T.NR = tHF.HeaderFieldID
ORDER BY T.ID
Isn't clear where does this list come from (as a parameter of a stored procedure or hardcoded in the SQL statement?). Try this query:
select *
from tblHeaderField
where HeaderFieldID in (2,1,3,4,6,5)
ORDER BY
CHARINDEX(','+CAST(HeaderFieldID as varchar(100))+','
,',2,1,3,4,6,5,')
SQLFiddle demo
I have solved my query.
SELECT * FROM tblHeaderField
WHERE HeaderFieldID in (5,6,2,1,3,4,7,8,9,10,11,12,13,14,15)
ORDER BY CHARINDEX(CAST(HeaderFieldID AS VARCHAR), '5,6,2,1,3,4,7,8,9,10,11,12,13,14,15')

Create unique ID based on grouped UserId

trying to write some SQL that does the following.
If I have a user id field, 12345, and there are 10 records for that user, I want to make a field that goes 1234xxxx
where xxxx refers to order of those records, based on a date field, 1 - 10
so 12340001, 12340002, 12340003 etc, up to 12340010
Thoughts?
Here is a method for getting the new value, assuming the userid is a string
select (left(userid, 4)+right(100000 +
row_number() over (partition by userid order by datefield), 4)
)
You can also use this in an update statement, if you want to change the value in the table.
Declare #x Table (Id INT)
INSERT INTO #x (ID) VALUES (1001),(1002),(1003),(1004),(1005)
select * from #x
select (
left(ID, 4)+right(10000 +DENSE_RANK() over ( order by Id), 4)
)
from #x
we can also use dense rank to get desired output

INSERT INTO With a SubQuery and some operations

I'm trying to insert some data to a table contains two things : "a string" and "maximum number in Order column + 1".
This is my query:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (Max([Order]) + 1)
FROM MyTable
What is going wrong with my query?
I'm using Microsoft SQL Server 2005 SP3.
You can test this query like this:
I don't receive error:
create table #MyTable
(
[Text] varchar(40),
[Order] int NOT NULL
)
INSERT INTO #MyTable([Text],[Order])
SELECT 'MyText' [Text], isnull(max([order]) + 1, 0) [Order]
FROM #MyTable
drop table #MyTable
Original:
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
or
INSERT INTO MyTable ([Text],[Order])
SELECT top 1 'MyText' [Text], max([Order]) + 1 [Order]
FROM MyTable
limit is not valid in SQL Server as far as I know.
Cannot insert the value NULL into column 'Order', table 'master.dbo.MyTable'; column does not allow nulls. INSERT fails. The statement has been terminated.
This means that the Order column isn't allowed to be null, and that the Max([Order]) + 1 part of your column returns NULL.
This is because your table is empty, as you already noticed by yourself.
You can work around this by replacing NULL by a real number in the query, using ISNULL():
INSERT INTO MyTable ([Text],[Order])
SELECT 'MyText' , (isnull(Max([Order]),0) + 1)
FROM MyTable
Unless he has a column named OrderBy
then he would have to add / assign all values within that Insert especially if the column does not allow for nulls
sounds like fully qualifying the Insert with the dbo.MyTable.Field may make more sense.
also why are you naming fields with SQL Key words...???
INSERT INTO MyTable ([Text],[Order] Values('MyTextTest',1)
try a test insert first..