Search

Showing posts with label SQL Server 2005. Show all posts
Showing posts with label SQL Server 2005. Show all posts

Dec 16, 2008

Display multiple comma separated value into single column output Part II

Here is the data:

Field1      Field2
----------- --------------------
1 A,B,C
2 A
3 D,G


And we need output as following

Field1               ID
-------------------- ----
1 A
1 B
1 C
2 A
3 D
3 G

Lets create data first.

DECLARE @Fields AS TABLE
(
Field1 INT,
Field2 VARCHAR(20)
)

INSERT INTO @Fields VALUES (1,'A,B,C')
INSERT INTO @Fields VALUES (2,'A')
INSERT INTO @Fields VALUES (3,'D,G')

Here is the query for getting expected result.

SET @AnswerXML =
REPLACE(REPLACE((SELECT
Field1, '<Ids><Id value="' + REPLACE(Field2, ',','" /><Id value="') + '" /></Ids>'
FROM @Fields
FOR XML PATH ('F')
), '&lt;', '<'), '&gt;', '>')

SELECT
Answer.value('Field1[1]', 'BIGINT') as Field1
,y.value('@value[1]', 'VARCHAR(1)') AS ID
FROM
@AnswerXML.nodes('/F') p(Answer)
OUTER APPLY Answer.nodes('Ids/Id') o(y)

Also check Display multiple comma separated value into single column output Part I

Nov 28, 2008

Display multiple comma separated value into single column output

Here is the data:

Field1      Field2
----------- --------------------
1 A,B,C
2 A
3 D,G

And we need output as following


output
------
A
B
C
A
D
G

Lets create data first.

DECLARE @Fields AS TABLE
(
Field1 INT,
Field2 VARCHAR(20)
)

INSERT INTO @Fields VALUES (1,'A,B,C')
INSERT INTO @Fields VALUES (2,'A')
INSERT INTO @Fields VALUES (3,'D,G')

Here is the query for getting expected result.


DECLARE @FieldXml AS XML

DECLARE @v VARCHAR(MAX)

--Creates single row for Field2
SELECT @v = (SELECT ',' + Field2 FROM @Fields FOR XML PATH(''))
--Remove the first comma
SELECT @v = SUBSTRING(@v, 2, LEN(@v))

--Add the XML tag
SELECT @FieldXml = '<F value="' + REPLACE(@v , ',', '" /><F value="') + '" />'

--List single attribute value
SELECT x.value('@value', 'VARCHAR(1)') AS [output]
FROM @FieldXml.nodes('/F') p(x)

Oct 8, 2008

Finding nth maximum number in SQL Server 2005

This is the frequent requirement for the developer to find the nth max number from the table. It will easy to get it if you are using SQL Server 2005, as its allows us to make the top query variable.

Please read the Flexibility using TOP clause in SQL Server 2005 for more details.

Lets say, we are having student and their marks, and we want the nth max mark. First will see the table structure and will add few data into it.


SET NOCOUNT ON
DECLARE @Marks TABLE
(
StudName VARCHAR(100),
Mark INT
)

INSERT INTO @Marks VALUES('AAAAA', 55)
INSERT INTO @Marks VALUES('BBBBB', 65)
INSERT INTO @Marks VALUES('CCCCC', 59)
INSERT INTO @Marks VALUES('DDDDD', 52)
INSERT INTO @Marks VALUES('FFFFF', 65)
INSERT INTO @Marks VALUES('EEEEE', 95)

SELECT Mark FROM @Marks ORDER BY Mark DESC

Mark
-----------
95
65
65
59
55
52

Now we write the query which allow us to find nth max mark form this list.


DECLARE @Top INT
SET @Top = 2

SELECT MIN(Mark) AS 'Top' FROM(
SELECT DISTINCT TOP (@Top) Mark FROM @Marks ORDER BY Mark DESC) A

Top
-----------
65

@Top is variable; which gives you the ability to fetch Nth max.

Sep 18, 2008

Visual Studio IDE Support for SQL Server

Hello,

As we all know Visual Studio is now supporting Database project, which allows you to write query, procedure etc... from IDE only.

Recently I found the error while connecting SQL2008 from VS2008.

This server version is not supported. Only servers up to Microsoft SQL Server 2005 are supported.

I found after doing some googling; that there is no patch available which allos me to connect SQL2008 to VS2008!!!.

I found few comments which says that it will come soon.

Somasegar's WebLog
Euan Garden's BLOG

However there is Sservice Pack for Visual Studio 2008 Team Foundation Server which has ability to Support for SQL Server 2008, you can download that form Microsoft Download Center

Let me add that there is Service Pack for Visual Studio 2005 Support for SQL Server 2008, which you can download it from Microsoft Download Center

Jun 17, 2008

APPLY Clause in SQL Server 2005


select ClientId, Birthday from
(select top 10 Clnt.* from [Client] Clnt
inner join CaseClient CC on Clnt.ClientId = CC.ClientID
inner join [Case] C on C.CaseID = CC.CaseID order by Clnt.ClientID) as Result
This is the query which returns me the ClientId and Birthday; its TOP 10 Clients.

select Clnt.ClientId, Birthday, TopData.FormNumber from
(select top 10 Clnt.* from [Client] Clnt
inner join CaseClient CC on Clnt.ClientId = CC.ClientID
inner join [Case] C on C.CaseID = CC.CaseID order by Clnt.ClientID) as Result
inner join
(select TOP (3) * from ClientSession where ClientSession.ClientID = Result.ClientId) TopData
on TopData.ClientID = Result.ClientID
What I am trying to do here is… there is multiple sessions for one client, and form that multiple I need top 3 rows and its FormNumner. The above query will syntactically right, parser will not generate any error; but it will at compile time it will throw error

Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "Result.ClientId" could not be bound.
Msg 4104, Level 16, State 1, Line 1
The multi-part identifier "Clnt.ClientId" could not be bound.

For correlated Join; Result is not defined.

So here is the solution with SQL Server 2005's new APPLY clause. The APPLY clause let's you join a table to a table-valued-function. That let's you write a query like this:

select Result.ClientID, Result.Birthday, TopData.FormNumber from
(select top 10 Clnt.* from [Client] Clnt
inner join CaseClient CC on Clnt.ClientId = CC.ClientID
inner join [Case] C on C.CaseID = CC.CaseID order by Clnt.ClientID) as Result
CROSS/span> Apply
fn_GetTopClientSession(Result.ClientId, 3) AS TopData

And here is the expected output

ClientID Birthday FormNumber
----------- ----------------------- -----------
46 1990-01-01 00:00:00.000 11094
46 1990-01-01 00:00:00.000 11062
46 1990-01-01 00:00:00.000 30211
52 1983-01-04 00:00:00.000 11159
52 1983-01-04 00:00:00.000 11155
52 1983-01-04 00:00:00.000 30190
53 2000-01-01 00:00:00.000 11154
53 2000-01-01 00:00:00.000 11158
53 2000-01-01 00:00:00.000 11157
68 2000-01-01 00:00:00.000 10104
68 2000-01-01 00:00:00.000 12168
68 2000-01-01 00:00:00.000 11215
73 1957-10-09 00:00:00.000 11137
73 1957-10-09 00:00:00.000 32464
73 1957-10-09 00:00:00.000 11150


And here is the function

CREATE FUNCTION dbo.fn_GetTopClientSession(@ClientId AS int, @n AS INT)
RETURNS TABLE
AS
RETURN
select TOP (@n) * from ClientSession where ClientSession.ClientID = @ClientId
GO

I just put the Correlated Join query inside the Function, nothing more.

You can see the APPLY clause acts like a JOIN without the ON clause!!!

There are two flavors of APPLY clause, CROSS and OUTER. The OUTER APPLY clause returns all the rows on the left side whether they return any rows in the table-valued-function or not. The columns that the table-valued-function returns are null if no rows are returned. The CROSS APPLY only returns rows from the left side f the table-valued-function returns rows.

Notice that I'm just passing in the ClientId to the function. It returns the TOP 3 rows based on the amount of the order. Since I'm using CROSS APPLY a Cases without Client won't appear in the list. I can also pass in a number other than 3 to easily return a different number of Cases per Client. So I could list the top 5. How cool is that?!?

Jun 16, 2008

Flexibility using TOP clause in SQL Server 2005

Hello all,

Upto now we know that how to use TOP clause in Sql Server 2000 . SQL Server 2005 come up with more flexible way to use TOP clause.

Here is the simple way to get TOP 10 [or say 'n' a dynamic number] from a table.

DECLARE @Rows INT
SET @Rows = 10

SELECT TOP ( @Rows ) *
FROM TempMaster
This will return the top 10 rows from TempMaster. You can also replace @Rows with anything that evaluates to a number.

Now look at the following query; its odd but runs just fine:

SELECT TOP ( SELECT COUNT(*) FROM TempMaster ) *
FROM TempDetails
You can also use the TOP clause for INSERT, UPDATE and DELETE statements. If you wanted to DELETE in batches of 500 you can now do that using the TOP clause.

May 7, 2008

Converting row to column in Sql Server 2005

Consider the following data and our target is to have all the ClientId starting form 247 to 252 will be in column
name Client1, Client2... etc. 
UserID      CaseID      CaseNumber  ClientID
----------- ----------- ----------- -----------
80 216 1087 247
80 216 1087 248
80 216 1087 249
80 216 1087 250
80 216 1087 251
80 216 1087 252
80 276 1140 328
80 277 1143 329
80 347 1191 438
80 348 1192 439

SQL Server 2005 introduced Ranking, Partitioning and Pivoting. By using all togather
we can achive our goal.



Ranking functions that provide the ability to rank a record within a partition. 
In this case, we can use RANK() to assign a unique number for each record, and partition
by the ClientID (so that the RANK will reset for each ClientID)

By prefixing some text to the rank number, we end up with something like:


SELECT UserID, C.CaseID, CaseNumber, ClientID, 
'ClientId' + CAST(
RANK() OVER (
PARTITION BY C.CaseID, CaseNumber
ORDER BY ClientID) AS VARCHAR(10)) ClientIdListing
FROM [Case] C, CaseClient CC
WHERE C.CaseId = CC.CaseID AND USerID = 80

Result:


UserID      CaseID      CaseNumber  ClientID    ClientIdListing
----------- ----------- ----------- ----------- ------------------
80 216 1087 247 ClientId1
80 216 1087 248 ClientId2
80 216 1087 249 ClientId3
80 216 1087 250 ClientId4
80 216 1087 251 ClientId5
80 216 1087 252 ClientId6
80 276 1140 328 ClientId1
80 277 1143 329 ClientId1
80 347 1191 438 ClientId1
80 348 1192 439 ClientId1

The new column (ClientIdListing) is the concatenation of the literal string "ClientId"
and the string representation of the number that the RANK function returned. But
the bigger point is that now this column can be used for pivoting, and result in
a series of new columns called [ClientId1], [ClientId2], [ClientId3], etc.




Pivoting in SQL Server 2005 requires explicit declaration of values as a column
list. In this case, we can't just say "Pivot on the ClientIdListing column", but
rather must say "Pivot on the ClientIdListing column, and make new columns only
for these specific values". This restriction is a little bit of a downside because
we need knowledge of the values in the column. Or, in this case, we need to know
how many ClientIds a Case could possibly have so that we create enough columns in
the result.




So here is the final query:

SELECT * FROM
(SELECT UserID, C.CaseID, CaseNumber, ClientID, 'ClientId'
+ CAST(RANK() OVER (PARTITION BY C.CaseID, CaseNumber
ORDER BY ClientID)
AS VARCHAR(10)) ClientIdListing
FROM [Case] C, CaseClient CC
WHERE C.CaseId = CC.CaseID
AND USerID = 80) P

PIVOT
(MAX(ClientID) FOR ClientIdListing IN
(ClientID1, ClientID2, ClientID3, ClientID4, ClientID5, ClientID6)
) AS Clients

And here is the Output:


UserID CaseID CaseNumber ClientID1 ClientID2 ClientID3 ClientID4 ClientID5 ClientID6
----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
80 216 1087 247 248 249 250 251 252
80 276 1140 328 NULL NULL NULL NULL NULL
80 277 1143 329 NULL NULL NULL NULL NULL
80 347 1191 438 NULL NULL NULL NULL NULL
80 348 1192 439 NULL NULL NULL NULL NULL

Jan 21, 2008

Passing lists to SQL Server 2005 with XML Parameters

We frequently have requirement like

Passing IDs in comma saperated value to the sql server for further processing.

Generally what we do is just create loop and get the value from it and ...

But SQL 2005 comes up with XQuery. Using this you can easly pass such type of data also some complex thing too.

For example...

DECLARE @productIds xml
SET @productIds ='<Products><id>3</id><id>6</id><id>15</id></Products>'


SELECT ParamValues.ID.value('.','VARCHAR(20)')FROM @productIds.nodes('/Products/id') as ParamValues(ID)

Which gives us the following three rows:

3
6
15

Read more..

Apr 4, 2007

Exception Handling in SQL2k5

Hi

For handling exception just need to write 4 additional statements!


BEGIN TRY
print convert(int, 'hi')
END TRY
BEGIN CATCH
print @@ERROR
print 'ERROR'
END CATCH

OUTPUT:
245
ERROR

It's simple!!