How to PIVOT over up to 49 fields? - tsql

I have a table that contains procedure data. There can be up to 49 entries for a given encounter. I want to output one row for each account and include the procedure, date and provider. I've tried writing CASE statements to this end:
Select DISTINCT [Encounter Number],
CASE When [Encounter Proc Sequence] = '1' Then [Procedure Code (Enctr)]
END as 'Proc1',
Case When [Encounter Proc Sequence] = '1' Then [Date of Service]
END as 'SvcDate1',
CASE When [Encounter Proc Sequence] = '1' Then [Surgeon]
END as 'Surgeon1',
CASE When [Encounter Proc Sequence] = '2' Then [Procedure Code (Enctr)]
END as 'Proc2',
Case When [Encounter Proc Sequence] = '2' Then [Date of Service]
END as 'SvcDate2',
CASE When [Encounter Proc Sequence] = '2' Then [Surgeon]
END as 'Surgeon2',
CASE When [Encounter Proc Sequence] = '3' Then [Procedure Code (Enctr)]
END as 'Proc3',
Case When [Encounter Proc Sequence] = '3' Then [Date of Service]
END as 'SvcDate3',
CASE When [Encounter Proc Sequence] = '3' Then [Surgeon]
END as 'Surgeon3',
CASE When [Encounter Proc Sequence] = '4' Then [Procedure Code (Enctr)]
END as 'Proc4',
Case When [Encounter Proc Sequence] = '4' Then [Date of Service]
END as 'SvcDate4',
CASE When [Encounter Proc Sequence] = '4' Then [Surgeon]
END as 'Surgeon4',
CASE When [Encounter Proc Sequence] = '5' Then [Procedure Code (Enctr)]
END as 'Proc5',
Case When [Encounter Proc Sequence] = '5' Then [Date of Service]
END as 'SvcDate5',
CASE When [Encounter Proc Sequence] = '5' Then [Surgeon]
END as 'Surgeon5',
CASE When [Encounter Proc Sequence] = '6' Then [Procedure Code (Enctr)]
END as 'Proc6',
Case When [Encounter Proc Sequence] = '6' Then [Date of Service]
END as 'SvcDate6',
CASE When [Encounter Proc Sequence] = '6' Then [Surgeon]
END as 'Surgeon6',
CASE When [Encounter Proc Sequence] = '7' Then [Procedure Code (Enctr)]
END as 'Proc7',
Case When [Encounter Proc Sequence] = '7' Then [Date of Service]
END as 'SvcDate7',
CASE When [Encounter Proc Sequence] = '7' Then [Surgeon]
END as 'Surgeon7'
from EncounterProc
where [Date of Service] between '20090101' and '20091231'
and [Procedure Code (ENCTR)] is not null
Group by [Encounter Number], [Encounter Proc Sequence],[Procedure Code (ENCTR)], [Date of
Service], Surgeon
The query output shows some duplicated rows and the query isn't placing procedure 3 (for example) in the Proc3 column.
How would I setup the PIVOT syntax for this scenario?
UPDATE:
I've read the MSDN Library documentation on PIVOT, and also the link shared in Comments. I took a stab at adapting those sources to my need as follows:
Select [Encounter Number],
[1] as Proc1,
[Date1] as SvcDate1,
[MD1] as MD1,
[2] as Proc2,
[Date2] as SvcDate2,
[MD2] as MD2,
[3] as Proc3,
[Date3] as SvcDate3,
[MD3] as MD3,
[4] as Proc4,
[Date4] as SvcDate4,
[MD4] as MD4
From
(Select * From
(SELECT [Encounter Number]
,[Procedure Code (Enctr)]
,Row_Number() OVER ( Partition By [Encounter Number] Order By
[Encounter Number], [Procedure Code (Enctr)] ) AS RowNumber
FROM EncounterProc)
PIVOT ( MAX([Procedure Code (Enctr)] ) for RowNumber IN
( [1], [Date1], [MD1],[2], [Date2], [MD2], [3], [Date3], [MD3], [4], [Date4],
[MD4]))
When I run this query, SSMS gives me the following error:
Incorrect syntax near the keyword 'PIVOT'.
Update2: Based on Stuart's comment, I've revised the query to be:
Select [Encounter Number],
p.[1] as Proc1,
p.[Date1] as SvcDate1,
p.[MD1] as MD1,
p.[2] as Proc2,
p.[Date2] as SvcDate2,
p.[MD2] as MD2,
p.[3] as Proc3,
p.[Date3] as SvcDate3,
p.[MD3] as MD3,
p.[4] as Proc4,
p.[Date4] as SvcDate4,
p.[MD4] as MD4
From
(Select * From
(SELECT [Encounter Number]
,[Procedure Code (Enctr)]
,[Date of Service]
,[Surgeon]
,Row_Number() OVER ( Partition By [Encounter Number] Order By
[Encounter Number], [Encounter Proc Sequence] ) AS RowNumber
FROM EncounterProc) p
PIVOT ( MAX([Procedure Code (Enctr)] ) for RowNumber IN
( [1], [Date1], [MD1],[2], [Date2], [MD2], [3], [Date3], [MD3], [4], [Date4],
[MD4]) )
I now receive a new error stating:
Msg 102, Level 15, State 1, Line 23
Incorrect syntax near ')'.
which points to the closing parenthesis of the PIVOT statement.
What must be done to fix the syntax error?

Your first query is the closest one, except that you did not enclosed every case into aggreagate function. Also it seems that you do not need some columns in group by clause:
select
[Encounter Number],
Proc1 = max(CASE When [Encounter Proc Sequence] = '1' Then [Procedure Code (Enctr)] END),
SvcDate1 = max(Case When [Encounter Proc Sequence] = '1' Then [Date of Service] END),
Surgeon1 = max(CASE When [Encounter Proc Sequence] = '1' Then [Surgeon] END),
Proc2 = max(CASE When [Encounter Proc Sequence] = '2' Then [Procedure Code (Enctr)] END),
SvcDate2 = max(Case When [Encounter Proc Sequence] = '2' Then [Date of Service] END),
Surgeon2 = max(CASE When [Encounter Proc Sequence] = '2' Then [Surgeon] END),
Proc3 = max(CASE When [Encounter Proc Sequence] = '3' Then [Procedure Code (Enctr)] END),
SvcDate3 = max(Case When [Encounter Proc Sequence] = '3' Then [Date of Service] END),
Surgeon3 = max(CASE When [Encounter Proc Sequence] = '3' Then [Surgeon] END)
--- etc.
from EncounterProc
where [Date of Service] between '20090101' and '20091231'
and [Procedure Code (ENCTR)] is not null
group by [Encounter Number], [Encounter Proc Sequence]

Related

conditional Order By SQL statement for tokio postgres in Rust [duplicate]

How can i achieve dynamic order by column and sort direction in a postgresql function.
Here is what i have so far:
CREATE OR REPLACE FUNCTION get_urls_by_crawl_id(
p_account_id character varying(64),
p_crawl_id character varying(64),
p_sort_column character varying(30),
p_sort_direction character varying(30),
p_page integer,
p_total integer
)
RETURNS TABLE(id character varying(64), source_url text, http_status_code integer, ref_cnt integer) AS $BODY$
BEGIN
RETURN QUERY SELECT u.id, u.source_url, u.http_status_code, u.ref_cnt FROM url AS u
JOIN crawl AS c ON(u.crawl_id = c.id)
JOIN site AS s ON(c.site_id = s.id)
JOIN person AS p ON(s.person_id = p.id)
WHERE p.account_id = p_account_id AND u.crawl_id = p_crawl_id AND u.secured = 0
ORDER BY p_sort_column (CASE WHEN p_sort_direction = 'ASC' THEN ASC ELSE DESC END) LIMIT p_total OFFSET (p_page * p_total);
END;
$BODY$ LANGUAGE plpgsql;
the psql client returns this error:
ERROR: syntax error at or near "ASC"
LINE 16: ...t_column (CASE WHEN p_sort_direction = 'ASC' THEN ASC ELSE D...
I have tried multiple forms of the CASE statement but none seems to work.
Use two different order by keys:
ORDER BY (case when p_sort_direction = 'ASC' then p_sort_column end)
asc,
p_sort_column desc
LIMIT p_total OFFSET (p_page * p_total);
Note that you have another problem. p_sort_column is a string. You would need to use dynamic SQL to insert it into the code.
Alternatively, you can use a series of cases:
order by (case when p_sort_column = 'column1' and p_sort_direction = 'ASC' then column1 end) asc,
(case when p_sort_column = 'column1' and p_sort_direction = 'DESC' then column1 end) desc,
(case when p_sort_column = 'column2' and p_sort_direction = 'ASC' then column2 end) asc,
(case when p_sort_column = 'column2' and p_sort_direction = 'DESC' then column2 end) desc,
. . .

SQL OVER(Partition) issue - selecting a subset

I'm trying to get a specific subset of data using "over(partition)" syntax. I've created sample data to illustrate. Running the following CTE results in the a small example result set.
I need to calculate 2 date ranges using the following definitions/pseudocode
1: Days to close = CloseDate where stat = 'Closed' minus opendate partitioned by problem
2: Days to solve = "ClosedDate where stat = 'Solved' minus opendate partitioned by problem.
I can get #1 using the over(partition) syntax, but I cannot figure out #2.
with cte as
(
select 114110712007835 as 'SRNumber', 214110712007835004 as ProblemNumber, 'Open' as 'Stat', 314110712007835004001 as TaskNumber, convert(datetime, '2015-03-02 19:47:43',120) as OpenDate, convert(datetime, '2015-03-03 19:36:37',120) as CloseDate union
select 114110712007835 as 'SRNumber', 214110712007835004 as ProblemNumber, 'Investigate' as 'stat', 314110712007835004002 as TaskNumber, convert(datetime, '2015-03-04 00:29:13',120) as OpenDate, convert(datetime, '2015-03-05 19:36:34',120) as CloseDate union
select 114110712007835 as 'SRNumber', 214110712007835004 as ProblemNumber, 'Solve' as 'stat', 314110712007835004003 as TaskNumber, convert(datetime, '2015-03-06 18:17:13',120) as OpenDate, convert(datetime, '2015-03-07 13:07:31',120) as CloseDate union
select 114110712007835 as 'SRNumber', 214110712007835004 as ProblemNumber, 'Close' as 'stat', 315032012542588001001 as TaskNumber, convert(datetime, '2015-03-08 15:24:34',120) as OpenDate, convert(datetime, '2015-03-09 15:15:42',120) as CloseDate union
select 114110712007835 as 'SRNumber', 215032012542588001 as ProblemNumber, 'Open' as 'stat', 315032012542588001002 as TaskNumber, convert(datetime, '2015-04-20 20:05:48',120) as OpenDate, convert(datetime, '2015-04-21 03:24:24',120) as CloseDate union
select 114110712007835 as 'SRNumber', 215032012542588001 as ProblemNumber, 'Investigate' as 'stat', 315032012542588001003 as TaskNumber, convert(datetime, '2015-04-22 18:55:03',120) as OpenDate, convert(datetime, '2015-04-23 03:24:28',120) as CloseDate union
select 114110712007835 as 'SRNumber', 215032012542588001 as ProblemNumber, 'Solve' as 'stat', 315032012542588001004 as TaskNumber, convert(datetime, '2015-04-24 13:35:24',120) as OpenDate, convert(datetime, '2015-04-27 02:24:31',120) as CloseDate union
select 114110712007835 as 'SRNumber', 215032012542588001 as ProblemNumber, 'Close' as 'stat', 315032012542588001004 as TaskNumber, convert(datetime, '2015-04-26 13:35:24',120) as OpenDate, convert(datetime, '2015-04-29 03:24:31',120) as CloseDate
)
select srnumber, problemnumber, stat, opendate, closedate, --min(opendate) over(partition by problemnumber) as MinDate, max(closedate) over(partition by problemnumber) as MaxDate
case
when stat = 'Solve' then datediff(mi,min(opendate) over(partition by problemnumber),max(closedate) over(partition by problemnumber))
else NULL end as Days_to_Solve
,datediff(mi,min(opendate) over(partition by problemnumber),max(closedate) over(partition by problemnumber)) as Days_to_Close
from cte
order by problemnumber asc, opendate asc
go
A subquery could get you the result you need.
SELECT srnumber ,
problemnumber ,
stat ,
opendate ,
closedate , --min(opendate) over(partition by problemnumber) as MinDate, max(closedate) over(partition by problemnumber) as MaxDate
( CASE WHEN stat = 'Solve'
THEN ( SELECT TOP 1
DATEDIFF(mi, MIN(opendate) OVER ( ),
MAX(closedate) OVER ( ))
FROM cte c
WHERE c.problemnumber = cte.problemnumber
AND c.CloseDate <= cte.CloseDate
)
ELSE NULL
END ) AS Days_to_Solve ,
DATEDIFF(mi, MIN(opendate) OVER ( PARTITION BY problemnumber ),
MAX(closedate) OVER ( PARTITION BY problemnumber )) AS Days_to_Close
FROM cte
ORDER BY problemnumber ASC ,
opendate ASC
My results very closely resemble user1221684's, but I use windows functions instead of a subquery. So my answer should run a little more efficiently and it's simpler. Check it out:
SELECT *,
DATEDIFF( MI, --this is minutes. For days switch "MI" to "DAY"
MIN(CASE WHEN [Stat] = 'Open' THEN OpenDate END) OVER (PARTITION BY problemNumber),
MIN(CASE WHEN [Stat] = 'Solve' THEN CloseDate END) OVER (PARTITION BY problemNumber)
) AS Minutes_To_Solve
,
DATEDIFF( MI, --this is minutes. For days switch "MI" to "DAY"
MIN(CASE WHEN [stat] = 'Open' THEN OpenDate END) OVER (PARTITION BY problemNumber),
MIN(CASE WHEN [Stat] = 'Close' THEN CloseDate END) OVER (PARTITION BY problemNumber)
) AS Minutes_To_Close
FROM CTE
ORDER BY OpenDate

Adding a, b, c to end of data [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I have table with contract_code column, but in this column have same data, how can I change the same data to samedata_a, and samedata_b and etc.
For example:
Change this data
ASFRETERT
JDFJDSFJS
ASFRETERT
TO
ASFRETERT_a
JDFJDSFJS
ASFRETERT_b
You can perform this by applying a row_number() to the column. If you don't need the additional character to be an alpha character then it would be easier using the following:
The first version using CTE:
-- cte version
;with cte as
(
select col1, row_number() over(partition by col1 order by col1) rn
from yourtable
)
select
case when t1.cnt > 1
then c.col1 + '_'
+ cast(c.rn as varchar(10))
else c.col1
end yourColumn
from cte c
inner join
(
select count(*) cnt, col1
from yourtable
group by col1
) t1
on c.col1 = t1.col1;
The second version uses sub-queries
-- non-cte version
select case when t2.cnt > 1
then t1.col1 + '_'
+ cast(t1.rn as varchar(10))
else t1.col1
end yourColumn
from
(
select col1, row_number() over(partition by col1 order by col1) rn
from yourtable
) t1
inner join
(
select count(*) cnt, col1
from yourtable
group by col1
) t2
on t1.col1 = t2.col1
See SQL Fiddle with Demo. The two versions above add an integer to the end of the column but if you want to apply an alpha character, you should add a function to your database (Code for function from this question on StackOverflow):
CREATE FUNCTION dbo.fnColumnNameFromIndex(#i int)
RETURNS varchar(3)
AS
BEGIN
DECLARE #dividend int, #letters varchar(3), #modulo int
SET #dividend = #i
SET #letters = ''
WHILE #dividend > 0
BEGIN
SET #modulo = (#dividend - 1) % 26
SET #letters = CHAR(65 + #modulo) + #letters
SET #dividend = CONVERT(int, (#dividend - #modulo) / 26 )
END
RETURN #letters
END
If you create this function, then you can get the alpha character for each row. Your queries would then be:
The CTE version:
-- cte version
;with cte as
(
select col1, row_number() over(partition by col1 order by col1) rn
from yourtable
)
select
case when t1.cnt > 1
then c.col1 + '_'
+ cast(dbo.fnColumnNameFromIndex(c.rn) as varchar(10))
else c.col1
end yourColumn
from cte c
inner join
(
select count(*) cnt, col1
from yourtable
group by col1
) t1
on c.col1 = t1.col1;
The sub query version:
-- non-cte version
select case when t2.cnt > 1
then t1.col1 + '_'
+ cast(dbo.fnColumnNameFromIndex(t1.rn) as varchar(10))
else t1.col1
end yourColumn
from
(
select col1, row_number() over(partition by col1 order by col1) rn
from yourtable
) t1
inner join
(
select count(*) cnt, col1
from yourtable
group by col1
) t2
on t1.col1 = t2.col1
See SQL Fiddle with Demo

SQL Server 2000: select into case when in order by clause

I am trying to select rows into a temporary table with a CASE statement in the ORDER BY clause but records are not being sorted on insert.
Declare #orderby varchar(10) , #direction varchar(10)
set #orderby = 'col1'
set #direction = 'desc'
select identity (int) as autoid, *
into #temp
from table
order by case when #direction = 'desc' and #orderby = 'co1' then col1 end desc
declare #startrow int
declare #maxrows int
set #starrow = 19
set #maxrow = 30
set rowcount #maxrows
select * from #temp
where autoid > #startrow
Worst case - you'll just have to use two separate SQL queries to achieve your goal:
if #direction = 'desc'
select identity (int) as autoid, *
into #temp
from table
order by col1 desc
if #direction = 'asc'
select identity (int) as autoid, *
into #temp
from table
order by col1 asc
You'll need to use multiple sort conditions in your order by clause to handle this properly. The problem with this approach is that the performance will be bad when you have a lot of rows in the table because of that nasty sort operation.
Instead, you may be better off using dynamic SQL (as someone else suggested).
Declare #orderby varchar(100) , #direction varchar(10)
set #orderby = 'col1'
set #direction = 'desc'
select identity (int) as autoid, *
into #temp
from table
order by case when #direction = 'desc' and #orderby = 'col1' then col1 end desc,
case when #direction = 'asc' and #orderby = 'col1' then col1 end,
case when #direction = 'desc' and #orderby = 'col2' then col2 end desc,
case when #direction = 'asc' and #orderby = 'col2' then col2 end,
case when #direction = 'desc' and #orderby = 'col3' then col3 end desc,
case when #direction = 'asc' and #orderby = 'col3' then col3 end,
case when #direction = 'desc' and #orderby = 'col4' then col4 end desc,
case when #direction = 'asc' and #orderby = 'col4' then col4 end,
case when #direction = 'desc' and #orderby = 'col5' then col5 end desc,
case when #direction = 'asc' and #orderby = 'col5' then col5 end
You can achieve this not using #temp tables insted use normal table temp. Later when you are done with your process you can drop it at the end.
declare #dir varchar(10)='desc'
DECLARE #str varchar(1000)
SET #str='select identity (int) as autoid,
* into temp from cust1 order by TransactionType '+#dir
exec(#str)
select * from temp

T-SQL Paging Sorting & Filtering - Filtering not Working

T-SQL Paging Sorting & Filtering
I have been working on a T-SQL stored procedure for a number of hours now that will enable me to retrieve a paged set of articles that are sorted in ASC or DESC order based on a specified column.
I am now working on getting the stored procedure to filter based on the first character of the 'Title' field and have added the lines:
#StartAlpha nvarchar(1) = null
and
WHERE ((#StartAlpha IS NULL) OR (Title Like #StartAlpha + '%'))
see below.
The stored procedure no longer returns any results. And I don't really know why.
Can anyone please help?
Regards
Walter
USE [ABC]
GO
/****** Object: StoredProcedure [dbo].[Get_MyArticles_Paged] Script Date: 08/07/2011 20:41:28 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[Get_MyArticles_Paged]
/*Paging Total For Output*/
#Row_Count BIGINT OUT,
/*Paging Inputs*/
#Page_Size INT = 10,
#Page_Number INT = 1,
#Sort_Column VARCHAR(100), /* ('articleid','createdate','title','subject') */
#Sort_Direction VARCHAR(4), /* ('ASC','DESC') */
#StartAlpha nvarchar(1) = null
AS
BEGIN
print #StartAlpha
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
/*========================================================================
Declare local variables
========================================================================*/
DECLARE #FirstRecord int
DECLARE #LastRecord int
-- create a temporary space for paged result set
DECLARE #PagedResults AS TABLE (
[ArticleID] INT,
[CreateDate] SMALLDATETIME,
[Title] VARCHAR(200),
[Subject] VARCHAR(500),
[Row_Number] BIGINT,
[Row_Count] BIGINT
);
/*========================
Normalize Paging Parameters
==========================*/
--Fix invalid input for Page Size
SET #Page_Size = CASE
WHEN #Page_Size IS NULL THEN 10
WHEN #Page_Size < 1 THEN 10
ELSE #Page_Size
END;
--Fix invalid input for Page Number
SET #Page_Number = CASE
WHEN #Page_Number IS NULL THEN 1
WHEN #Page_Number < 1 THEN 1
ELSE #Page_Number
END;
--starting record to use.
SET #FirstRecord = ((#Page_Number - 1) * #Page_Size) + 1
--last record to use.
SET #LastRecord = #FirstRecord + #Page_Size - 1
--ensure sort column is valid in the list
SET #Sort_Column = CASE
WHEN LOWER(#Sort_Column) IN ('articleid','createdate','title','subject')
THEN LOWER(#Sort_Column)
ELSE
'title' --default
END
--ensure sort direction is ASC or DESC
SET #Sort_Direction = CASE
WHEN LEFT(UPPER(COALESCE(#Sort_Direction, '')) + ' ', 4) = 'DESC'
THEN 'DESC' --explicit descending
WHEN #Sort_Column = 'created' AND LEFT(UPPER(COALESCE(#Sort_Direction,'')) + ' ', 3) <> 'ASC' THEN
'DESC' --default for created date
ELSE 'ASC' --default otherwise
END;
/*============
Prepare Results
==============*/
WITH [MyTempArea] AS (
SELECT TOP (#LastRecord)
[ArticleID],
[CreateDate],
[Title],
[Subject],
ROW_NUMBER() OVER (
ORDER BY
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='articleid' THEN [articleid] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='createdate' THEN [createdate] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='title' THEN [title] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='subject' THEN [subject] END END ASC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='articleid' THEN [articleid] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='createdate' THEN [createdate] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='title' THEN [title] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='subject' THEN [subject] END END DESC
) AS [Row_Number],
COUNT(*) OVER () AS [Row_Count]
FROM Articles
WHERE ((#StartAlpha IS NULL) OR (Title Like #StartAlpha + '%'))
)
INSERT INTO #PagedResults
SELECT * FROM [MyTempArea] WHERE [Row_Number] >= #FirstRecord;
/*===========
Return Results
=============*/
-- #Row_Count output param
SELECT #Row_Count = COALESCE(MAX(Row_Count), 0) FROM #PagedResults;
-- Paged results set to return
SELECT [ArticleID],[CreateDate],[Title],[Subject]
FROM #PagedResults
ORDER BY [Row_Number];
END
Thanks to everyone that made helpful suggestions.
I completely refactored the stored procedure and it now works. See below.
I'm not entirely sure why the original Stored Procedure didn't work and why this version does, but I thought I would share with the forum.
Thanks again.
Walter.
ALTER PROCEDURE [dbo].[Account_ContactGetData]
#CurrentPage int = null,
#PageSize int = null,
#SortColumn nvarchar(max) = null,
#SortDirection varchar(5),
#StartAlpha nvarchar(1) = null
WITH EXECUTE AS CALLER
AS
BEGIN
SET NOCOUNT ON;
DECLARE #FirstRecord int;
DECLARE #LastRecord int;
--starting record to use.
SET #FirstRecord = ((#CurrentPage - 1) * #PageSize) + 1;
--last record to use.
SET #LastRecord = #FirstRecord + #PageSize - 1;
with ContactCTE as
(
SELECT [ContactID], [DisplayName], [FirstName], [MiddleName], [LastName],
(ROW_NUMBER() OVER (Order By
CASE WHEN #SortColumn='ContactID' AND #SortDirection='DESC' THEN ContactID END DESC,
CASE WHEN #SortColumn='ContactID' AND #SortDirection='ASC' THEN ContactID END ASC,
CASE WHEN #SortColumn='DisplayName' AND #SortDirection='DESC' THEN DisplayName END DESC,
CASE WHEN #SortColumn='DisplayName' AND #SortDirection='ASC' THEN DisplayName END ASC,
CASE WHEN #SortColumn='FirstName' AND #SortDirection='DESC' THEN FirstName END DESC,
CASE WHEN #SortColumn='FirstName' AND #SortDirection='ASC' THEN FirstName END ASC,
CASE WHEN #SortColumn='MiddleName' AND #SortDirection='DESC' THEN MiddleName END DESC,
CASE WHEN #SortColumn='MiddleName' AND #SortDirection='ASC' THEN MiddleName END ASC,
CASE WHEN #SortColumn='LastName' AND #SortDirection='DESC' THEN LastName END DESC,
CASE WHEN #SortColumn='LastName' AND #SortDirection='ASC' THEN LastName END ASC
)) AS Row
FROM Contact
WHERE
((#StartAlpha is NULL) OR (LastName Like #StartAlpha+ '%'))
)
SELECT [ContactID], [DisplayName], [FirstName], [MiddleName], [LastName]
FROM ContactCTE
WHERE Row BETWEEN #FirstRecord AND #LastRecord
END
Based on those requirements alone, this is what I would do:
WHERE ((#StartAlpha IS NULL) OR (LEFT(Title, 1) = #StartAlpha))
What do you get when you run just this part? (Please also state which values you are using in your parameters)
WITH [MyTempArea] AS (
SELECT TOP (#LastRecord)
[ArticleID],
[CreateDate],
[Title],
[Subject],
ROW_NUMBER() OVER (
ORDER BY
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='articleid' THEN [articleid] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='createdate' THEN [createdate] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='title' THEN [title] END END ASC,
CASE WHEN(#Sort_Direction = 'ASC') THEN CASE WHEN #Sort_Column='subject' THEN [subject] END END ASC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='articleid' THEN [articleid] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='createdate' THEN [createdate] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='title' THEN [title] END END DESC,
CASE WHEN(#Sort_Direction = 'DESC') THEN CASE WHEN #Sort_Column='subject' THEN [subject] END END DESC
) AS [Row_Number],
COUNT(*) OVER () AS [Row_Count]
FROM Articles
WHERE ((#StartAlpha IS NULL) OR (Title Like #StartAlpha + '%'))
)
SELECT * FROM [MyTempArea]
#Andreas LEFT(Title, 1) syntax would perform better than the like comparison... but using the like, this should work:
WHERE (Title Like isnull(#StartAlpha, '') + '%')
(The combination of working with nulls that OR makes me edgy.)