This question already has answers here:
Dynamic Sorting within SQL Stored Procedures
(15 answers)
Closed 5 years ago.
I have a requirement to sort the results dynamically based on the column selection. I know that only first query below works and 2nd one fails. But am unable to understand why it fails, as per my understanding based on #SortDirection value it should give ASC or DESC, which will get appended to the earlier CASE which is returning column name. Can you please explain why it fails?
create table EmpData
(
EmpID int identity,
FName varchar(20),
LName varchar(20),
Email varchar(30),
City varchar(20),
DOB date
)
GO
INSERT INTO EmpData values ('Mark','Smith','Mark.s#email.com','London','02-Jun-1980')
INSERT INTO EmpData values ('Mark','Marsh','Mark.m#email.com','Paris','02-Jul-1981')
INSERT INTO EmpData values ('Steve','Elgar','Steve.e#email.com','Canada','12-Jun-1980')
INSERT INTO EmpData values ('Michael','Jones','Michael.j#email.com','France','22-Jan-1980')
GO
----------QUERY 1--------
DECLARE #SortByColumn varchar(20)='City',
#SortDirection varchar(5)='ASC'
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
ORDER BY
CASE #SortDirection WHEN 'ASC' THEN
CASE #SortByColumn
WHEN 'FirstName' THEN FName
WHEN 'LastName' THEN LName
WHEN 'Email' THEN Email
WHEN 'City' THEN City
ELSE ''
END
END,
CASE #SortDirection WHEN 'DESC' THEN
CASE #SortByColumn
WHEN 'FirstName' THEN FName
WHEN 'LastName' THEN LName
WHEN 'Email' THEN Email
WHEN 'City' THEN City
ELSE ''
END
END DESC
GO
----------QUERY 2--------
DECLARE #SortByColumn varchar(20)='City',
#SortDirection varchar(5)='ASC'
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
ORDER BY
CASE #SortByColumn
WHEN 'FirstName' THEN FName
WHEN 'LastName' THEN LName
WHEN 'Email' THEN Email
WHEN 'City' THEN City
ELSE ''
END
CASE #SortDirection
WHEN 'DESC' THEN DESC
ELSE ASC
END
Try like this
DECLARE #SortByColumn varchar(20)='City',
#SortDirection varchar(5)='asc'
;WITH CTE
AS
(
SELECT
Seq1 = ROW_NUMBER() OVER(ORDER BY
CASE #SortByColumn
WHEN 'FirstName' THEN FName
WHEN 'LastName' THEN LName
WHEN 'Email' THEN Email
WHEN 'City' THEN City
ELSE ''
END ASC),
Seq2 = ROW_NUMBER() OVER(ORDER BY
CASE #SortByColumn
WHEN 'FirstName' THEN FName
WHEN 'LastName' THEN LName
WHEN 'Email' THEN Email
WHEN 'City' THEN City
ELSE ''
END DESC),
EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as 'Date-Of-Birth'
FROM EmpData
)
SELECT
*
FROM CTE
ORDER BY CASE #SortDirection WHEN 'DESC' THEN Seq2 ELSE Seq1 END
DEMO
It is better to use dynamic SQL in such cases
Declare #sql nvarchar(max)
declare #orderby nvarchar(100) = ' ORDER BY '
DECLARE #SortByColumn varchar(20) = 'City'
declare #SortDirection varchar(5) = 'ASC'
set #sql = '
SELECT EmpID,FName AS FirstName, LName AS LastName, Email, City, DOB as ''Date-Of-Birth''
FROM EmpData
' +
CASE #SortByColumn
WHEN 'FirstName' THEN #orderby + ' FName ' + #SortDirection
WHEN 'LastName' THEN #orderby + ' LName ' + #SortDirection
WHEN 'Email' THEN #orderby + ' Email ' + #SortDirection
WHEN 'City' THEN #orderby + ' City ' + #SortDirection
ELSE ''
END
exec sp_executesql #sql
Since ASC or DESC is SQL clauses, we can not use them in CASE statements
Related
Can somebody refresh my memory on how to build a query for this.
I want to use a list of several names (first and last), to update their rows in the table with same information. for example:
if I have a table set up with the columns:
[first_name],[last_name],[dob],[married_status]
I want to find:
(bob, smith),
(robert, john),
(jane, doe);
and edit their field for [married_status] to 'm'.
how do I structure this search and replace?
Thanks!
Use the IN operator:
UPDATE myTable
SET married_status = 'm'
WHERE (first_name, last_name) IN (
('bob' , 'smith'),
('robert', 'john'),
('jane' , 'doe'))
Code:
UPDATE tablename
SET married_status = 'm'
WHERE
( first_name = 'bob' AND last_name = 'smith' )
OR
( first_name = 'robert' AND last_name = 'john' )
OR
( first_name = 'jane' AND last_name = 'doe' )
You would use UPDATE query:
UPDATE `table`
SET `married_status` = 'm'
WHERE
(`first_name` = 'bob' AND `last_name` = 'smith')
OR (`first_name` = 'robert' AND `last_name` = 'john')
OR (`first_name` = 'jane' AND `last_name` = 'doe')
I've written the following sql statement, but I'm unsure how to write the where statement because it is conditional. So I have:
declare #subject varchar(100)
select surname, forename, result
from student
join subject on subject.upn = student.upn
where...
what I then want to write as sql is:
where
if subject = 'English' then subject=#subject and KS2en=''
or if subject = 'Maths' then subject = #subject and KS2ma = ''
or if subject <> 'Maths' and <> 'English' then subject = #subject and KS2av = ''
I assume this can be done logically or maybe using case, but I'm at a bit of a loss at the moment.
Here are the tables:
Student
UPN | Surname | Forename | KS2en | KS2Ma | KS2av
Subject
UPN | Subject
All are varchar.
Something like the following would do it.
SELECT surname,
forename,
result
FROM student
JOIN subject
ON subject.upn = student.upn
WHERE subject.subject = #subject
AND '' = CASE #subject
WHEN 'English' THEN KS2en
WHEN 'Maths' THEN KS2ma
ELSE KS2av
END
I am assuming subject is not nullable. If it is the above query has slightly different semantics than your pseudo code.
Where restricts the number of rows returned, you want to return a different column value according to your condition.
So instead of using Where you have to include the condition into the select via CASE:
DECLARE #subject VARCHAR(100)
SELECT surname,
forename,
subject=#subject,
KS2en=CASE
WHEN subject = 'Engish' THEN ''
ELSE ks2en
END,
KS2ma=CASE
WHEN subject = 'Maths' THEN ''
ELSE ks2ma
END,
KS2av=CASE
WHEN subject NOT IN( 'Maths', 'English' ) THEN ''
ELSE ks2av
END
FROM student
JOIN subject
ON subject.upn = student.upn
I have a table student that contains :
student_id , prefered_cell , cell_1 , cell_2 , cell_3
now under prefered cell values we have (cell_1,cell2,cell3)
what is the best way to get the value of the prefered cell in mysql ?
those are the available rows :
1 , 'cell_1' , '123-321-1231' , '431-2133-321' , '123-123-4111'
2 , 'cell_2' , '122-333-3333' , '455-123-123' , '123-421-2345'
so i want to have the preferred number for student 1 and 2 :
will get :
1 , '123-321-1231'
2 , '455-123-123'
Try this Query.
Select student_id, case when prefered_cell = 'cell_1' then cell_1
when prefered_cell = 'cell_2' then cell_2
when prefered_cell = 'cell_3' then cell_3
else '0'
End as cell_value from student
we have switch in sql.You can use that
select student_id ,case from table_name
CASE prefered_cell
WHEN 'cell_1' THEN 'value is cell_1 '
WHEN 'cell_2' THEN 'value is cell_2'
WHEN 'cell_3'= 'cell_3' then cell_3
END
else '0'
End from student
I am using CASE Statement in Stored procedure. I am using like
create proc USP_new
(
#searchtype varchar(30),
#stateName char(2),
#keywords varchar(300),
#locations varchar(100),
#searchBy varchar(20),
#keywordOption varchar(5),
#jobType char(4),
#startDate varchar(20),
#endDate varchar(20),
#companyID int
)
as begin
declare #mainQuery varchar(8000)
SELECT #mainQuery = 'SELECT JobID, JobTitle, CompanyInfo, JobSummaryLong, ModifiedDate
FROM Jobs
WHERE IsActive = 1 '
IF #startDate = '' BEGIN
SELECT #mainQuery = #mainQuery + 'And ModifiedDate >= ''' + #startDate + ' 00:00:00'' '
END
SELECT #mainQuery = #mainQuery + 'And ModifiedDate <= ''' + #endDate + ' 23:59:59'''
SELECT
CASE #mainQuery
WHEN 'state' THEN 'ONE'
WHEN 'keyword' THEN 'Second'
WHEN 'company' THEN 'Third'
ELSE 'Other'
END
I want check more condition on this 'Keyword' like When Keyword and keyword is not null then
goto THEN condition..
I used like WHEN 'keyword' AND (#keyword IS NULL) THEN '' but its is giving syntax error.
IT is possible to check condition like this or any other way to check this
Thanks....
It's really hard to tell what you are trying to accomplish with this stored proc, but I think you are definitely making thing harder than they need to be. You could probably re-write this as a single query like so:
SELECT
KeywordResult = CASE
WHEN #keywords = 'state' THEN 'ONE'
WHEN #keywords = 'keyword' THEN 'Second'
WHEN #keywords = 'company' THEN 'Third'
ELSE 'Other' END,
JobID,
JobTitle,
CompanyInfo,
JobSummaryLong,
ModifiedDate
FROM
Jobs
WHERE
IsActive = 1
AND (#StartDate <> '' AND ModifiedDate >= #StartDate)
AND ModifiedDate <= #endDate + ' 23:59:59'''
I got a stored procedure that delivers a table of students, and it needs to order by surname, name etc... it also needs to sort ascending, descending, depending on the parameter #orderby...
code:
ORDER BY
CASE
WHEN #orderby = 'studentkey' THEN Studentkey END ASC,
CASE
WHEN #orderby = 'studentkey' and #desc = 1 THEN Studentkey END DESC,
CASE
WHEN #orderby = 'initials' THEN Initials END ASC,
CASE
WHEN #orderby = 'initials' and #desc = 1 THEN Initials END DESC,
CASE
WHEN #orderby = 'firstname' THEN Firstname END ASC,
CASE
WHEN #orderby = 'firstname' and #desc = 1 THEN Firstname END DESC,
CASE
WHEN #orderby = 'nickname' THEN Nickname END ASC,
CASE
WHEN #orderby = 'nickname' and #desc = 1 THEN Nickname END DESC,
CASE
WHEN #orderby = 'insertion' THEN Insertion END ASC,
CASE
WHEN #orderby = 'insertion' and #desc = 1 THEN Insertion END DESC,
CASE
WHEN #orderby = 'surname' THEN Surname END ASC,
CASE
WHEN #orderby = 'surname' and #desc = 1 THEN Surname END DESC
NED
There is a difference in output between #desc = 1 and #desc = 0, but not what i desire...
Does anyone have a solution?
Try this:
CASE
WHEN #orderby = 'studentkey' and #desc = 0 THEN Studentkey END ASC,
CASE
WHEN #orderby = 'studentkey' and #desc = 1 THEN Studentkey END DESC,
...