Concatenate different variables with number values in SQL Server - sql-server-2012

I have different variables with string values, that I simply want to concatenate into one number.
For example I have the following variables:
pupil_id, class, term, id should result into Pupil_class_id
23 8 3 23 8323
I tried:
Select
pupil_id, class, term, id,
concat(class + term + id) as Pupil_class_id
from
school
and I tried
concat(class, term, id) as Pupil_class_id
from school
and I tried
concat('class', 'term' 'id') as Pupil_class_id
from school
I would have thought that solution 1 or 2 work, but they don't
Any suggestions?
No errors, but also no result, just 0

The approach with using a comma (,) as separator, and specifying the column names without single quotes is the way to do. I cannot reproduce any problems with that - not sure why you say this didn't work for you....
Try this (I'm using SQL Server 2016, but this should work from 2012 on):
DECLARE #Input TABLE (pupil_id INT, class INT, term INT, id INT)
INSERT INTO #Input (pupil_id, class, term, id)
VALUES (23, 8, 3, 23)
SELECT
CONCAT(class, term, id)
FROM
#Input
I get this output:
(No column name)
8323
which - if I understand correctly - is what you're looking for.
The only reason this might not work is if you're using an "old" database, e.g. if your database compatibility level is set to an earlier version of SQL Server. Was this database "upgraded" from a previous version of SQL Server?
Try this:
SELECT compatibility_level
FROM sys.databases
WHERE database_id = DB_ID()
What value do you get?? SQL Server 2012 should be "110" - do you have a lower value?

Related

How to get the data in SQL Server for string concat value compare to int value without using like operator

I have table with data like this:
Id | StringValue
----+-------------
1 | 4,50
2 | 90,40
I will get input StringValue like 4. I need to fetch the data exact matched record. When I am using LIKE operator, select query is returning two rows, but I need exact matched data record only.
Can anybody please help me with this?
SELECT *
FROM Table1
WHERE StringValue like '%4%'
But that returns two rows - both ID 1 and 2.
My expectation is I need to get ID = 1 row only
Storing delimited data like this is a well documented anti-pattern, violates basic normalisation principles and prevents the database engine from fully utilising an index.
What you can do is delimit your search value and also ensure the expression to search is correctly delimited; this is an unsargable expression however and the strorage engine will have to scan all rows every time -
declare #valueToFind varchar(10) = '4';
select *
from t
where Concat(',', t.StringValue, ',') like Concat('%,' #valueToFind, ',%');
for SQL Server 2016 and later you can use STRING_SPLIT or earlier version of SQL Server, there are many alternative, just do a search for it.
Or, you can simply do
SELECT * FROM Table1 where ',' + StringValue + ',' like '%,4,%'

Query to find results starting with a number or higher - SQL Server

Example: http://sqlfiddle.com/#!18/7f3df/2
CREATE TABLE Table1 (
Reg uniqueidentifier
);
INSERT INTO Table1 (Reg)
Values
('DF215E10-8BD4-4401-B2DC-99BB03135F2E'),
('93015E10-8BD4-4401-B2DC-99BB03135F2E'),
('21215E10-8BD4-4401-B2DC-99BB03135F2E');
Query:
select * from Table1
WHERE left(CAST(Reg AS CHAR(36)),1) > 8
I need to create a query that finds all results that start with either a number 8 or higher or starts with a letter but i am getting a conversion error i cant find a fix for. The column is a uniqueidentifier. How can i cast this to something i can filter on?
Can anyone give some advice on a solution to this?
Thanks
You need to do the comparison using strings:
convert(varchar(36), newid()) like '[89ABCDEF]%'
You may use SQL Server's enhanced LIKE here, which has some basic regex support:
SELECT *
FROM table1
WHERE Reg LIKE '[89A-Z]%';
The pattern [89A-Z]% says to match a starting 8 or 9, or any letter.

Reg: Auto incrementing a value in SQL Table

I got a value in a field called it (EmployeeDetailKey - varchar(10)) with sequential values such as
00001, 00002, 00003....
It is in a table Employeedetail. When ever a new Employee detail has to be inserted I have to get the max(EmployeeDetailKey) and increment by 1 and store it back. If I have 10 employeedetail records that need to be inserted then the same procedure has to follow.
If the max(EmployeeDetailKey) = 00003 then after inserting 10 records
it has to be 00013. Later on after inserting let us say 100 records it has to
be 00113.
How can I do it in the form of MS-SQL statement.
Please note the column cannot be identity type.
Just add an identity column to your table. I would suggest something like:
IntEmployeeDetailKey int not null identity(1, 1) primary key,
. . .
Then add a computed column:
EmployeeDetailKey as (right(('00000' + cast(IntEmployeeDetailKey as varchar(10)), 5)
Then SQL Server will do the incrementing automatically. And you can get the value out as a zero-padded string.
If you prefer a solution without changing the table structure, then:
Cast your zero-padded string value to int. This is easy in SQl server, as it will easily convert such strings to numbers:
SELECT CAST('00003' AS int)
This will return integer value of 3.
Find MAX()
Just perform MAX() on column you've just converted to string, like...
SELECT MAX(CAST(mycolumn AS int)) FROM mytable
Actually, you don't have to do a conversion, as SQL server will sort the values correctly in original string representation.
Increment
This is easy, since you now have the integer value, so...
SELECT MAX(CAST(mycolumn AS int)) + 1 FROM mytable
Convert it back to zero-padded string
SQL Server 2008 is a bit tricky to tame here, since left-padding is not his speciality. However, starting from in SQL Server 2012, there is a FORMAT function available, so, you can use...
SELECT FORMAT(MAX(CAST(mycolumn AS int)) + 1, '00000') FROM mytable
If you have only SQL Server 2005 or 2008 available, you can use REPLICATE() combined with LEN() to get what you need (disclaimer: UGLY CODE):
SELECT REPLICATE('0', 5 - LEN(MAX(CAST(mycolumn AS int)) + 1)) + CAST((MAX(CAST(mycolumn AS int)) + 1) AS nvarchar(5)) FROM mytable
EDIT As Luaan hinted, you can use another padding option (shorter and more readable code):
SELECT RIGHT('00000' + CAST(MAX(CAST(mycolumn AS int) + 1) as nvarchar(5)), 5) FROM mytable
I don't know if it is mandatory that EmployeeDetailKey must have this format.
I'll suggest you to substitute the datatype from varchar(10) to IDENTITY.
IDENTITY is a sort of special data type that gets automatically incremented by SQL Server each time you insert a row in the parent table. You can learn more here: https://msdn.microsoft.com/en-us/library/ms186775.aspx
If you need to present it with leading zeroes you can always select it like this (liberally adapted from here: Most efficient T-SQL way to pad a varchar on the left to a certain length?):
SELECT right('00000'+ rtrim(EmployeeDetailKey), 5) FROM YourTable

Puzzling SQL server behaviour - results in different formats if there is a 1<>2 expression in WHERE clause

I have two almost identical SELECT statements. I am running them on a SQL Server 2012 with server collation Danish_Norwegian_CI_AS, and database collation Danish_Norwegian_CI_AS. The database runs in compatibility level set to SQL Server 2005 (90).
I run both of the queries on the same client via a SQL Server 2012 Management Studio. The client is a Windows 8.1 laptop.
The puzzling part is, although the statements are almost identical, the resultset is different as shown below (one returns 24-hour format time, the other with AM / PM, which gets truncated tpo P in this case). The only difference is the 'and 1<>2' expression in WHERE clause. I looked up and down, searched in google, digged as deep as I could, cannot find an explanation. Tried COLLATE to force conversion, did not help. If I use 108 to force formatting in CONVERT call, then the resultsets are alike. But not knowing the reason why this does not work is eating me alive.
Issue recreated on SqlFiddle, SQL Server 2008:
http://sqlfiddle.com/#!3/a97f8/1
Have someone an explain for this?
The SQL DDL and statements after results can be used to recreate the issue. The script creates a table with two columns, inserts some rows, and makes two selects.
On my machine the sql without the 1<>2 expression returns:
Id StartTime
----------- ---------
2 2:00P
2 2:14P
The sql with the 1<>2 expression returns:
Id StartTime
----------- ---------
2 14:00
2 14:14
if NOT EXISTS (Select * from sysobjects where name = 'timeVarchar')
begin
create table timeVarchar (
Id int not null,
timeTest datetime not null
)
end
if not exists (select * from timeVarchar)
begin
-- delete from timeVarchar
print 'inserting'
insert into timeVarchar (Id, timeTest) values (1, '2014-04-09 11:37:00')
insert into timeVarchar (Id, timeTest) values (2, '1901-01-01 14:00:00')
insert into timeVarchar (Id, timeTest) values (3, '2014-04-05 15:00:00')
insert into timeVarchar (Id, timeTest) values (2, '1901-01-01 14:14:14')
end
select
Id,
convert ( varchar(5), convert ( time, timeTest)) as 'StartTime'
from
timeVarchar
where
Id = 2
select
Id,
convert ( varchar(5), convert ( time, timeTest)) as 'StartTime'
from
timeVarchar
where
Id = 2 and
1 <> 2
I can't answer why this is happening (at least not at the moment), but setting the conversion format explicitly does solve the issue:
select Id,
convert (varchar(5), convert (time, timeTest), 14) as "StartTime"
from timeVarchar
where Id = 2;
select Id,
convert (varchar(5), convert (time, timeTest), 14) as "StartTime"
from timeVarchar
where Id = 2
and 1 <> 2;
Going through the execution plan, the two queries end up very different indeed.
The first one passes 2 as a parameter and (!) does CONVERT_IMPLICIT of the value. The second one passes it as a part of the query itself!
In the end, the actual query that gets to run in the first case actually explicitly does CONVERT(x, y, 0). For US locale, this is not a problem, since 0 is the invariant (~US) culture. But outside of the US, you're suddenly using 0 instead of e.g. 4 (for Germany).
So, definitely, one thing to take from this is that queries that look very much alike could execute completely differently.
The second thing is - always use convert with a specific format. The defaults don't seem to be entirely reliable.
EDIT: Ah, finally fished the thing out of the MSDN:
http://msdn.microsoft.com/en-us/library/ms187928.aspx
In earlier versions of SQL Server, the default style for CAST and
CONVERT operations on time and datetime2 data types is 121 except when
either type is used in a computed column expression. For computed
columns, the default style is 0. This behavior impacts computed
columns when they are created, used in queries involving
auto-parameterization, or used in constraint definitions.
Since the first query is invoked as a parametrized query, it gets the default style 0, rather than 121. This behaviour is fixed in compatibility level 110+ (i.e. SQL SERVER 2012+) - on those servers, the default is always 121.
It seems the problem is solved in SQL2012
see this link
http://sqlfiddle.com/#!6/a97f8/4
p.s Your mentioned url on sqlfiddle is running on SQL2008

SQL statement to get largest ID from database column

I have an ID column which it supposed to set to auto-increment but I forgot to set in when creating the database. Let's say the ID is from 1 - 20. I used the select Max() Sql statement to get the largest ID:
SELECT MAX(id) FROM Table_Name;
It supposed to return me 20. However, it returns me 9. I also realized that the id column in database is jumbled up. It starts from 1,2 then skips to 9,10 - 20 then back to 3 - 8. And 8 appears to be the last row and I think that's where the 9 comes from. My id in database is varchar() data type.
So, is there any way to amend my Sql statement to get the largest id in a list of sorted id?
Thanks in advance.
The issue is likely that the ID column is a varchar field, so 9 is greater than 10.
select max(convert(int, id)) from Table
Your column is a character type, not a numeric type, which explains everything you're seeing.
Try casting it to numeric:
select max(cast(id as signed)) from table
You haven't said which database you are using, so the syntax may vary to achieve the cast - consult online docs for your database.
Try this:
SELECT TOP 1 Id FROM Table ORDER BY Convert(INT, id) DESC