SQL - ORDER BY in IF-ELSE CLAUSE - sql-server

I have ONE table A and if the parameters #x is 0 i want to ordering A by date, else by Name.
This is an example:
declare #x int set #x = 0
if(#x=0)(
SELECT * FROM A
order by DATE
)
else
(
SELECT * FROM A
order by Name
)
When try to do it SQL Server return 2 egual error as
Incorrect syntax near the keyword 'order'.
What could i do?

Try this instead
SELECT * FROM A
order by
Case #x When 0 Then Cast(DATE as sql_variant) Else Name End
The casting is required for the dynamic sort to work with a date - I'm trying to find a reference, but you need a type that can be casted automatically to a common type, and date can't be done. Hence casting yourself.
Here's a link to some options. Note the section on mixed datatypes.
https://web.archive.org/web/20211029044050/https://www.4guysfromrolla.com/webtech/010704-1.shtml

declare #x int set #x = 0
if(#x=0)
begin
SELECT * FROM A
order by DATE
end
else
begin
SELECT * FROM A
order by Name
end

SELECT
*
FROM
A
ORDER BY
CASE WHEN #x = 0 THEN Date ELSE Name END

declare #x int
set #x = 0
IF (#x=0)
BEGIN
SELECT * FROM A order by DATE
END
ELSE
SELECT * FROM A order by Name
END
http://msdn.microsoft.com/en-us/library/aa933214(SQL.80).aspx

If your query becomes reasonably complex, then copying it into both sides of an IF/ELSE can becomes rather onerous. You can instead use a CASE expression in your ORDER BY. In this case, you might do:
SELECT * FROM A ORDER BY CASE WHEN #x=0 THEN DATE END, CASE WHEN #x<>0 THEN Name END
This can be expanded up to more conditions/columns. You just need to ensure that each CASE expression is returning a sensible data type.

Parentheses ( and ) are wrong. Use BEGIN and END instead.
DECLARE #x INT
SET #x = 0
IF (#x = 0) BEGIN
SELECT * FROM A ORDER BY DATE
END
ELSE BEGIN
SELECT * FROM A ORDER BY Name
END
Also, in my opinion, DATE as column name is not good idea.

As noted in the answers but not explained.
SQL uses BEGIN - END syntax instead of () or {} for block of commands

Related

How can I complete this Excel function in SQL Server?

I have approximately 30,000 records where I need to split the Description field and so far I can only seem to achieve this in Excel. An example Description would be:
1USBCP 2RJ45C6 1DVI 1DP 3MD 3MLP HANDS
Below is my Excel function:
=TRIM(MID(SUBSTITUTE($G309," ",REPT(" ",LEN($G309))),((COLUMNS($G309:G309)-1)*LEN($G309))+1,LEN($G309)))
This is then dragged across ten Excel columns, and splits the description field at each space.
I have seen many questions asked about splitting a string in SQL but they only seem to cover one space, not multiple spaces.
There is no easy function in SQL server to split strings. At least I don't know it. I use usually some trick that I found somewhere in the Internet some time ago. I modified it to your example.
The trick is that first we try to figure out how many columns do we need. We can do it by checking how many empty strings we have in the string. The easiest way is lenght of string - lenght of string without empty string.
After that for each string we try to find start and end of each word by position. At the end we cut simply string by start and end position and assign to coulmns. The details are in the query. Have fun!
CREATE TABLE test(id int, data varchar(100))
INSERT INTO test VALUES (1,'1USBCP 2RJ45C6 1DVI 1DP 3MD 3MLP HANDS')
INSERT INTO test VALUES (2,'Shorter one')
DECLARE #pivot varchar(8000)
DECLARE #select varchar(8000)
SELECT
#pivot=coalesce(#pivot+',','')+'[col'+cast(number+1 as varchar(10))+']'
FROM
master..spt_values where type='p' and
number<=(SELECT max(len(data)-len(replace(data,',',''))) FROM test)
SELECT
#select='
select p.*
from (
select
id,substring(data, start+2, endPos-Start-2) as token,
''col''+cast(row_number() over(partition by id order by start) as varchar(10)) as n
from (
select
id, data, n as start, charindex('','',data,n+2) endPos
from (select number as n from master..spt_values where type=''p'') num
cross join
(
select
id, '' '' + data +'' '' as data
from
test
) m
where n < len(data)-1
and substring(odata,n+1,1) = '','') as data
) pvt
Pivot ( max(token)for n in ('+#pivot+'))p'
EXEC(#select)
Here you can find example in SQL Fiddle
I didn't notice that you want to get rid of multiple blank spaces.
To do it please create some function that preprare your data :
CREATE FUNCTION dbo.[fnRemoveExtraSpaces] (#Number AS varchar(1000))
Returns Varchar(1000)
As
Begin
Declare #n int -- Length of counter
Declare #old char(1)
Set #n = 1
--Begin Loop of field value
While #n <=Len (#Number)
BEGIN
If Substring(#Number, #n, 1) = ' ' AND #old = ' '
BEGIN
Select #Number = Stuff( #Number , #n , 1 , '' )
END
Else
BEGIN
SET #old = Substring(#Number, #n, 1)
Set #n = #n + 1
END
END
Return #number
END
After that use the new version that removes extra spaces.
DECLARE #pivot varchar(8000)
DECLARE #select varchar(8000)
SELECT
#pivot=coalesce(#pivot+',','')+'[col'+cast(number+1 as varchar(10))+']'
FROM
master..spt_values where type='p' and
number<=(SELECT max(len(dbo.fnRemoveExtraSpaces(data))-len(replace(dbo.fnRemoveExtraSpaces(data),' ',''))) FROM test)
SELECT
#select='
select p.*
from (
select
id,substring(data, start+2, endPos-Start-2) as token,
''col''+cast(row_number() over(partition by id order by start) as varchar(10)) as n
from (
select
id, data, n as start, charindex('' '',data,n+2) endPos
from (select number as n from master..spt_values where type=''p'') num
cross join
(
select
id, '' '' + dbo.fnRemoveExtraSpaces(data) +'' '' as data
from
test
) m
where n < len(data)-1
and substring(data,n+1,1) = '' '') as data
) pvt
Pivot ( max(token)for n in ('+#pivot+'))p'
EXEC(#select)
I am probably not understanding your question, but all that you are doing in that formula, can be done almost exactly the same in SQL. I see someone has already answered but to my mind, how can it be necessary to do all that when you can do this. I might be wrong. But here goes.
declare #test as varchar(100)
set #test='abcd1234567'
select right(#test,2)
, left(#test,2)
, len(#test)
, case when len(#test)%2>0
then left(right(#test,round(len(#test)/2,0)+1),1)
else left(right(#test,round(len(#test)/2,0)+1),2) end
Results
67 ab 11 2
So right, left, length and mid can all be achieved.
If the spaces are the "substring" dividers, then: I dont remember well the actual syntax for do-while inside selects of sql, neither have i actually done that per se, but I don't see why it should not be possible. If it doesn't work then you need a temporary table and if that does not work you need a cursor. The cursor would be an external loop around this one to fetch and process a single string at a time. Or you can do something more clever. I am just a novice.
declare #x varchar(1)
declare #n integer
declare #i integer
declare #str varchar(100) -- this is your description. Fetch it and assign it. if in a cursor just use column-name
set #x = null
set #n = 0
set #i = 0
while n < len(#str)
while NOT #x = " "
begin
set #x = left(right(#str,n),1)
n = n+1
end
--insert into or update #temptable blablabla here.
Use i and n to locate substring and then left(right()) it out. or you can SELECT it, but that is a messy procedure if the number of substrings are long. Continue with:
set i = n
set #str = right(#str, i) -- this includes the " ". left() it out at will.
end
Now, a final comment, there should perhaps be a third loop checking for if you are at the last "substring" because I see now this code will throw error when it gets to the end. or "add" an empty space at the end to #str, that will also work. But my time is up. This is a suggestion at least.

How Do I Use a Variable in a Select Statement?

When I run the following code I get the error : Incorrect syntax near '#num_to_remove'.
Any idea why this doesn't work?
Thanks in advance,
Matt
DECLARE #num_to_remove INT
SET #num_to_remove = 2
-- get em_ids for records to delete
WITH em_ids
AS (SELECT TOP #num_to_remove em_id
FROM irs_self_cert_em sc
WHERE sc.date_cert_loc IS NULL
AND sc.date_first_cert_email_sent < '2014-10-03')
SELECT * FROM em_ids
In regular tSQL, you can only use variables to represent values, not column names or other objects. I know the numeric value for a "TOP" clause seems like it should qualify but it doesn't.
To use a variable in this way, you have to do Dynamic SQL.
Try this (Note: I haven't tested it. You can try similar this)
DECLARE #num_to_remove INT
SET #num_to_remove = 2
-- get em_ids for records to delete
EXEC
(
'WITH em_ids
AS (SELECT TOP ' + CAST(#num_to_remove AS varchar(10) + 'em_id
FROM irs_self_cert_em sc
WHERE sc.date_cert_loc IS NULL
AND sc.date_first_cert_email_sent < ''2014-10-03'')
'
)

how to select rows that contains non-english characters in sql server 2005(it should filter only non-english chars, not special characters)

As my table contains non-English(contains characters in different languages) characters and special characters in a column. I need filter only non-English characters. It should filter any special characters.
i tried using different methods to filter but failed to filter few rows. someone please help me on this. Thanks in advance.
ex:
column name LOCATION contains following rows :
row 1: துய இம்மானுவேல் தேவாலயம், North Street, Idyanvillai, Tamil Nadu, India
row 2:Dr.Hakim M.Asgar Ali's ROY MEDICAL CENTRE™ Unani Clinic In Kerala India, Thycaud Hospital Road, Opp. Amritha Hotel,, Thycaud.P.O.,, Thiruvananthapuram, Kerala, India
row 3: ಕಾಳಿಕಾಂಬ ದೇವಿ ದೇವಸ್ಥಾನ, Shivaji Nagar, Davangere, Karnataka, India
As the above contains characters in many language. can any one help me to select only row 2 thanks.
T-SQL's string-handling capability is pretty rudimentary.
If the "non-English" fields are distinguished by their use of Unicode UTF-16, you can try something like
SELECT * FROM MyTable WHERE MyField = Cast(MyField AS VARCHAR)
to pull only rows that are expressible in UTF-8.
The only way I know how to test whether a field is drawn from an arbitrary set of characters is with a user-defined function, like this:
CREATE FUNCTION IsAllowed (#input VARCHAR(MAX)) RETURNS BIT
-- Returns 1 if string is allowed, 0 otherwise.
-- Usages: SELECT dbo.IsAllowed('Hello'); -- returns 1
-- SELECT dbo.IsAllowed('Hello, world!'); -- returns 0
-- Note CHARINDEX is not case sensitive so #allowables doesn't need both.
-- VARCHAR(MAX) is different under SQL Server 2005 than 2008+
--- and use of defined VARCHAR size might be necessary.
AS
BEGIN
DECLARE #allowables char(26) = 'abcdefghijklmnopqrstuvwxyz';
DECLARE #allowed int = 0;
DECLARE #index int = 1;
WHILE #index <= LEN(#input)
BEGIN
IF CHARINDEX(SUBSTRING(#input,#index,1),#allowables)=0
BEGIN
SET #allowed = 0;
BREAK;
END
ELSE
BEGIN
SET #allowed = 1;
SET #index = #index+1;
END
END
RETURN #allowed
END
User-defined functions can be applied to columns in SELECT, like this:
SELECT * FROM MyTable WHERE dbo.IsAllowed(MyField) = 1
Note the schema name (dbo in this case) is not optional with user-defined functions.
If a T-SQL user-defined function is inadequate, you can also use a CLR Function. Then you could apply a regexp or whatever to a column. Because they break portability and pose a security risk, many sysadmins don't allow CLR functions. (This includes Microsoft's SQL Azure product.)
If you have all the allowed special characters, following select statement should select all columns with only English and the allowed special characters:
select column_name from table_name where column_name like '%[^a-z, .-™]%';
You can add all the allowed special characters inside the square brackets.
Got a great answer for my question.
select ID, LATITUDE, LONGITUDE, REFERENCE, LOCATION, VALIDATE,
patindex('%[^ !-~()"]%' COLLATE Latin1_General_BIN,LOCATION) as [Position],
substring(LOCATION,patindex('%[^ !-~()"]%' COLLATE Latin1_General_BIN,LOCATION),1) as [InvalidCharacter],
ascii(substring(LOCATION,patindex('%[^ !-~()"]%' COLLATE Latin1_General_BIN,LOCATION),1)) as [ASCIICode]from dbo.RADAR_SEARCH where patindex('%[^ !-~()"]%' COLLATE Latin1_General_BIN,LOCATION) >0
EDIT1:
Explanation for above answer
Above query filters only non-English chars in Location column in which special characters are not included.
NOTE: Tested only in MS-SQL.
I used this for converting emails which has non-english characters to NULL. (MS SQL)
CREATE FUNCTION ufn_character_test(#kontrol nvarchar(MAX))
RETURNS int
AS
BEGIN
DECLARE #intFlag INT
SET #intFlag = 1
DECLARE #intFlag2 INT
SET #intFlag2 = 1
DECLARE #SonucFlag INT
SET #SonucFlag=0
DECLARE #SonucFlag2 INT
SET #SonucFlag2=0
WHILE (#intFlag <=LEN(#kontrol))
BEGIN
WHILE (#intFlag2 <=62)
BEGIN
IF CAST(SUBSTRING(#kontrol, #intFlag, 1) as varbinary(2))
=CAST(SUBSTRING('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', #intFlag2, 1) as varbinary(2))
SET #SonucFlag=#SonucFlag+1
SET #intFlag2 = #intFlag2 + 1
END
SET #intFlag = #intFlag + 1
SET #intFlag2 = 1
END
IF #SonucFlag=LEN(#kontrol)
SET #SonucFlag2=1
ELSE
SET #SonucFlag2=0
RETURN #SonucFlag2
END
USE master;
GRANT EXEC ON dbo.ufn_character_test TO PUBLIC
SELECT ADR_EMAIL,
CASE WHEN ADR_EMAIL NOT LIKE '%[%]%'
AND ADR_EMAIL NOT LIKE '%#%#%%'
AND ADR_EMAIL NOT LIKE '.%'
AND ADR_EMAIL NOT LIKE '%.'
AND dbo.ufn_character_test(REPLACE(REPLACE(REPLACE(REPLACE(ADR_EMAIL,'.',''),'#',''),'_',''),'-',''))=1
AND ADR_EMAIL LIKE '__%#%__.__%'
THEN ADR_EMAIL ELSE NULL END AS EMAIL
FROM EMAILTABLE

How to add column dynamically in where clause

I want to include column in where clause depending on the condition.
e.g
select * From emp
where id=7,
and if(code is not null) then code=8;
how can i do this in sql server
If I understand you correct, you could make use of COALESCE.
COALESCE()
Returns the first nonnull expression
among its arguments.
SQL Statement
SELECT *
FROM emp
WHERE id=7
AND code = COALESCE(#code, code)
If code is a column rather than a variable the query in your question would be rewritten as follows.
SELECT *
FROM emp
WHERE id=7 AND (code IS NULL OR code=8)
You'll probably have to create a query dynamically, as a string, and then use the Execute method to actually execute it. This approach has some potentially optimization issues, but it's commonly done. You might wan to Google T-SQL Dynamic Query, or something like that.
Also use this in case of Null value in #var1.
Select * from ABC where Column1 = isNull(#var1, Column1)
here is the example:
declare #SQL varchar(500)
declare #var1 int
set int = 1
set #SQL = 'Select * from ABC Where 1 = 1'
if(#var1 = 1)
set #SQL + #SQL ' And column1 = ' #var1
exec(#SQL)
You can use COALESCE function.
Well,
I don't know if i understood your question, but i guess that you want to include the value of the code column in the results.
If i'm right it can be done in the select part instead of the where clause. i. e.
Select ..., case when code is not null then 8 else code end as code from emp where id = 7
The other interpretation is that you want to filter rows where code <> 8,that would be
Select * from emp where id = 7 and (code is null OR code = 8)

How to get MAX value of numeric values in varchar column

I have a table with a nvarchar column. This column has values for example:
983
294
a343
a3546f
and so on.
I would like to take MAX of this values, but not as text but like from numerics. So in this example numerics are:
983
294
343
3546
And the MAX value is the last one - 3546. How to do this in TSQL on Microsoft SQL?
First install a regular expression function. This article has code you can cut/paste.
Then with RegexReplace (from that article) you can extract digits from a string:
dbo.RegexReplace( '.*?(\d+).*', myField, '$1' )
Then convert this string to a number:
CAST( dbo.RegexReplace( '.*?(\d+).*', myField, '$1' ) AS INT )
Then use this expression inside a MAX() function in a SELECT.
You can try to keep it simple without using Regular Expression
Here is the source
create table #t ( val varchar(100) )
insert #t select 983
insert #t select 294
insert #t select 'a343'
insert #t select 'a3546f';
GO
;with ValueRange as (
select val,
[from] = patindex('%[0-9]%', val),
[to] = case patindex('%[a-z]', val)
when 0 then len(val)
else patindex('%[a-z]', val) - patindex('%[0-9]%', val)
end
from #t
)
select substring(val, [from], [to]) as val
from ValueRange VR
order by cast(substring(val, [from], [to]) as int) desc
CAST() would do the trick, probably.
SELECT MAX(CAST(yourColumn AS int)) AS maxColumns FROM yourTable
Edit.
I didn't read the whole question, as it seems...
– Function to strip out non-numeric chars
ALTER FUNCTION dbo.UDF_ParseNumericChars
(
#string VARCHAR(8000)
)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE #IncorrectCharLoc SMALLINT
–SET #IncorrectCharLoc = PATINDEX(’%[^0-9A-Za-z]%’, #string)
SET #IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, #string)
WHILE #IncorrectCharLoc > 0
BEGIN
SET #string = STUFF(#string, #IncorrectCharLoc, 1, ”)
SET #IncorrectCharLoc = PATINDEX(’%[^0-9.]%’, #string)
END
SET #string = #string
RETURN #string
END
GO
I picked it from here. (I voted up the reg exp answer though)
you can write a function something like
create FUNCTION [dbo].[getFirstNumeric](
#s VARCHAR(50)
)
RETURNS int AS
BEGIN
set #s = substring(#s,patindex('%[0-9]%',#s),len(#s)-patindex('%[0-9]%',#s) + 1)
if patindex('%[^0-9]%',#s) = 0
return #s
set #s = substring(#s,1,patindex('%[^0-9]%',#s)-1)
return cast(#s as int)
end
and then call
select max(dbo.getFirstNumeric(yourColumn)) from yourTable
if you are using SQL Server 2005 or never you can also use the solution posted by Sung Meister
As far as I know you would need to create a process (or user defined function) to scrub the column, so that you can actually convert it to an INT or other appropriate datatype, then you can take the max of that.
By using user defined function parse the value to an int and then run the select.
SELECT MAX(dbo.parseVarcharToInt(column)) FROM table
SELECT dbo.RegexReplace('[^0-9]', '','a5453b',1, 1)
and RegexReplace installation like Jason Cohen said
This is an old question, I know - but to add to the knowledge base for others...
Assuming all your values have at least 1 number in them:
Select max(convert(int, SubString(VarName, PATINDEX('%[0-9]%',VarName), Len(VarName))))
from ATable
This is my simple answer. You can try it. But it works for fixed removable string value.
select max(cast(SUBSTRING(T.column,3,len(T.column)) as int)) from tablename T

Resources