Mysql if Null or Empty String then Show N/A - mysql

Hello I'm new to mysqsl and I'm trying to display N/A if the return data is empty or NULL but my query is unrecognized statement type. What do you think is wrong with my query? wrong placement of code?
CASE when 'Earliest Time Opened' = '' or 'Earliest Time Opened' is 'Null'
then 'N/A'
ELSE
SELECT (date_format(d.date_opened, '%r') as 'Earliest Time Opened'
FROM daily_report d JOIN userinfo ui
ON d.userid= ui.id
WHERE d.date_opened >= date_sub(curdate(), interval 0 day)
AND d.survey_at_what_blh = 'Bagong Silang' AND ui.status='Employee'
ORDER BY d.date_opened DESC
limit 1
END

Use IF with ISNULL here:
SELECT IF(ISNULL(d.date_opened), 'N/A', DATE_FORMAT(d.date_opened, '%r')) AS `Earliest Time Opened`
FROM daily_report d
INNER JOIN userinfo ui ON d.userid = ui.id
WHERE
d.date_opened >= CURDATE() AND
d.survey_at_what_blh = 'Bagong Silang' AND
ui.status = 'Employee'
ORDER BY
d.date_opened DESC
LIMIT 1;
If you really wanted to use a CASE expression, then it would need to appear inside the select clause, something like this:
SELECT CASE WHEN DATE_FORMAT(d.date_opened, '%r') IS NOT NULL
THEN DATE_FORMAT(d.date_opened, '%r')
ELSE 'N/A' END AS `Earliest Time Opened`
But COALESCE is much more terse and appropriate here.

Related

selecting multiple fields using in where clause

I have a MySQL query and this is used to bring up certain events. The event_type and etype will change depending on what someone chooses in the form.
Below is what is added to the query based on a form on the webpage.
and event_type = '54' and etype = 'SP'
the full query is
select tevent.event_name, tevent.event_type, min(e_dates.event_date) as eventdate,
tevent.status, tevent.etype
from (tevent LEFT JOIN event_dates on tevent.eventid=event_dates.eventid)
Where status <> 'delete'
AND YEAR(e_dates.event_date) >= YEAR( CURDATE( ) ) and event_type = '54' and etype = 'SP')
group by tevent.eventid
order by (case when tevent.status = 'closed' and e_dates.event_date >= curdate() then 0 else 1 end),
(case when find_in_set(`status`, 'open,pending,approved') then 0 else 1 end),
e_dates.event_date asc, tevent.eventid ASC
This works perfectly for what I need. I shows all the events that are a certain event types and event category.
However, I want ALL queries to include the following statement
((event_type = '54' and etype = 'SM') or (event_type = '50' and
event_prelim = '2'))
the above statement will add the seminars to all event calendars, but will also show each particular event type based on what the person chooses.
I suppose your WHERE clause could look like this
WHERE status <> 'delete'
AND YEAR(e_dates.event_date) >= YEAR(CURDATE())
AND (
event_type NOT IN ('50','54')
OR event_type IS NULL
OR (event_type = '54' AND etype IN ('SP','SM'))
OR (event_type = '50' AND event_prelim = '2')
)
AND's are evaluated before the OR's.
So when using both AND's and OR's in the criteria, putting the parentheses does matter.

'?' Parameters not Filtering Data in SSRS (MySQL ODBC)

I have a report in SSRS that displays no results when a '?' parameter is specified. If I replace the '?' parameter with a string, it returns the desired results. I'm using a ODBC connection with a MySQL server. I have another report in the same project with a working '?' parameter.
Non-working SQL:
SELECT
*
FROM
(
SELECT
firstname
,lastname
,CASE
WHEN LENGTH(mdl_user.idnumber) = '1' THEN CONCAT('00000', mdl_user.idnumber)
WHEN LENGTH(mdl_user.idnumber) = '2' THEN CONCAT('0000', mdl_user.idnumber)
WHEN LENGTH(mdl_user.idnumber) = '3' THEN CONCAT('000', mdl_user.idnumber)
WHEN LENGTH(mdl_user.idnumber) = '4' THEN CONCAT('00', mdl_user.idnumber)
WHEN LENGTH(mdl_user.idnumber) = '5' THEN CONCAT('0', mdl_user.idnumber)
ELSE mdl_user.idnumber
END AS KUserID
,from_unixtime(GH.timemodified,'%Y-%m-%d %H:%i:%s') AS DateTaken
,YEAR(from_unixtime(GH.timemodified,'%Y-%m-%d %H:%i:%s')) AS YearDateTaken
,itemname
,ROW_NUMBER() OVER(PARTITION BY itemname ORDER BY DateTaken asc) AS `rn`
,finalgrade
,CASE
WHEN finalgrade >= 70 THEN 'Pass'
WHEN finalgrade < 70 THEN 'Fail'
END AS IsPassing
,gradepass
FROM moodle_prod.mdl_grade_grades_history GH
INNER JOIN mdl_user ON GH.userid = mdl_user.id
INNER JOIN mdl_grade_items GI ON GH.itemid = GI.id
WHERE
rawgrade is not null
) as subq
WHERE
subq.KUserID = ?
AND
subq.YearDateTaken = ?
ORDER BY itemname
Here's the working WHERE clause
WHERE
subq.KUserID = '032649'
AND
subq.YearDateTaken= '2018'
Any thoughts?
UPDATE: I've found a sub optimal workaround that gives me the results I'm looking for but at the cost of performance.
I removed the parameters from the query itself, and instead used the built-in filters in SSRS. This is quite a bit slower because the query returns all results and then the report filters them.
I thought I would include this as an answer because it may be helpful for anyone else who has this same issue, isn't bothered by a long query run time, and just wants a quick fix.
I'm still looking for an solution to the actual problem, rather than a workaround.

How to query last 2 business days only

I'm running a query that pulls the correct information I'm looking for, but I need it to pull the last 2 business days rather than the last 2 days. This comes into play when it's Monday and my results show information for Monday and Sunday rather than Monday and Friday. How can I change my query to pull in business days only?
USE [LetterGeneration]
SELECT g.LetterGenerationPrintJobId
,CAST(t.[TemplateKey] AS VarChar) AS LetterCode
,convert(char(12),r.CreatedDate,101) AS CreatedDate
,s.LetterGenerationStatusId AS Status
,s.StatusKey AS StatusDesc
,count(g.LetterGenerationId) as LetterCount
,c.BankingDateYorN
FROM [LetterGenerationTemplateRequest] AS r
INNER JOIN [LetterGenerationTemplate] AS t
ON t.[LetterGenerationTemplateId] = r.LetterGenerationTemplateId
INNER JOIN LetterGeneration g
ON g.LetterGenerationTemplateRequestId = r.LetterGenerationTemplateRequestId
INNER JOIN LetterGenerationStatus s
ON g.LetterGenerationStatusId = s.LetterGenerationStatusId
INNER JOIN Enterprise..Calendar C
ON c.BeginDate = g.LetterDate
WHERE ((DATEDIFF(d, r.CreatedDate, GETDATE()) = 0) OR (DATEDIFF(d, r.CreatedDate, GETDATE()) = 1))
--BankingDateYorN = 1
--AND RelativeTimeValue_BusinessDates =-1
AND t.[TemplateKey] NOT LIKE '%PLTV1%'
AND s.LetterGenerationStatusId NOT LIKE '4'
AND s.LetterGenerationStatusId NOT LIKE '16'
AND s.LetterGenerationStatusId NOT LIKE '19'
AND s.LetterGenerationStatusId NOT LIKE '20'
AND s.LetterGenerationStatusId NOT LIKE '38'
GROUP BY r.[LetterGenerationTemplateRequestId]
,r.LetterGenerationTemplateId
,g.Lettergenerationprintjobid
,t.[TemplateKey]
,r.[Loan_no]
,r.CreatedDate
,r.[CreatedBy]
,s.LetterGenerationStatusId
,s.StatusKey
,c.BankingDateYorN
ORDER BY r.CreatedDate DESC
UPDATE: I've recently discovered how to join a calendar table to my current query. The calendar query has a column called BusinessDayYorN with 1's for a business day and 0's for weekends and holidays. I've also updated the old query to now include the join.
select *
from LetterGenerationTemplateRequest
where createddate >= (
getdate() -
case datename(dw,getdate())
when 'Tuesday' then 5
when 'Monday' then 4
else 3
end
)
--and datename(dw,createdDate) not in ('Saturday','Sunday',datename(dw,getdate()))
and datename(dw,createdDate) not in ('Saturday','Sunday')
;
Assuming that you always want to include the last two non-weekend days you can try this:
; with aux as (
select diff = case
when datename(weekday, getdate()) in ('Tuesday', 'Wednesday ', 'Thursday', 'Friday') then 1
else
case datename(weekday, getdate())
when 'Saturday' then 2
when 'Sunday' then 3
when 'Monday' then 4
end
end
)
SELECT --r.[LetterGenerationTemplateRequestId]
--,r.LetterGenerationTemplateId
g.LetterGenerationPrintJobId
,CAST(t.[TemplateKey] AS VarChar) AS LetterCode
,r.[Loan_no]
,convert(char(12),r.CreatedDate,101) AS CreatedDate
-- ,g.ModifiedDate
-- ,convert(varchar(18), g.ModifiedDate - r.CreatedDate, 108) AS TimeSpan
,s.LetterGenerationStatusId AS Status
,s.StatusKey AS StatusDesc
,count(g.LetterGenerationId) as LetterCount
FROM [LetterGenerationTemplateRequest] AS r
INNER JOIN [LetterGenerationTemplate] AS t
ON t.[LetterGenerationTemplateId] = r.LetterGenerationTemplateId
INNER JOIN LetterGeneration g
ON g.LetterGenerationTemplateRequestId = r.LetterGenerationTemplateRequestId
INNER JOIN LetterGenerationStatus s
ON g.LetterGenerationStatusId = s.LetterGenerationStatusId
WHERE
DATEDIFF(day, r.CreatedDate, GETDATE()) <= (select diff from aux)
AND t.[TemplateKey] NOT LIKE '%PLTV1%'
AND s.LetterGenerationStatusId NOT LIKE '4'
AND s.LetterGenerationStatusId NOT LIKE '16'
AND s.LetterGenerationStatusId NOT LIKE '19'
AND s.LetterGenerationStatusId NOT LIKE '20'
AND s.LetterGenerationStatusId NOT LIKE '38'
GROUP BY r.[LetterGenerationTemplateRequestId]
,r.LetterGenerationTemplateId
,g.Lettergenerationprintjobid
,t.[TemplateKey]
,r.[Loan_no]
,r.CreatedDate
-- ,g.ModifiedDate
,r.[CreatedBy]
,s.LetterGenerationStatusId
,s.StatusKey
ORDER BY r.CreatedDate DESC
The CTE aux returns a dataset with only one record and only one field, the value of which is the number of days you need to go back in your WHERE statement.

Mysql exclude saturday where another value is equal to

Im having a little trouble coming to the correct syntax for my code to do what I want. Im summing up numbers of hour worked in a specific week by an employee, but I want to exclude certain days from my query. The employee can have worked for different clients, which are defined by a client_id.
Now the code below have a syntax error in the WHERE-statements inside the parantheses, and I know why, Ill just let them be there for the sake of explaining what I want to achieve in this case.
I appreciate any help you can give me.
Btw: I also tried AND( DAYOFWEEK(date) <> 7 AND client_id = '1' ) but this doesnt work either. I recon this is because my query return just a single line of result, and thus my above code doesnt do anything while the query is loop
SELECT
date,
client_id,
SUM(hours)-37.5 AS total,
SUM(lunch = 'yes') AS lunch
FROM
hours
WHERE
CONCAT(WEEK(date, 1)) = '25'
AND
CONCAT(YEAR(date)) = '2015'
AND
employee_id = '14'
AND ( DAYOFWEEK(date) <> 7 WHERE client_id = '1' )
AND ( DAYOFWEEK(date) <> 1 WHERE client_id = '2' )
AND
status = 'billed'
HAVING SUM(hours) > 37.5
You can use a bunch of logical not and and logical operators to build this logic:
SELECT
date,
client_id,
SUM(hours)-37.5 AS total,
SUM(lunch = 'yes') AS lunch
FROM
hours
WHERE
CONCAT(WEEK(date, 1)) = '25'
AND
CONCAT(YEAR(date)) = '2015'
AND
employee_id = '14'
AND NOT ( DAYOFWEEK(date) = 7 AND client_id = '1' )
AND NOT ( DAYOFWEEK(date) = 1 AND client_id = '2' )
AND
status = 'billed'
HAVING SUM(hours) > 37.5

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