Doing an Update in SQL, with a CASE WHEN Statement - sql-server-2008

What I want to know, is it somehow possible to do an update to a table, in a Case statement? Or if there is Some way to do this? I have a button to pull a report (this button goes and calls a stored procedure, and it gets a list of columns and their residing columns).
I basically want to update the table, IF, and only IF, the DateClosed column is NULL AND ClosedBy is null (i.e., the end date was reached, so the campaign is CLOSED).
The way I usually determine if the campaign is closed, is by doing Checks on the start and end date. Ie When EndDate < GetDate() Then "Closed". So obviously that displays correctly, but my database displays null because there was no update.
This is my stored procedure:
ALTER PROCEDURE [dbo].[sp_CampaignStats]
#from DATETIME,
#to DATETIME
AS
SELECT
CampaignName AS 'CAMPAIGN NAME',
CampaignDescription AS 'CAMPAIGN DESCRIPTION',
CASE
WHEN EndDate >= GETDATE() AND StartDate <= GETDATE() THEN 'Active'
WHEN StartDate >= GETDATE() THEN 'Pending'
WHEN CampaignStatus = 4 THEN 'Archived'
ELSE 'Closed'
END as 'CurrentStatus',
CONVERT(VARCHAR(11), StartDate, 106) + ' - ' + CONVERT(VARCHAR(11), EndDate, 106) AS 'CAMPAIGN DATES',
Discount AS 'DISCOUNT',
[Target] AS 'TARGET',
Uptake AS 'UPTAKE',
tc.DateAdded as 'DATE ADDED',
U.FirstName + ' ' + u.LastName As 'ADDED BY',
CASE
WHEN CloseBy IS NULL AND EndDate < GETDATE() AND CloseBy = Null THEN 'System'
WHEN CampaignStatus = 4 THEN 'Archived'
WHEN CloseBy IS not Null THEN UU.FirstName + ' ' + uu.LastName
ELSE 'Not Closed'
END AS 'CLOSED BY',
DateClosed AS 'DATE CLOSED'
FROM
Tbl_Campaign tc
LEFT JOIN
tbl_User U ON Tc.AddedBy = U.UserId
LEFT JOIN
Tbl_User UU ON TC.CloseBy = UU.UserId
WHERE
(startDate >= #from OR enddate <= #to)
AND CampaignStatus IN (1, 2, 3, 4)

So you want to update your table before the SELECT happens?
Try something like this:
UPDATE dbo.Tbl_Campaign
SET -- what do you want to update to what value here????
WHERE
DateClosed IS NULL
AND ClosedBy IS NULL
Or what exactly are you trying to do?? You're still being rather unclear and vague in your question - you're not mentioning WHAT column in WHICH table you want to update to WHAT value if that condition is met.....

SQL only allows one operation per statement. SELECTs only read data, UPDATEs only write data.
If I've understood your problem though, you've got a NULL in an end date field that's preventing you from displaying your button correctly? If that's the case, you could do something like
SELECT
StatusDate =
CASE WHEN EndDate < GETDATE() THEN 'Closed'
WHEN EndDate > GETDATE() THEN 'Open'
WHEN EndDate IS NULL THEN 'End Date not set'
END
FROM
SourceTable
Or, if it was easier in your code, wrap the CASE in an ISNULL or COALESCE function that can be used to fill in the default value.
None of these will update the table on the read, but they'll all stop the NULL from preventing your read returning anything at all.
Seeing your actual code now, what you want is something like this -
ALTER PROCEDURE [dbo].[usp_CampaignStats]
#from DATETIME,
#to DATETIME
AS
SET NOCOUNT ON;
--Make sure any NULLs we need to have been cleaned up
UPDATE Tbl_Campaign
SET <Fields>
WHERE DateClosed IS NULL AND ClosedBy IS NULL
AND (startDate >= #from OR enddate <= #to)
AND CampaignStatus IN (1, 2, 3, 4);
--Now return the data
SELECT
CampaignName AS 'CAMPAIGN NAME',
CampaignDescription AS 'CAMPAIGN DESCRIPTION',
CASE
WHEN EndDate >= GETDATE() AND StartDate <= GETDATE() THEN 'Active'
WHEN StartDate >= GETDATE() THEN 'Pending'
WHEN CampaignStatus = 4 THEN 'Archived'
ELSE 'Closed'
END as 'CurrentStatus',
CONVERT(VARCHAR(11), StartDate, 106) + ' - ' + CONVERT(VARCHAR(11), EndDate, 106) AS 'CAMPAIGN DATES',
Discount AS 'DISCOUNT',
[Target] AS 'TARGET',
Uptake AS 'UPTAKE',
tc.DateAdded as 'DATE ADDED',
U.FirstName + ' ' + u.LastName As 'ADDED BY',
CASE
WHEN CloseBy IS NULL AND EndDate < GETDATE() AND CloseBy = Null THEN 'System'
WHEN CampaignStatus = 4 THEN 'Archived'
WHEN CloseBy IS not Null THEN UU.FirstName + ' ' + uu.LastName
ELSE 'Not Closed'
END AS 'CLOSED BY',
DateClosed AS 'DATE CLOSED'
FROM
Tbl_Campaign tc
LEFT JOIN
tbl_User U ON Tc.AddedBy = U.UserId
LEFT JOIN
Tbl_User UU ON TC.CloseBy = UU.UserId
WHERE
(startDate >= #from OR enddate <= #to)
AND CampaignStatus IN (1, 2, 3, 4);

Related

What is wrong is this mysql statement with case?

SELECT COUNT(*)
FROM PATIENTS A, RECALLS_AFTER_RESERV C
LEFT JOIN PATIENT_LAST_RESERV D
ON D.PATIENT_ID = C.PATIENT_ID
WHERE C.PATIENT_ID = A.ID
AND C.OFFICE_ID = A.OFFICE_ID
AND C.OFFICE_ID = ?
AND YEAR(CONVERT_TZ(C.RECALLS_AT, 'UTC', 'Asia/Tokyo')) = ?
AND (CASE
WHEN ISNULL(D.STARTS_AT) THEN
A.CHECKED_IN_AT
ELSE
D.STARTS_AT
END) >= CONVERT_TZ('2015-01-27 00:00:00', 'Asia/Tokyo', 'UTC')) AND (CASE
WHEN ISNULL(D.STARTS_AT) THEN
A.CHECKED_IN_AT
ELSE
D.STARTS_AT
END) <= CONVERT_TZ('2015-01-27 23:59:59', 'Asia/Tokyo', 'UTC') AND C.RECALLED_AT IS NULL AND C.STARTS_AT IS NULL
I want to use the case to determine whether the D.starts_at have value,if not, I use A.checked_in_at to replace the D.starts_at.but it gives an error
(case when isnull(D.starts_at) then A.checked_in_at else D.starts_at end) >= CONVERT_TZ('2015-01-27 00:00:00', 'Asia/Tokyo', 'UTC') )
I finally find the problem, the case statement is right. the problem is the redundant ) in the above.

Struggling to get desired return

I'm relatively new to SQL, but am generally a quick learner and this particular query has stumped me for a few days. Any help would be beyond appreciated at this point.
When I run the below query, I only return rows where there exists a statusdatetime (the agent logged in that day). I need to return a row even when the agent didn't log in but was scheduled. How can I change this query to return a NULL for that. I thought the left join would work.
DECLARE #startDate datetime
DECLARE #endDate datetime
SET #startDate = GETDATE()
SET #endDate = GETDATE()
SET #startDate = CONVERT(DATETIME, CONVERT(varchar(11),#startDate, 111 ) + ' 00:00:00', 111)
SET #endDate = CONVERT(DATETIME, CONVERT(varchar(11),#endDate, 111 ) + ' 23:59:59', 111)
Begin
Create table #boris5table(
Firstname varchar(50),
lastname varchar (50),
username varchar (50),
starttime datetime,
loggedintime datetime,
variation int)
End
Insert into #boris5table (Firstname, lastname, username, starttime, loggedintime, variation)
Select firstname, lastname, userid,
(cast(DATEADD(MINUTE, (-300 +
(select min(startoffset) from [dbo].[IO_ScheduleInterval]
Where activitytypeid = '0000000000000000000004'
and PaidTime = '1'
and f1.agentid = f2.agentid
and ScheduleID = f1.scheduleid)), StartDateTimeUTC) as datetime)),
case when exists (select count(*), statusdatetime from [dbo].[AgentActivityLog] Where StatusDateTime between #startdate and #enddate Group by StatusDateTime) then min(statusdatetime)
Else NULL
End as LoggedInTime,
DATEDIFF(minute, (cast(DATEADD(MINUTE, (-300 +
(select min(startoffset) from [dbo].[IO_ScheduleInterval]
Where activitytypeid = '0000000000000000000004'
and PaidTime = '1'
and f1.agentid = f2.agentid
and ScheduleID = f1.scheduleid)), StartDateTimeUTC) as datetime)),
case when exists (select statusdatetime from [dbo].[AgentActivityLog] Where StatusDateTime between #startdate and #enddate and f3.UserId = f2.UserName) then min(statusdatetime)
Else 'NULL' END)
as 'Variation (minutes)'
From [I3_IC].[dbo].[IO_Schedule] as f1
left join [dbo].[IO_Agent] as f2 on f1.AgentID = f2.AgentID and (CAST(DATEADD(hour, - 5, f1.StartDateTimeUTC) as date)) between #startdate and #enddate
left join [dbo].[Individual] as f4 on f2.UserName = f4.WebLogin and LastName <> '-'
left join [dbo].[AgentActivityLog] as f3 on f2.UserName = f3.UserId and (CAST(DATEADD(hour, -1, f3.StatusDateTime) as date)) between #startdate and #enddate
Group by firstname, lastname, f2.UserName, ScheduleID, f1.AgentID, f2.AgentID, StartDateTimeUTC, f3.UserId
Select *
From #boris5table
drop table #boris5table

Migrating a PostgreSQL stored proc to MYSQL

I have the following PostgreSQL which I want to re-write to make it compatible for MySQL stored function.
CREATE OR REPLACE FUNCTION test.yearly_demand_function(IN paramstartdate date,
OUT network character varying,
OUT season_number integer,
OUT week_trans numeric,
OUT month_trans numeric,
OUT year_trans numeric )
RETURNS SETOF record AS
$BODY$
BEGIN
RETURN QUERY
(select qq.network::varchar,
qq.season_number,
qq.week_trans::numeric,
qq.month_trans::numeric,
qq.year_trans::numeric
from
(
SELECT coalesce(nullif(mpf.studio,''),fi.name) AS network,
coalesce(mpf.season_number, mpf.reported_season_number) AS season_number ,
sum(case when activity_date >= date_trunc('week', paramStartDate::timestamp) - interval '7 day' and activity_date <= paramStartDate then mpf.units_sold else 0 END) as week_trans,
sum(case when activity_date >= date_trunc('month', paramStartDate::timestamp) and activity_date <= paramStartDate then mpf.units_sold else 0 END) as month_trans,
sum(case when activity_date >= date_trunc('year', paramStartDate::timestamp) and activity_date <= paramStartDate then mpf.units_sold else 0 END) as year_trans
FROM customer.dim_product_view mpf
left join customer.feed_indicator fi on mpf.series_name = fi.indicator_value
and mpf.series_name = fi.indicator_value
left join
(
select p.series_name,p.season_number,count(*) as episode_count
from product p
where source in ('Amway','FifthThird')
and p.episode_number is not null
group by 1,2) as pec on mpf.series_name = pec.series_name
and mpf.season_number = pec.season_number
WHERE mpf.activity_date BETWEEN date_trunc('year', paramStartDate::timestamp) AND paramStartDate
AND 1=1
AND ( mpf.demographic is null or '' not in ( '' ) or ('' in ( '' ) and mpf.demographic = 'Persons') )
AND mpf.customer_product_id not ilike '%unallocated%'
GROUP BY 1,2,3,7,34,35,36
)qq
);
end;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100
ROWS 1000;
ALTER FUNCTION yearly_demand_function(date);
Now Im not sure how to write the RETURNS SETOF record AS from above PostgreSQL (RETURN QUERY part) for MYSQL
Although I have started writing the stored proc for MY SQL as below
-- DROP FUNCTION IF EXISTS looptest;
DELIMITER $$
CREATE FUNCTION test.yearly_demand_function( IN paramstartdate date,
OUT network varchar(256),
OUT season_number integer,
OUT week_value numeric,
OUT month_value numeric,
OUT year_value numeric
) RETURNS <What to Write >
LANGUAGE SQL
BEGIN
RETURN QUERY
(select qq.network::varchar,
qq.season_number,
qq.week_value::numeric,
qq.month_value::numeric,
qq.year_value::numeric
from
(
SELECT coalesce(nullif(mm.studio,''),fi.name) AS network,
coalesce(mm.season_number, mm.reported_season_number) AS season_number ,
sum(case when final_date >= date_trunc('week', paramStartDate::timestamp) - interval '7 day' and final_date <= paramStartDate then mm.units_sold else 0 END) as week_value,
sum(case when final_date >= date_trunc('month', paramStartDate::timestamp) and final_date <= paramStartDate then mm.units_sold else 0 END) as month_value,
sum(case when final_date >= date_trunc('year', paramStartDate::timestamp) and final_date <= paramStartDate then mm.units_sold else 0 END) as year_value
FROM customer.product_view mm
left join customer.f_indicator fi on mm.series_name = fi.indicator_value
and mm.series_name = fi.indicator_value
left join
(
select p.name,p.s_number,count(*) as episode_count
from product p
where source in ('Amway','FifthThird')
and p.e_number is not null
group by 1,2) as tt on mm.series_name = tt.series_name
and mm.season_number = tt.season_number
WHERE mm.final_date BETWEEN date_trunc('year', paramStartDate::timestamp) AND paramStartDate
AND 1=1
AND ( mm.demographic is null or '' not in ( '' ) or ('' in ( '' ) and mm.demographic = 'Persons') )
AND mm.customer_product_id not ilike '%unallocated%'
GROUP BY 1,2,3,7,34,35,36
)qq
);
END;
$$
DELIMITER
how to write the RETURNS SETOF record AS from above PostgreSQL (RETURN QUERY part) for MYSQL
Instead of CREATE FUNCTION use the CREATE PROCEDURE syntax. You can then write a normal SELECT statement inside that block. To execute the stored procedure you created use the CALL syntax (i.e. CALL test.yearly_demand_function('2013-01-01')). You also don't need to specify your 5 OUT parameters. The value of the 5 OUT parameters will just correspond to the 5 columns that you will specify in your SELECT statement.

CASE Statement in SQL WHERE clause

I'm trying to fetch data from table where I'm using a CASE condition in the WHERE clause and currently I'm using following query:-
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND (
STATUS = 'Sold'
OR STATUS = 'In Stock'
OR STATUS = 'Ref'
)
AND CASE WHEN (
STATUS = 'Sold'
)
THEN delivery_date >= '2012-08-01'
END
But it returns 0 for total and NULL for purchase.
From your comment.
I want to use Case Statement, could u pls clarify me about case statament in where clause
You can use CASE statement in WHERE like this:
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND ( STATUS = 'Sold'
OR STATUS = 'In Stock'
OR STATUS = 'Ref')
AND CASE STATUS
WHEN 'Sold'
THEN delivery_date >= '2012-08-01'
ELSE 1=1
END
Here you need to use ELSE 1=1. otherwise you will not get desired result. For more explanation see this SQLFiddle
I don't think that CASE can work that way. What you want is a slightly more complex expression as your WHERE clause. Probably something like this:
SELECT count(enq_id) AS total, sum(purchase_amount) AS purchase
FROM temp_stock
WHERE purchase_date <> '0000-00-00'
AND purchase_date < '2012-08-01'
AND (
(STATUS = 'Sold' AND delivery_date >= '2012-08-01')
OR STATUS = 'In Stock'
OR STATUS = 'Ref'
)

How to Check IF condition in Case statement of Stored procedure

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'''