sql - tips and tricks

32
SQL Tips and Tricks STRING FUNCTIONS ASCII Returns the ASCII of the left most character of the expression Syntax ASCII (‘A’) returns 65 CHAR Converts an int ASCII code to a character Syntax CHAR (integer expr) Eg: CHAR(65) returns A CHARINDEX Returns the starting position of the specified expression in a character string Syntax Charindex (exp1,exp2) Eg: Charindex (‘nj’,’anju’) returns 2 DIFFERENCE Returns an integer value that indicates the difference between the SOUNDEX values of two character expressions. It returns values from 0 to 4. 0 for weak or no similarity, 4 for strong or same values Syntax DIFFERENCE(exp1,exp2) Eg: DIFFERENCE(‘Anju’,’AnjuE’) returns 4 LEFT Returns the left part of a character string with the specified number of characters. Syntax LEFT(exp) Eg: LEFT(Renjith,3) returns Ren LEN Returns the length of the string. Syntax LEN(exp) Eg: LEN(‘Renjith’) returns 7 LOWER Returns the expression in lower case letters Syntax

Upload: anju-renjith

Post on 18-Jun-2015

321 views

Category:

Technology


8 download

DESCRIPTION

SQL - tips and tricks

TRANSCRIPT

Page 1: SQL - tips and tricks

SQL Tips and Tricks

STRING FUNCTIONS

ASCIIReturns the ASCII of the left most character of the expressionSyntaxASCII (‘A’) returns 65

CHARConverts an int ASCII code to a characterSyntaxCHAR (integer expr)Eg: CHAR(65) returns A

CHARINDEXReturns the starting position of the specified expression in a character stringSyntaxCharindex (exp1,exp2)Eg: Charindex (‘nj’,’anju’) returns 2

DIFFERENCEReturns an integer value that indicates the difference between the SOUNDEX values of two character expressions.It returns values from 0 to 4. 0 for weak or no similarity, 4 for strong or same valuesSyntaxDIFFERENCE(exp1,exp2)Eg: DIFFERENCE(‘Anju’,’AnjuE’) returns 4

LEFTReturns the left part of a character string with the specified number of characters.SyntaxLEFT(exp)Eg: LEFT(Renjith,3) returns Ren

LENReturns the length of the string.SyntaxLEN(exp)Eg: LEN(‘Renjith’) returns 7

LOWERReturns the expression in lower case lettersSyntaxLOWER(Exp)Eg: LOWER(‘ANJU’) returns anju

LTRIMReturns the string after it removes leading blanksSyntaxLTRIM(Exp)Eg: LTRIM(‘ ANJU ‘) returns ‘ANJU ‘

NCHAR

Page 2: SQL - tips and tricks

Returns the Unicode character with the specified integer code, as defined by the Unicode standard.

PATINDEXReturns the starting position of the first occurrence of a pattern in a specified expression, or zeros if the pattern is not found, on all valid text and character data types.Syntax PATINDEX (‘%search_string%’,’actual string’)Eg: PATINDEX (‘%nj%’,’anju’) returns 2

QUOTENAMEReturns the Unicode string with the delimiter added to make the input string a valid Microsoft sql server 2005 delimited identifier. If no delimiter is specified then [] is used.Eg: QUOTENAME (‘abc’,’”’) returns “abc”

REPLACEReplaces all the occurrences of the second string in the first string with the third string Eg: REPLACE (‘abcdefg’,’bcd’,’abc’) returns aabcefg

REPLICATERepeats a character expression specified number of timesEg: REPLICATE (‘abcdefg’,2) returns abcdefgabcdefg

REVERSEReturns the reverse of the stringEg: REVERSE (‘anju’) returns ujna

RIGHTReturns the specified number of characters from the right of the string.Eg: RIGHT (‘anju’,2) returns ju

RTRIMReturns a character string after truncating all trailing blanksEg: RTRIM (‘anju ’) returns anju

SOUNDEXReturns a four character soundex code to find the similarity between two stringsEg: SOUNDEX (‘anju’), SOUNDEX (‘anchu’) returns A520, A520Eg: SOUNDEX (‘anju’), SOUNDEX (‘achu’) returns A520, A200

SPACEReturns a string of repeated spacesEg: select ‘anju’+ SPACE(2)+’renju’ returns anju renju

STRReturns character data from numerical dataSyntaxSTR (numeric exp, length)Eg: Substring (123.45, 2) returns **Eg: Substring (123.45, 3) returns 123Eg: Substring (123.45, 10) returns 123 with 7 trailing spaces

STUFF

Page 3: SQL - tips and tricks

Deletes a specified length of characters and inserts another set of characters at a specified starting point.SyntaxSTUFF (exp, start, length, character exp)Eg: Select (‘Anju Renjith’, 5, 1,’&’) returns Anju&Renjith

SUBSTRINGReturns the sub string from a given stringSyntaxSubstring (exp1, start, length)Eg: Substring (‘SQLServer’, 2, 5) returns QLSer

UNICODEReturns the Unicode of the first character of the given expression.Eg: UNICODE (‘A’) returns 65Eg: UNICODE (‘Anju’) returns 65

UPPERReturns the upper case of the given expressionEg: UPPER (‘anju’) gives ANJU

Page 4: SQL - tips and tricks

OTHER QUESTIONS

To delete the duplicate records

1. DELETEFROM MyTableWHERE ID NOT IN (SELECT MAX(ID) FROM MyTable GROUP BY DuplicatevalueColumn1, DuplicateValueColumn2, DuplicateValueColumn3)

2. DELETE fFROM (SELECT ROW_NUMBER() OVER (PARTITION BY PHONE_NBR order by PHONE_NBR) AS RecIDFROM Table_2 ) AS fWHERE RecID > 1

Here PHONE_NBR is the suspected duplicate column

3. Set rowcount 1

Delete table_2 from table_2 AWhere (Select count(*) from table_2 B where B.PHONE_NBR= A.PHONE_NBR)>1

While @@rowcount > 0Delete table_2 from table_2 A Where (Select count(*) from table_2 B where B.PHONE_NBR= A.PHONE_NBR)> 1

Set rowcount 0

A puzzle

Step:1

CREATE TABLE tbl_Group_Test(_ID INT IDENTITY,_Place VARCHAR(50),_Name VARCHAR(100))

Step:2

INSERT INTO tbl_Group_Test VALUES('Tamil Nadu','Abdul Kalam')INSERT INTO tbl_Group_Test VALUES('Tamil Nadu','Karunanidhi')INSERT INTO tbl_Group_Test VALUES('Tamil Nadu','Jayalalitha')INSERT INTO tbl_Group_Test VALUES('Tamil Nadu','Robin Singh')INSERT INTO tbl_Group_Test VALUES('Maharashtra','Sachin Tendulkar')INSERT INTO tbl_Group_Test VALUES('Orissa','Sourav Ganguly')

Page 5: SQL - tips and tricks

SELECT * FROM tbl_Group_Test

Output must be

_ID _Place _Name-------- --------------------------------------------1 Tamil Nadu Abdul Kalam2 " Karunanidhi3 " Jayalalitha4 " Robin Singh5 Maharashtra Sachin Tendulkar6 Orissa Sourav Ganguly---------------------------------------------------------

Answer is SELECT b._id, _place =CASE _placeWHEN (SELECT _place FRom tbl_Group_Test A WHERE A._id=b._id-1) THEN '"'ELSE _placeEND,b._NameFROM tbl_Group_Test bORDER BY _id

Employee table and allowances (IKM)1. TableEarnings MasterFields are EarningsId, EarningsName Rows1, DA2, HRA

2. Table EmployeeFields are Id, Name

Rows1, Renju2, Anju

3. Table EarningsFields are Id, EarningsId, Amount1, 1, 1000 Renju has DA Amount of Rs.10001, 2, 2002, 1, 8002, 2, 400

Query is

Select A.Id as EmplId, A.Name as EmplName , A.DA as DA, A.HRA as HRAFrom(Select Id, Name,

Page 6: SQL - tips and tricks

Case when Earnings.Id=1 Then Amount as DA,Case when Earnings.Id=2 Then Amount as HRAFrom EarningsInner join EmployeeOn Employee.Id= Earnings.Id)A

Output is

1, Renju, 1000,2002, Anju, 800, 400

To get the minimum marksselect intempid, 'MinMark' =case

when mark1 < mark2 and mark1 < mark3then mark1

when mark2< mark1 and mark2 < mark3 then mark2 when mark3< mark1 and mark3 < mark2 then mark3endfrom table_3

Eg: Table_3 has values 1,90,40,30,80 2,50,60,20,40

Output of the query will be 1 30 2 20

To get the amount of employees separated by comma

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Table_1]') ) -- If prcRptDdlPartyNameForGoverningBodies exist then drop DROP TABLE [dbo].[Table_1] GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GOgoUSE [master]GO/****** Object: Table [dbo].[Table_1] Script Date: 08/07/2007 13:27:28 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOCREATE TABLE [dbo].[Table_1](

[intEmpId] [int] NULL,[fltamount] [float] NULL

Page 7: SQL - tips and tricks

) ON [PRIMARY]

goDELETE FROM [master].[dbo].[Table_1]goINSERT INTO [master].[dbo].[Table_1] ([intEmpId] ,[fltamount]) VALUES (1,1000)INSERT INTO [master].[dbo].[Table_1] ([intEmpId] ,[fltamount]) VALUES (1,500)INSERT INTO [master].[dbo].[Table_1] ([intEmpId] ,[fltamount]) VALUES (1,300)INSERT INTO [master].[dbo].[Table_1] ([intEmpId] ,[fltamount]) VALUES (2,500)INSERT INTO [master].[dbo].[Table_1] ([intEmpId] ,[fltamount]) VALUES (2,400)goDeclare @intempid as intdeclare @count as intdeclare @amt as floatdeclare @PrintAmt as varchar(1000)

Declare curs_Emp cursor forselect distinct intempid from dbo.Table_1open curs_Empfetch next from curs_Emp into @intempid

while(@@fetch_status=0)begin

set @PrintAmt=''set @count=0set @count=(select count(*) from dbo.Table_1 where intempid=@intempid)if @count<>0begin

Declare curs_Amt cursor forselect fltamount from dbo.Table_1 where intempid=@intempidopen curs_Amtfetch next from curs_Amt into @amtwhile(@@fetch_status=0)begin

set @PrintAmt=@PrintAmt+','+cast(@amt as varchar(10))fetch next from curs_Amt into @amt

Page 8: SQL - tips and tricks

endCLOSE curs_AmtDEALLOCATE curs_Amtselect @intempid,substring(@PrintAmt,2,len(@PrintAmt)-1)

endfetch next from curs_Emp into @intempid

end

CLOSE curs_EmpDEALLOCATE curs_Emp

Eg: Table_1 has 1 1000,1 200,1 902 200, 2 300

Output of the query will be 1 1000,200,902 200,300

To get the maximum and minimum values of the students

SELECT ID, MIN(Q) AS Lowest, MAX(Q) AS HighestFROM (SELECT ID, Q1 AS Q FROM Table1 UNION ALLSELECT ID, Q2 FROM Table1 UNION ALLSELECT ID, Q3 FROM Table1 UNION ALLSELECT ID, Q4 FROM Table1) AS dGROUP BY IDORDER BY ID

Eg: Table1 has values 1,90,40,30,802,50,60,30,40

Output of the query will be 1 30 902 30 60

CURSORS—An example from IKM

--written with cursor.

--Generates Bonus for Eligible employees

CREATE PROCEDURE Sp_InsertBonusNew ASDeclare @intEmpId as integerDeclare @flgBonus as bitDeclare @bitPayScale as bit

Declare @fltAmount as int Declare @intBonusRPay as intDeclare @intSpecialFestivalAll as intdeclare @fltEmoluments as Floatdeclare @intFestAdvAmt as floatdeclare @fltFestAdvAmount as floatdeclare @flgFestAdvFlag as floatdeclare @bitretirement as bit

Page 9: SQL - tips and tricks

Declare NewBonus_cursor CURSOR forSelect intEmpID,flgBonus,flgFestAdvFlag,bitretirement from Tb_BonusEligilbleEmp_Lcl_Trn

set @intBonusRPay =(select intBonusRPay from TB_BonusSettings_Lcl_MST)

set @intSpecialFestivalAll =(select intSpecialFestivalAll from TB_BonusSettings_Lcl_MST)

set @intFestAdvAmt=(select fltAmount from tb_FestivalAdvanceSettings_Gbl_Mst)

truncate table tb_empbonus_lcl_trn

Open NewBonus_cursor

Fetch next from NewBonus_cursor into @intEmpId,@flgBonus,@flgFestAdvFlag,@bitretirement

While @@Fetch_Status=0Begin

if @bitretirement=1begin

set @fltEmoluments =(select fltEmoluments from TB_EmpBonusHistory_Lcl_Trn where intEmpid=@intEmpID)

endif @bitretirement=0begin

set @fltEmoluments =(select fltEmoluments from TB_EmpBonusRegular_Lcl_Trn where intEmpid=@intEmpID)

endset @fltAmount=@intBonusRPayset @fltFestAdvAmount=0if @flgBonus=0Begin

set @fltAmount=@intSpecialFestivalAll Endif @flgFestAdvFlag=1Begin

set @fltFestAdvAmount=@intFestAdvAmtEndInsert Into TB_EmpBonus_Lcl_Trn (intEmpId,bitBonus,fltEmoluments,fltAmount,fltFestAdvAmount)Values(@intEmpId,@flgBonus,@fltEmoluments,@fltAmount,@fltFestAdvAmount)

Fetch next from NewBonus_cursor into @intEmpId,@flgBonus,@flgFestAdvFlag,@bitretirement

End Close NewBonus_cursorDeallocate NewBonus_cursor

Page 10: SQL - tips and tricks

IF U NEED TO USE THE ALREADY EXISTING CURSOR AGAIN, U SHOULD CLOSE THE CURSOR AND OPEN IT AGAIN. PUT THE DEALLOCATE CURSOR(ONLY ONCE) AT THE END AFTER THE CLOSE STATEMENT WHEN U HAVE DONE WITH THE USAGE OF CURSORS.

Row_Number

Suppose a table has 2 fields id, phone number.Select row_number()over (partition by id order by id) from table Gives output as 1,1,1,2,3

ROUND

The ROUND function returns a numeric expression rounded to the specified length or precision. The second parameter of the ROUND function is the precision to which the input numeric expression is to be rounded. When the second parameter is a negative number, the numeric expression is rounded on the left side of the decimal point, as specified in the length. The third parameter of the ROUND function determines the type of operation to perform. When a value other than 0 is specified, the numeric expression is truncate.

PuzzleSELECT CAST(-1 AS DATETIME)1899-12-31 00:00:00.000 is the output

A DATETIME data type is stored internally in SQL Server as two 4-byte integers. The first 4 bytes store the number of days before or after the base date of January 1, 1900. Given this, a value of 0 corresponds to January 1, 1900 and a value of -1 corresponds to 1 day before the base date, December 31, 1899.

Data type precedence

The order of data type precedence of the given options from highest to lowest: DATETIME, FLOAT, NUMERIC, MONEY, INT and VARCHAR.

Properties of Primary Keys

1. Primary keys are not always created as CLUSTERED indexes. If a table already has an existing clustered index before a PRIMARY KEY constraint is created for the table, adding a PRIMARY KEY constraint on the table will be created as a non-clustered index.

2. Can be of more than 1 column

3. Enforces data uniqueness by creating a unique index for the primary key columns

4. Column that participates in the PRIMARY KEY constraint cannot accept NULL values

Whats the purpose of RANK keyword in SQL server 2005? I have encountered this when i searched for ROW_NUMBER() and cudnt make out

Page 11: SQL - tips and tricks

its meaning? also explain abt DENSE_RANK and NTILE? pls give examples too..

My Table:Create table tbl_Rank(Year int,Quarter Varchar(40),Amount int)

Here my table has three columns with the following Data

INSERT INTO tbl_Rank Values(2002,'Q2',40)INSERT INTO tbl_Rank Values(2001,'Q3',55)INSERT INTO tbl_Rank Values(2002,'Q2',60)INSERT INTO tbl_Rank Values(2001,'Q2',70)INSERT INTO tbl_Rank Values(2001,'Q4',90)INSERT INTO tbl_Rank Values(2001,'Q3',110)INSERT INTO tbl_Rank Values(2002,'Q3',110)INSERT INTO tbl_Rank Values(2002,'Q3',120)INSERT INTO tbl_Rank Values(2002,'Q2',150)INSERT INTO tbl_Rank Values(2002,'Q4',180)INSERT INTO tbl_Rank Values(2002,'Q1',200)

-- QuerySELECT *,RANK() OVER(ORDER BY AMOUNT) AS 'RANK', DENSE_RANK() OVER(ORDER BY AMOUNT) AS 'DENSE_RANK',NTILE(2) OVER(ORDER BY AMOUNT) AS 'NTILE_2', NTILE(3) OVER(ORDER BY AMOUNT) AS 'NTILE_3' FROM tbl_Rank

Output:

Year Quarter Amount RANK DENSE_RANK NTILE_2 NTILE_3---- ------- ------- ---- --------- ------- -------2002 Q2 40 1 1 1 12001 Q3 55 2 2 1 12002 Q2 60 3 3 1 12001 Q2 70 4 4 1 12001 Q4 90 5 5 1 22001 Q3 110 6 6 1 22002 Q3 110 6 6 2 22002 Q3 120 8 7 2 22002 Q2 150 9 8 2 32002 Q4 180 10 9 2 32002 Q1 200 11 10 2 3

Rank() Applies to monotonically increasing number for each value in the setThe value of ties, however, is the same. If the columns in the OVER(ORDER BY) clausehave unique values, the result produced by Rank() is identical to the result produced

Page 12: SQL - tips and tricks

by ROW_NUMBER().

Rank() and Row_Number differ only if there are ties.

In Dense_Rank() Method the rank is increasing number for each value in the set.

Here in the Example the Record 6th and 7th has same amount 110.For that the Rank() is 6 and 6, Dense_Rank() is 6 and 6.But for the next record the Rank() will be 8 and Dense_Rank() will be 7.

NTILE(n)- Which splits the records into partition based on the Column in the Over() and assigns the Rank for the partition.

RECURSIVE QUERIES USING CTE

A common table expression (CTE) provides the significant advantage of being able to reference itself, thereby creating a recursive CTE. A recursive CTE is one in which an initial CTE is repeatedly executed to return subsets of data until the complete result set is obtained.

In SQL Server 2005, a query is referred to as a recursive query when it references a recursive CTE. Returning hierarchical data is a common use of recursive queries, for example: Displaying employees in an organizational chart, or data in a bill of materials scenario in which a parent product has one or more components and those components may, in turn, have subcomponents or may be components of other parents.

A recursive CTE can greatly simplify the code required to run a recursive query within a SELECT, INSERT, UPDATE, DELETE, or CREATE VIEW statement. In earlier versions of SQL Server, a recursive query usually requires using temporary tables, cursors, and logic to control the flow of the recursive steps.

STRUCTURE OF CTE

The structure of the recursive CTE in Transact-SQL is similar to recursive routines in other programming languages. Although a recursive routine in other languages returns a scalar value, a recursive CTE can return multiple rows.

A recursive CTE consists of three elements:

1. Invocation of the routine.

The first invocation of the recursive CTE consists of one or more CTE_query_definitions joined by UNION ALL, UNION, EXCEPT, or INTERSECT operators. Because these query definitions form the base result set of the CTE structure, they are referred to as anchor members.

CTE_query_definitions are considered anchor members unless they reference the CTE itself. All anchor-member query definitions must be positioned before the first recursive member definition, and a UNION ALL operator must be used to join the last anchor member with the first recursive member.

2. Recursive invocation of the routine.

Page 13: SQL - tips and tricks

The recursive invocation includes one or more CTE_query_definitions joined by UNION ALL operators that reference the CTE itself. These query definitions are referred to as recursive members.

3. Termination check.

The termination check is implicit; recursion stops when no rows are returned from the previous invocation.

--Creating table and inserting values to itUSE [master]GO/****** Object: Table [dbo].[Table_4] Script Date: 10/03/2007 12:10:51 ******/SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGOSET ANSI_PADDING ONGOIF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Table_4]') AND type in (N'U'))DROP TABLE [dbo].[Table_4]GOCREATE TABLE [dbo].[Table_4](

[parent_id] [int] NULL,[child_id] [int] NULL

) ON [PRIMARY]

GOSET ANSI_PADDING OFFGOdelete from Table_4GOinsert into Table_4 values(100,101)insert into Table_4 values(101,102)insert into Table_4 values(99,100)insert into Table_4 values(98,99)insert into Table_4 values(100,103)

--Get the parent detailsDECLARE @my_id intSET @my_id = 102; WITH MyRecords (ID, parent_ID)AS(SELECT child_ID ,parent_IDFROM table_4 WHERE child_ID = @my_idUNION ALLSELECT table_4.child_ID,table_4.parent_ID FROM table_4JOIN MyRecords ON table_4.child_ID = MyRecords.parent_ID

Page 14: SQL - tips and tricks

)SELECT parent_ID As anjusPath FROM MyRecords

--Get the root parent (with Depth)DECLARE @my_id intSET @my_id = 102; WITH MyRecords (ID, parent_ID, Depth)AS(SELECT table_4.child_id ,table_4.parent_id, 0 AS DepthFROM table_4 WHERE child_id = @my_idUNION ALLSELECT child_id,table_4.parent_id, MyRecords.Depth + 1 AS Depth FROM table_4JOIN MyRecords ON table_4.child_id = MyRecords.parent_ID)SELECT top 1 parent_ID,Depth As anjusPath FROM MyRecords order by depth desc

--Get the childrenDECLARE @my_id intSET @my_id = 100; WITH MyRecords (ID, parent_ID)AS(SELECT child_ID ,parent_IDFROM table_4 WHERE parent_ID = @my_idUNION ALLSELECT table_4.child_ID,table_4.parent_ID FROM table_4JOIN MyRecords ON table_4.parent_ID = MyRecords.ID)SELECT ID As anjusPath FROM MyRecords

FUNCTION CALLING AND DEFINING

--calling functionselect distinct animalunitguid, dbo.[fnGetSexCount](dbo.GroupCount.SexRatio,'M')from groupcount

--functionset ANSI_NULLS ONset QUOTED_IDENTIFIER ONgo

--Recreate fnGetSexCount stored function ALTER FUNCTION [dbo].[fnGetSexCount] (@sexRatio AS VARCHAR(MAX) ,@sexType AS VARCHAR(100)) RETURNS INT AS BEGIN

DECLARE @returnSex AS INTDECLARE @sexRatiotemp AS VARCHAR(100)DECLARE @index AS INTDECLARE @length AS INT

Page 15: SQL - tips and tricks

DECLARE @count AS INTDECLARE @maleCount AS VARCHAR(100)DECLARE @femaleCount AS VARCHAR(100)DECLARE @unknownCount AS VARCHAR(100)

SET @maleCount ='0'SET @femaleCount ='0'SET @unknownCount ='0'

SET @sexRatio=REPLACE(@sexRatio,' ','')SET @sexRatiotemp=@sexRatioset @length=len(@sexRatio)SET @index = 0SET @count =0

while @index<=@lengthBEGIN

IF ASCII(SUBSTRING(@sexRatiotemp,@index,1))=46BEGIN

IF @count=0 -- AND @sexRatio<>'' AND @sexRatio<>'.'BEGIN

IF ISNUMERIC(SUBSTRING(@sexRatio,1,Charindex('.',@sexRatio)-1))=1

SET @maleCount = SUBSTRING(@sexRatio,1,Charindex('.',@sexRatio)-1)

END IF @count=1 -- AND @sexRatio<>'' AND @sexRatio<>'.'

BEGINIF

ISNUMERIC(SUBSTRING(@sexRatio,1,Charindex('.',@sexRatio)-1))=1SET @femaleCount =

SUBSTRING(@sexRatio,1,Charindex('.',@sexRatio)-1)END

SET @sexRatio = SUBSTRING(@sexRatio,Charindex('.',@sexRatio)

+1,@length) SET @count = @count + 1ENDIF @count=0 AND @length=@index AND ISNUMERIC(@sexRatio)=1

SET @maleCount = @sexRatioIF @count=1 AND @length=@index AND ISNUMERIC(@sexRatio)=1

SET @femaleCount = @sexRatioIF @count=2 AND @length=@index AND ISNUMERIC(@sexRatio)=1

SET @unknownCount = @sexRatioSET @index = @index + 1

ENDIF @sexType='M'

SET @returnSex = CAST(@maleCount AS INT)IF @sexType='F'

SET @returnSex = CAST(@femaleCount AS INT)IF @sexType='U'

SET @returnSex = CAST(@unknownCount AS INT)RETURN @returnSex

--PRINT @maleCount + ':' + @femaleCount + ':' + @unknownCount END

Page 16: SQL - tips and tricks

To get the latest sex ratio by date

Select m.animalunitguid,max(m.countdate),(select a.sexratio from  GroupCount a where a. countdate =max(m. countdate) AND a. animalunitguid = m. animalunitguid) from GroupCount m Group By m.animalunitguid

To get the distinct values concatenated of a varchar column in a table

SELECT substring(Ms, 1, datalength(Ms) / 2 - 1)FROM (SELECT yourFieldName + ';' AS [text()]FROM yourTableNameFOR XML PATH('')) AS T(Ms)

Comparison between Temp tables and Table variables

Hi All:

As we all are writing complex queries, sometimes even using temp tables, it’s worth

reading the performance impact on SQL Server. A comparison between Temp tables

and Table variables is given below for your reference:

Temporary Tables vs. Table Variables and Their Effect on SQL

Server Performance

There are three major theoretical differences between temporary tables:

Create table #T (…)

And table variables:

declare @T table (…)

The first difference is that transaction logs are not recorded for the table variables. Hence,

they are out of scope of the transaction mechanism, as is clearly visible from this example:

create table #T (s varchar(128))

declare @T table (s varchar(128))

insert into #T select 'old value #'

insert into @T select 'old value @'

begin transaction

Page 17: SQL - tips and tricks

     update #T set s='new value #'

     update @T set s='new value @'

rollback transaction

select * from #T

select * from @T

s

---------------

old value #

s

---------------

new value @

After declaring our temporary table #T and our table-variable @T, we assign each one with the

same "old value" string. Then, we begin a transaction that updates their contents. At this point,

both will now contain the same "new value" string. But when we rollback the transaction, as

you can see, the table-variable @T retained its value instead of reverting back to the "old

value" string. This happened because, even though the table-variable was updated within the

transaction, it is not a part of the transaction itself.

The second major difference is that any procedure with a temporary table cannot be pre-

compiled, while an execution plan of procedures with table variables can be statically compiled

in advance. Pre-compiling a script gives a major advantage to its speed of execution. This

advantage can be dramatic for long procedures, where recompilation can be too pricy.

Finally, table variables exist only in the same scope as variables. Contrary to the temporary

tables, they are not visible in inner stored procedures and in exec(string) statements. Also,

they cannot be used in an insert/exec statement.

But let's compare both in terms of performance.

At first, we prepare a test table with 1 million records:

create table NUM (n int primary key, s varchar(128))

GO

set nocount on

declare @n int

Page 18: SQL - tips and tricks

set @n=1000000

while @n>0 begin

     insert into NUM

          select @n,'Value: '+convert(varchar,@n)

     set @n=@n-1

     end

GO

Now we prepare our test procedure T1:

create procedure T1

     @total int

as

     create table #T (n int, s varchar(128))

     insert into #T select n,s from NUM

          where n%100>0 and n<=@total

     declare @res varchar(128)

     select @res=max(s) from NUM

          where n<=@total and

               not exists(select * from #T

               where #T.n=NUM.n)

GO

Called with a parameter, which we will vary from 10, 100, 1,000, 10,000, 100,000 up to

1,000,000, it copies the given number of records into a temporary table (with some

exceptions, as it skips records where n is divisible by 100), and then finds a max(s) of such

missing records. Of course, the more records we give, the longer the execution is.

To measure the execution time precisely, I use the code:

declare @t1 datetime, @n int

set @t1=getdate()

set @n=100 – (**)

while @n>0 begin

     exec T1 1000 – (*)

     set @n=@n-1 end

Page 19: SQL - tips and tricks

select datediff(ms,@t1,getdate())

GO

(*) The parameter to our procedure is varied from 10 to 1,000,000.

(**) If an execution time is too short, I repeat the same loop 10 or 100 times.

I run the code several times to get a result of a "warm" execution.

The results can be found in Table 1 below.

Now let's try to improve our stored procedure by adding a primary key to the temporary table:

create procedure T2

     @total int

as

     create table #T (n int primary key, s varchar(128))

     insert into #T select n,s from NUM

          where n%100>0 and n<=@total

     declare @res varchar(128)

     select @res=max(s) from NUM

          where n<=@total and

               not exists(select * from #T

               where #T.n=NUM.n)

GO

Then, let's create a third one. With a clustered index, it works much better. But let's create the

index AFTER we insert data into the temporary table—usually, it is better:

create procedure T3

     @total int

as

     create table #T (n int, s varchar(128))

     insert into #T select n,s from NUM

          where n%100>0 and n<=@total

     create clustered index Tind on #T (n)

     declare @res varchar(128)

     select @res=max(s) from NUM

Page 20: SQL - tips and tricks

          where n<=@total and

               not exists(select * from #T

               where #T.n=NUM.n)

GO

Surprise! Large amounts of data take longer; merely adding 10 records takes an additional 13

milliseconds. The problem is that "create index" statements force SQL server to recompile

stored procedures, and slows down the execution significantly.

Now let's try the same using table variables:

create procedure V1

     @total int

as

     declare @V table (n int, s varchar(128))

     insert into @V select n,s from NUM

          where n%100>0 and n<=@total

     declare @res varchar(128)

     select @res=max(s) from NUM

          where n<=@total and

               not exists(select * from @V V

               where V.n=NUM.n)

GO

To our surprise, this version is not significantly faster than the version with the temporary

table. This is a result of a special optimization SQL server has for the create table #T

statements in the very beginning of a stored procedure. For the whole range of values, V1

works better or the same as T1.

Now let's try the same with a primary key:

create procedure V2

     @total int

as

     declare @V table (n int primary key, s varchar(128))

     insert into @V select n,s from NUM

          where n%100>0 and n<=@total

     declare @res varchar(128)

Page 21: SQL - tips and tricks

     select @res=max(s) from NUM

          where n<=@total and

               not exists(select * from @V V

               where V.n=NUM.n)

GO

The result is much better, but T2 outruns this version.

Records T1 T2 T3 V1 V2

10 0.7 1 13.5 0.6 0.8

100 1.2 1.7 14.2 1.2 1.3

1000 7.1 5.5 27 7 5.3

10000 72 57 82 71 48

100000 883 480 580 840 510

1000000 45056 6090 15220 20240 12010

Table 1: Using SQL Server 2000, time in ms.

But the real shock is when you try the same on SQL Server 2005:

N T1 T2 T3 V1 V2

10 0.5 0.5 5.3 0.2 0.2

100 2 1.2 6.4 61.8 2.5

1000 9.3 8.5 13.5 168 140

10000 67.4 79.2 71.3 17133 13910

100000 700 794 659 Too long! Too long!

1000000 10556 8673 6440 Too long! Too long!

Table 2: Using SQL Server 2005 (time in ms).

Page 22: SQL - tips and tricks

In some cases, SQL 2005 was much faster then SQL 2000 (marked with green). But in many

cases, especially with huge amounts of data, procedures that used table variables took much

longer (highlighted with red). In four cases, I even gave up waiting.

Conclusion

There is no universal rule for when and where to use temporary tables or table variables.

Try them both and experiment.

In your tests, verify both sides of the spectrum—small numbers of records and huge data sets.

Be careful with migrating to SQL 2005 when you use complicated logic in your stored procedures. The same code can run 10-100 times slower on SQL server 2005!

DELETE STATEMENT

delete from table_1 from table_1 as ainner join table_5 as bon a.intempid=b.intid

OR

delete dbo.table_1 from dbo.table_1 inner join dbo.table_5 on dbo.table_1.intempid=dbo.table_5.intid

dbo is optional.

DELETE with TOP & PERCENT

Delete top (20) from table_1Delete top (20) percent from table_1

DELETE with output keyword

1. delete from table_1 output deleted.*

This will return all the deleted records of table_1. if we try to execute this query once again, then no o/p will be obtained.

2. The deleted records if needed can be saved to a table using the following query. Here the query has a table variable, it can be replaced by an ordinary table also.

--Table variabledeclare @tb table(intid int,chvname varchar(10))delete from Table_6 –-has 2 columns intid and chvnam

Page 23: SQL - tips and tricks

output deleted.intid,deleted.chvnaminto @tb

select * from @tb

--Ordinary tablecreate table tb(intid int,chvname varchar(10))delete from Table_6 -–has 2 columns intid and chvnamoutput deleted.intid,deleted.chvnaminto tb

select * from tb

NEW_ID()

Used to assign a new value to an uniqueidentifier variable.

DECLARE @myid uniqueidentifierSET @myid = NEWID()PRINT 'Value of @myid is: '+ CONVERT(varchar(255), @myid)

SET ROWCOUNT

Suppose there’s an update statement with a where clause. Actually the update statement will update the values of 7 rows of a table and if we set SET ROWCOUNT 4 then, only the first 4 rows will be affected by the update statement.set rowcount 4update table_6 set chvname='ab' where intid<15

SET NOCOUNT

Controls the message showing the number of rows affected by a query.SET NOCOUNT ON– does not display the number of rowsSET NOCOUNT OFF-displays the number of rows affected

NULLIF

This function returns a null values if the first parameter is equal to the second parameter

Eg: Suppose a table has a field chvname and it has values like A,B,C,D Select NULLIF(chvname,’A’) from table_1 will give the output as

NULLBCD

SCOPE_IDENTITY()

This will return the latest inserted identity column value in the database

Page 24: SQL - tips and tricks

Eg: Suppose table_1 has an auto increment column say id and when I run the 2 queries at the same time let the id have the value 5, then the same value will be inserted to table_2 also

Table_1 has fields id,chvname,frmdate,todateTable_2 has fields id,details,currdt

insert into table_1 values ('e','1/1/2008','2/6/2008')insert into table_2values (scope_identity(),'kgnjknjgknfg',getdate())

DIVISION

To get float values after division

Declare @i as intSet @i=1.0/2.0Select @i

Output is 0.5

GROUP BY can have WHERE clause like shown below

SELECT * from Table where {condition}GROUP BYHAVING {condition}

update tbl_sum set sval=(select sum(val) from tbl_sum s1 where s1.name=tbl_sum.name)

What's the earliest date that can be stored in a DATETIME data type?

DATETIME data types can store dates from January 1, 1753 through December 31, 9999, with an accuracy of three-hundredths of a second, or 3.33 milliseconds.

Page 25: SQL - tips and tricks

db_securityadminA. Manages roles and members of database rolesB. Manages statement permissions in the databaseC. Manages object permissions in the database

db_accessadminA. Adds or removes Windows groups and users, and SQL Server users in the

databaseB. The db_accessadmin fixed database role can add or remove Windows NT 4.0

or Windows 2000 groups and users, and SQL Server users in the database. On the other hand, the db_securityadmin fixed database role manages roles and members of SQL Server 2000 database roles, and manages statement and object permission in the database. Both db_setupadmin and db_sysadmin are not valid fixed database roles.

View text definitions are stored in which system table?

The syscomments system table contains entries for each view, rule, default, trigger, CHECK constraint, DEFAULT constraint and stored procedure. The text column contains the original SQL definition statements.

Trigger

create trigger UpdateWaterTypeLang on WaterTypeLang for UPDATE AS SET NoCount ON /* ERwin Builtin Thu Jun 21 10:43:34 2007 */ /* UPDATE trigger on WaterTypeLang */ begin Update WaterTypeLang set LastUpdtDate = GetUTCDate(), LastUpdtUserid = suser_sname() FROM WaterTypeLang JOIN Inserted ON WaterTypeLang.WaterTypeCode = Inserted.WaterTypeCode AND WaterTypeLang.LanguageCode = Inserted.LanguageCode return error: raiserror ('Update trigger UpdateWaterTypeLang on WaterTypeLang failed',16,1) rollback transaction end

A SMALLDATETIME data type is stored internally in SQL Server as two 2-byte integers. The first 2 bytes store the number of days after the base date of January 1, 1900. Given this, a value of 0 corresponds to January 1, 1900. Since a SMALLDATETIME only stores the number of days AFTER January 1, 1900, any negative values will generate an error.

ROUND

The ROUND function returns a numeric expression rounded to the specified length or precision. The second parameter of the ROUND function is the precision to which the input numeric expression is to be rounded. When the second parameter is a negative number, the numeric expression is rounded on the left side of the decimal point, as specified in the length.

Page 26: SQL - tips and tricks

What's the maximum number of parameters can a SQL Server 2000 stored procedure have?

The maximum number of parameters a stored procedure in SQL Server can have is 1,024, which is also the maximum number of columns a table can have.

The order of data type precedence of the given options from highest to lowest: SMALLDATETIME, SMALLMONEY, SMALLINT CHAR.

CURRENT_DATE is a reserved word, so can not be used as an object or column name. DATE, SMALLDATETIME, TIMESTAMP, DATETIME are not reserved words. So they can be used as object or column names.

Using the INSERT statement in a user-defined function is not allowed unless the target table is a table variable local to the function. The INSERT command is only allowed when modifying table variables local to the function.

Fixed server roles can be mapped to the more specific permissions that are included in SQL Server 2005. The following table describes the mapping of the fixed server roles to permissions.

Fixed server role Server-level permission

bulkadmin Granted: ADMINISTER BULK OPERATIONS

dbcreator Granted: CREATE DATABASE

diskadmin Granted: ALTER RESOURCES

processadmin

Granted: ALTER ANY CONNECTION, ALTER SERVER STATE

securityadmin

Granted: ALTER ANY LOGIN

serveradmin

Granted: ALTER ANY ENDPOINT, ALTER RESOURCES, ALTER SERVER STATE, ALTER SETTINGS, SHUTDOWN, VIEW SERVER STATE

setupadmin Granted: ALTER ANY LINKED SERVER

sysadmin Granted with GRANT option: CONTROL SERVER

Updatable Views

INSERT, UPDATE and DELETE statements may be used on views.

Page 27: SQL - tips and tricks

The operation is then performed on the base table upon which the view is defined. However, certain views may not be updated (for example a view containing DISTINCT values, where a single row in the view may represent several rows in the base table).

A view is not updatable if any of the following conditions are true:

the keyword DISTINCT is used in the view definition the select list contains components other than column specifications, or

contains more than one specification of the same column the FROM clause specifies more than one table reference or refers to a non-

updatable view the GROUP BY clause is used in the view definition the HAVING clause is used in the view definition

Note: By defining an INSTEAD OF trigger any view can be made updatable. If all the INSTEAD OF triggers on the view are dropped, the view will revert to not updatable if one or more of the conditions are true.

Link about Updatable Views with exampleshttp://www.ibm.com/developerworks/db2/library/techarticle/0210rielau/0210rielau.htmlalter view vwas select intempid,monRs*monRs as amt from TB_Projectleft outer join table_2 on TB_Project.intEmpid=table_2.id

select * from vwdelete from vw where intempid =4545update vw set intempid=4545 where intempid=1010insert into vw (intempid) values(1010)

get nth highest value

SELECT intEmpID,fltBasicPayFROM TB_PayParticulars_Lcl_Mst AWHERE 5=(SELECT COUNT (DISTINCT fltBasicPay) FROM TB_PayParticulars_Lcl_MstWHERE A.fltBasicPay<=fltBasicPay)

select fltBasicPay from TB_PayParticulars_Lcl_Mst twhere 5= (select count(fltBasicPay)from (select distinct fltBasicPay from TB_PayParticulars_Lcl_Mst)bwhere t.fltBasicPay<=fltBasicPay)

Send mail via SP.

Create a profile in Management Database mail. Give the email address, server name and all details to create an acoount.

EXEC msdb.dbo.sp_send_dbmail @profile_name = 'Anju', @recipients = @email,@copy_recipients='[email protected]',

Page 28: SQL - tips and tricks

@body = @msg, @subject = 'Account information is updated',@body_format ='HTML'