I am writing a CASE statement in my SQL Server Stored Procedure. There I am repeeating a same long SQL statements every time for 11 CASEs. Should I put the SQL Statement in CASE condition in a another Stored Procedure? What could be the best approach?
CASE (SELECT ..................)
THEN 'SELCET a.field'
ELSE
''SELECT vlaues'
END
as 'Coulmn1 '
CASE (SELECT ..................)
THEN 'SELCET vaues'
ELSE
''SELECT vlaues'
END
as 'Coulmn1 '
You might want to do something like
SELECT
CASE (your select statement which retuns one value)
WHEN 'option1' THEN 'value2return1'
WHEN 'option2' THEN 'value2return2'
WHEN 'option3' THEN 'value2return3'
...
ELSE 'defaultValue'
END
Use common table expressions link.
WITH CTE (ColA)
AS
(
Select ColA From Table
)
SELECT ColA
FROM CTE
Use a CTE. In the future it would help if you gave us a slightly better example of your code however.
WITH RepeateSelect AS (SELECT ..................)
.....
.....
CASE (SELECT * FROM RepeateSelect)
THEN 'SELCET a.field'
ELSE
'SELECT vlaues'
END
as 'Coulmn1 '
CASE (SELECT * FROM RepeateSelect)
THEN 'SELCET vaues'
ELSE
''SELECT vlaues'
END
as 'Coulmn1 '
Try using the repeated query once thusly:
select A.C1, X.C2, X.C3
from TableA as A inner join
( select B.AlmondJoy,
case when B.YN > 7 then 'Yes' else 'No' end as C2,
case when C.UD in ( -1, 1 ) then 'Up' else 'Down' end as C3
from TableB as B inner join
TableC as C on C.Id = B.Id
) as X on X.AlmondJoy = A.Zagnut
Related
I'm trying to perform an if statement that needs to be done within the From clause of my query. However when I try to do so, I get this error
Incorrect syntax near the keyword 'THEN'.
The query I'm trying to use is the following:
SELECT *
FROM
--a few tables with joins
IF (#a IS NULL OR #a <> '') THEN
--perform a few more joins
WHERE
--rest of query
Is it not possible to perform a case or if statement from the from clause?
After realising I can't use a IF Statement and Case would be more appropriate, I've read up and this can only be done dynamically and not from SQL itself.
You can't do this on a fundamental level. When you write a query, you already know what data it will return and what tables are needed to get that data.
Now, you can do some switchng between tables in a join by using outer joins and statements like ISNULL() and COALESCE() to see if the joined table actually has the data we're looking for.
The joins could loook like this:
declare #checkthis int
select #checkthis = (whatever, resulting in a 1 or a 0)
select *
from tbl_a as a
left outer join tbl_b as b -- tbl_b is optional if #checkthis is 1, else ignore it
on a.b_foreign_key = b.primary_key and #checkthis = 1
Depending on your joins, you can do something like this...
DECLARE #Join AS BIT
SET #Join = 1 --Performs inner join
SET #Join = 0 --ignores join
SELECT *
FROM Table1 a
LEFT JOIN Table2 b
ON a.Id = b.Id
WHERE
((#Join = 0) OR (#Join = 1 AND b.Id IS NOT NULL))
The IF statement in TSQL has the following syntax:
IF [Condition] --NO 'THEN' keyword needed
BEGIN
--myquery
END
ELSE IF [2nd Condition]
BEGIN
--myquery
END
ELSE
BEGIN
--myquery
END
[Condition] can be everything that gives you a TRUE output like
IF DAY(GETDATE()) = 7
BEGIN
PRINT 'IT IS TRUE'
END
ELSE
BEGIN
PRINT 'IT IS FALSE'
END
For your specific problem, you can use CASE statement, in a WHERE clause, like this:
SELECT *
FROM MYTABLE T
INNER JOIN MYTABLE2 T2 ON T2.ID = T1.ID
WHERE T.MYCOLLUMN = CASE
WHEN T.MYCOLUMN2 = 0 THEN 'FIRST'
WHEN T.MYCOLUMN2 = 1 THEN 'SECOND'
ELSE T2.MYCOLUMN
END
I have this piece of code (please look below). I keep getting error: "Invalid column name 'SuppFinish2'
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2],
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
FROM TABLE
Is it because of [SuppFinish2] being an alias? Thanks!
As you said its due to alias and aliased columns can be referenced only on order by to logical query flow order
with cte
as
(
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2]
FROM TABLE
)
select
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
from cte
You cant use those aliases in the same level as you created them, becuase they are not existing yet.. wrap your query with another select like this:
SELECT * ,
CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST]
FROM (
SELECT
[ID],
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2],
FROM TABLE)
In order to reference aliased columns, you can use a derived table (or CTE, but that is not shown here)
Select *, CASE
WHEN [RegFinish]<[SuppFinish2] THEN '1'
ELSE '0'
END AS [TEST] From
(
SELECT
CASE
WHEN [RegFinish] IS NULL THEN ''
ELSE [RegFinish]
END AS [RegFinish],
CASE
WHEN [SuppFinish] IS NULL THEN ''
ELSE [SuppFinish]
END AS [SuppFinish2]
) T1
FROM TABLE
You cannot, at the same time, set and access an alias in the SELECT clause. I would suggest rewriting your query using CROSS APPLY:
SELECT t1.[RegFinish],
t2.[SuppFinish],
CASE
WHEN t1.[RegFinish] < t2.[SuppFinish] THEN '1'
ELSE '0'
END AS [TEST]
FROM TABLE
CROSS APPLY (SELECT COALESCE([RegFinish], '') AS [RegFinish]) AS t1
CROSS APPLY (SELECT COALESCE([SuppFinish], '') AS [SuppFinish]) AS t2
SELECT ISNULL([RegFinish],'') as [RegFinish]
, ISNULL([SuppFinish],'') as [SuppFinish2], CASE
WHEN
ISNULL([RegFinish],'') < ISNULL([SuppFinish],'') THEN 1
ELSE 0
END AS [TEST]
FROM TABLE
Why not use ISNULL instead of CASE? The problem with your query is that [SuppFinish2] is an alias not an column and can only be used in ORDER BY clause
I am trying to MERGE values from one table to another. One of the values is a conditional value, but it looks like I am not getting the syntax correctly. Initially, I was using an IF-THEN-ELSE statement but was advise to use a CASE statement instead.
Here is the gist the syntax that is failing:
CREATE PROCEDURE EmployeeMerge
AS
BEGIN
SET NOCOUNT ON;
MERGE INTO Employee AS t1
USING
(SELECT
EmployeeName,
Zip,
UpdateDate
FROM table2) AS t2
ON (t1.EmployeeID = t2.EmployeeID)
WHEN MATCHED AND t2.UpdatedDate > t1.UpdatedDate THEN
UPDATE
SET
t1.EmployeeName = s.EmployeeName,
t1.Zip =
(CASE
WHEN t2.ZipExt IS NULL OR t2.ZipExt = '' THEN t2.Zip
ELSE (t2.Zip + '-' + t2.ZipExt)
END),
t1.UpdatedDate = t2.UpdateDate
WHEN NOT MATCHED THEN
INSERT (EmployeeName,
Zip,
ModDate)
VALUES
(t2.Name,
(CASE
WHEN t2.ZipExt IS NULL OR t2.ZipExt = '' THEN t2.Zip
ELSE (t2.Zip + '-' + t2.Zip_Ext)
END),
t2.UpdatedDate)
OUTPUT
deleted.*,
$action,
inserted.*
END; **-- A MERGE statement must be terminated by a semi-colon (;)**
GO
This MERGE statement works just fine if I do not implement the condition, i.e. simply set the t1.Zip = t2.Zip, but of course, this is avoiding the t2.ZipExt field.
A MERGE statement must be terminated by a semi-colon (;)
You haven't terminated the MERGE with a semicolon. You have terminated BEGIN-END. Move the semicolon.
I never really cared for the merge command. There are times where I can see using it, but for the most part, it's more complicated than I like my SQL.
UPDATE e
SET e.EmployeeName=t1.EmployeeName
, e.Zip=CASE
WHEN t1.ZipExt IS NULL OR t1.ZipExt = '' THEN t1.Zip
ELSE (t1.Zip + '-' + t1.ZipExt)
END
, e.UpdatedDate=t1.UpdatedDate
FROM Employee e
INNER JOIN Table t1 ON e.EmployeeID = t1.EmployeeID
WHERE t1.UpdatedDate > e.UpdatedDate
INSERT INTO Employee (EmployeeName,Zip,UpdatedDate)
SELECT
t1.EmployeeName
, t1.Zip=CASE
WHEN t1.ZipExt IS NULL OR t1.ZipExt = '' THEN t1.Zip
ELSE (t1.Zip + '-' + t1.ZipExt)
END
, t1.UpdatedDate
FROM Table t1
LEFT JOIN Employee e ON e.EmployeeID = t1.EmployeeID
WHERE e.EmployeeID IS NULL
I'm new to StackOverflow, and new to SQL Server, I'd like you to help me with some troublesome query.
This is my database structure(It's half spanish, hope doesn't matter)
Database
My problem is that I don't now how to make a query that states which team is local and which is visitor(using table TMatch, knowing that the stadium belongs to only one team)
This is as far as I can get
Select P.NroMatch, (select * from fnTeam (P.TeamA)) as TeamA,(select * from fnTeam (P.TeamB)) as TeamB,
(select * from fnEstadium (P.CodEstadium)) as Estadium, (cast(P.GolesTeamA as varchar)) + '-' + (cast(P.GolesTeamA as varchar)) as Score,
P.Fecha
from TMatch P
Using this functions:
If object_id ('fnTeam','fn')is not null
drop function fnTeam
go
create function fnTeam(#CodTeam varchar(5))
returns table
return(Select Name from TTeam where CodTeam = #CodTeam)
go
select * from fnTeam ('Eq001')
go
----****
If object_id ('fnEstadium','fn')is not null
drop function fnEstadium
go
create function fnEstadium(#CodEstadium varchar(5))
returns table
return(Select Name from TEstadium where CodEstadium = #CodEstadium)
go
I hope I'd explained myself well, and I thank you help in advance
EDIT:
Thanks for the help, this is what I've been looking for
Select P.NroMatch,
CASE
WHEN Ts.CodTeam= Ta.CodTeamTHEN Ta.Name
ELSE Tb.Name
END
As TeamLocal,
CASE
WHEN Ts.CodTeam<> Ta.CodTeamTHEN Ta.Name
ELSE Tb.Name
END
As TeamVisitante,
Ts.Name as Estadium,
(cast(P.GolesTeamA as varchar)) + '-' + (cast(P.GolesTeamB as varchar)) as Score,
P.Fecha
from
TMatch P
join TTeamTa ON Ta.CodTeam= P.TeamA
join TTeamTb ON Tb.CodTeam= P.TeamB
join TEstadium Ts ON Ts.CodEstadium = P.CodEstadium
You do not need to use 'lookup' functions for this (and shouldn't), joins are a better approach:
Select
P.NroMatch,
Ta.Name as TeamA,
Tb.Name as TeamB,
Ts.Name as Estadium,
cast(P.GolesTeamA as varchar)) + '-' + (cast(P.GolesTeamA as varchar) as Score,
P.Fecha,
CASE
WHEN Ts.CodTeam = Ta.Name THEN Ta.Name
ELSE Tb.Name
END As HomeTeam,
CASE
WHEN Ts.CodTeam <> Ta.Name THEN Ta.Name
ELSE Tb.Name
END As VistorTeam
from
TMatch P
join TTeam Ta ON Ta.CodTeam = P.TeamA
join TTeam Tb ON Tb.CodTeam = P.TeamB
join TEstadium Ts ON Ts.CodEstadium = P.CodEstadium
If you are new to SQL, it might be useful searching SO for some resources such as these:
SQL Tutorial
SQL Tutorial
I have an assignment table in my database. I also have a assignment_notes table, which has a reference to the assignment table. There can exists multiple rows in this table.
When I select all my assignments, I want to check if there exists some notes to this assignment. And all I want is a true/false return.
Is it possible to do something like (pseudo):
Select all assignments; if assignment
has assignment_notes HasNotes = true; else
HasNotes = false.
I hope I made this clear enough - I'm not so good at explaining programming stuff ;-)
DECLARE #Assignments TABLE
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
Name VARCHAR(30) NOT NULL
)
DECLARE #AssignmentNotes TABLE
(
Id INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AssignmentId INT NOT NULL,
Note VARCHAR(MAX)
)
INSERT INTO #Assignments(Name) VALUES('Biology')
INSERT INTO #Assignments(Name) VALUES('Chemistry')
INSERT INTO #AssignmentNotes (AssignmentId, Note) VALUES(1, 'Studies on DNA')
INSERT INTO #AssignmentNotes (AssignmentId, Note) VALUES(1, 'Evolution notes from Darwin')
SELECT
A.*,
CASE WHEN COUNT(AN.Id) > 0 THEN 1 ELSE 0 END AS HasNotes
FROM
#Assignments AS A
LEFT JOIN
#AssignmentNotes AS AN
ON A.Id = AN.AssignmentId
GROUP BY
A.Id,
A.Name
Don't have SQL Server ready to test, but a query like this should work:
SELECT A.*,
CAST(
CASE (SELECT TOP 1 AssignmentNotes_ID
FROM AssignmentNotes AN
WHERE AN.AssignmentID = A.AssignmentID)
WHEN NULL THEN 0 ELSE 1 END
AS BIT) AS HasNotes
FROM Assignments A
SELECT a.*,
(SELECT COUNT(*)
FROM assignment_notes an
WHERE an.assignmentid = a.id) as NumNotes
FROM Assignment a
That will give you the number of notes with that assignment.
You can translate your pseudo code to SQL if you use the case statement. On MSDN: http://msdn.microsoft.com/en-us/library/ms181765.aspx
And another article just in case: http://www.devx.com/tips/Tip/15633
This approach means that you don't need a huge GROUP BY statement as a result of returning lots of Assignment fields.
SELECT Assignment.*,
CAST(CASE WHEN NotesQty>0 THEN 1 ELSE 0 END as bit) AS HasNotes
FROM Assignment
LEFT JOIN
(SELECT AssignmentId,COUNT(*) AS NotesQty
FROM assignment_notes
GROUP BY AssignmentId) as Assignment_NotesQty
ON Assignment_NotesQty.AssignmentId=Assignment.AssignmentId