I need help displaying a field that is zero - sql

In this query I'm counting work orders that were created the previous week and displaying a count by wotype2. If a wotype2 for the previous week is zero, I need the wotype2 to appear in my results. Any ideas on how to pull this off?
-- Retrieve Last Week's New Work Orders.
DECLARE #TodayDayOfWeek INT
DECLARE #EndOfPrevWeek DateTime
DECLARE #StartOfPrevWeek DateTime
--get number of a current day (1-Monday, 2-Tuesday... 7-Sunday)
SET #TodayDayOfWeek = datepart(dw, GetDate())
--get the last day of the previous week (last Sunday)
SET #EndOfPrevWeek = DATEADD(dd, -#TodayDayOfWeek, GetDate())
--get the first day of the previous week (the Monday before last)
SET #StartOfPrevWeek = DATEADD(dd, -(#TodayDayOfWeek+6), GetDate())
SELECT wotype2 as WOType, COUNT(*) as NewWOsLastWeek
FROM tasks
WHERE ((OpenDATE BETWEEN
CONVERT(VARCHAR, #StartOfPrevWeek,7) AND
CONVERT(VARCHAR, #EndOfPrevWeek+1,7)) AND
(TYPE = 'Information Systems') AND
(RESPONS != 'ADMIN'))
group by wotype2
order by wotype2

You may need to do an outer join (say a left outer join) with a table which has all the possible values of wotype2.
If there is such a table, let's say it's named wotype2s, then the SQL would be:
SELECT wotype2s.wotype2 as WOType, COUNT(*) as NewWOsLastWeek
FROM wotype2s left outer join tasks on wotype2s.wotype2 = tasks.wotype2
WHERE ((OpenDATE BETWEEN
CONVERT(VARCHAR, #StartOfPrevWeek,7) AND
CONVERT(VARCHAR, #EndOfPrevWeek+1,7)) AND
(TYPE = 'Information Systems') AND
(RESPONS != 'ADMIN'))
group by wotype2s.wotype2
order by wotype2s.wotype2
or, if there is no such table,
SELECT wotype2s.wotype2 as WOType, COUNT(*) as NewWOsLastWeek
FROM (select distinct wotype2 from tasks) wotype2s
left outer join tasks on wotype2s.wotype2 = tasks.wotype2
WHERE ((OpenDATE BETWEEN
CONVERT(VARCHAR, #StartOfPrevWeek,7) AND
CONVERT(VARCHAR, #EndOfPrevWeek+1,7)) AND
(TYPE = 'Information Systems') AND
(RESPONS != 'ADMIN'))
group by wotype2s.wotype2
order by wotype2s.wotype2

Related

Using an Aggregate function with a sub query

We get a new batch of widgets each month. We know the product codes of these widgets which will be is stock, waiting to be used. Each also has an availability date, after which it can be used.
Table WidgetStock
Columns: WidgetID, AvailabilityDate,
Another table has the uses of the widget, ie when it was first used.
Table WidgetsUsed
Columns: datetime, Operator
I'd like to see by day and hour the amount of fresh widgets that I have used for the first time, since the start of the month. The widgets will be used multiple times, so a simple distinct count by hour is not really enough, as widgets would be double counted.
In my mind this would require looking at a list of available numbers, which is updated for each line of a group by query.
The below query will not work, but hopefully it shows what I am trying to achieve:
declare #StartofMonth datetime
set #StartofMonth = '20160901'
select CONVERT(varchar, wu.datetime, 103)'Date'
, convert(char(2), wu.datetime, 108)'Hour'
--Problem Line below
, SUM(case when wu.StockNo in (select ba.NUMBER
from widgetStock ba
where availability_date between CONVERT(varchar, wu.datetime, 103) and #StartofMonth) then 1 else 0 end) 'Number Used'
from widgetsUsed wu
left join widgetStock ws on wu.StockNo = ws.NUMBER
where wu.OPERATOR = 'WidgetWorld'
and DATETIME between '20160914' and '20160916'
group by CONVERT(varchar,wu.datetime,103), convert(char(2), wu.datetime, 108)
Any help with this is appreciated. Thanks in advance.
If understood your requirement then below script may solve your problem
declare #StartofMonth datetime
set #StartofMonth = '20160901'
select CONVERT(varchar, wu.datetime, 103)'Date'
, convert(char(2), wu.datetime, 108)'Hour'
, SUM(ISNULL(ba.NUMBER,0)) 'Number Used'
from widgetsUsed wu
left join widgetStock ws on wu.StockNo = ws.NUMBER
LEFT JOIN widgetStock ba ON wu.StockNo = ba.NUMBER AND availability_date between CONVERT(varchar, wu.datetime, 103) and #StartofMonth
where wu.OPERATOR = 'WidgetWorld'
and DATETIME between '20160914' and '20160916'
group by CONVERT(varchar,wu.datetime,103), convert(char(2), wu.datetime, 108)

How to get week formatted string in sql query

I have the following SQL query (sql server 2008):
SELECT sum(data.freq) as freq,data.week as week FROM (
SELECT
count(daterequested) as freq,
datepart(wk,daterequested) as week,
daterequested
FROM request ma
JOIN contracts mc ON (mc.uid= ma.uid)
JOIN groups og ON og.groupuid = mc.groupuid
JOIN member m ON (m.memberuid = mc.memberuid)
WHERE daterequested BETWEEN
DATEADD(MONTH,-1,GETDATE())
AND
GETDATE()
AND isdeleted = 0
GROUP BY datepart(wk,daterequested),daterequested
--ORDER BY daterequested ASC
) data
GROUP BY data.week
The result is a table with the following data:
Instead of showing the week number I would like to show the week formatted as following:
MM/dd where MM = month and dd is the day where the week starts.
It would be great if I can format starting with first day of the week, then a middle slash, then the last day of that week and finally the month: example: 11-17/04 (April 11 to 17), etc.
Here is the final table that I would like to get:
Any clue?
In case someone needs it just found a solution, maybe is not the best but works.
SELECT sum(data.freq) as freq,
data.week as week, CAST(data.weekstart as varchar) + '-' + CAST(data.weekend as varchar) + '/' + CAST(data.monthend as varchar) as formatweek
FROM (
SELECT
count(daterequested) as freq,
datepart(wk,daterequested) as week,
DATEPART(dd,DATEADD(dd, -(DATEPART(dw, daterequested)-1), daterequested)) weekstart,
DATEPART(dd,DATEADD(dd, 7-(DATEPART(dw, daterequested)), daterequested)) weekend,
DATEPART(mm,DATEADD(dd, 7-(DATEPART(dw, daterequested)), daterequested)) monthend,
daterequested
FROM requestma
JOIN contracts mc ON (mc.uid= ma.uid)
JOIN groups og ON og.groupuid = mc.groupuid
JOIN member m ON (m.memberuid = mc.memberuid)
WHERE daterequested BETWEEN
DATEADD(MONTH,-1,GETDATE())
AND
GETDATE()
AND isdeleted = 0
GROUP BY datepart(wk,daterequested),daterequested
--ORDER BY daterequested ASC
) data
GROUP BY data.week,data.weekstart,data.weekend,data.monthend

Adding a max date subquery to a group by clause

I need to add a max transactional date to this report, so I can see the most recent transaction date for a patient who does not fall under the parameters in the query. This report will be going into a crystal report and I plan to put the last date of service date in the group header for each patient. The code below is to get the max date for each patient. I need the results inserted, so it takes the patients who fall under the below report and gives their max date. Regardless of what is entered for a date. Thank you in advance. SQL Server 2005.
select
patient_id,
Max(proc_chron)
from patient_clin_tran pct
group by patient_id
The Code for the transaction
select patient_id,
(select p.case_status from patient p where p.patient_id = btb.patient_id and p.episode_id = (select max(episode_id) from patient p2 where p2.patient_id = p.patient_id)) as 'Status',
(select p.lname +', '+ p.fname from patient p where p.patient_id = btb.patient_id and p.episode_id = (select max(episode_id) from patient p2 where p2.patient_id = p.patient_id)) AS 'client',
Coverage_plan_id,
(select proc_code from billing_transaction bt where bt.clinical_transaction_no = btb.clinical_transaction_no and bt.coverage_plan_id=btb.coverage_plan_id and bt.coverage_plan_id = btb.coverage_plan_id) as 'Procedure',
proc_chron,
(select billing_amt from billing_transaction bt where bt.clinical_transaction_no = btb.clinical_transaction_no and bt.coverage_plan_id = btb.coverage_plan_id) as 'Billing Amount',
balance_amount,
(select max (accounting_date) from billing_ledger bl where bl.clinical_transaction_no = btb.clinical_transaction_no and subtype = 'pa' and bl.coverage_plan_id = 'standard') as 'Last Payment on Trans',
(select max (instrument_date) from payment p where p.patient_id = btb.patient_id and p.coverage_plan_id = 'standard') as 'Last Payment on Acct',
(select sum(balance_amount) from billing_transaction_balance btb2 where btb2.patient_id=btb.patient_id and btb2.coverage_plan_id=btb.coverage_plan_id and proc_chron <= CONVERT(CHAR(6), DATEADD(year, -1, DATEDIFF(day, 0,GETDATE())), 112) + '01' and btb2.coverage_plan_id in('standard')) AS 'Balance'
from billing_transaction_balance btb
where proc_chron <= CONVERT(CHAR(6), DATEADD(year, -1, DATEDIFF(day, 0, GETDATE())), 112) + '01' and coverage_plan_id in('standard')
group by patient_id, proc_chron, coverage_plan_id, balance_amount, clinical_transaction_no
In your transaction code, you need to add all the Select columns which are not being aggregated to the Group By. I count 8 non-aggregated columns in the Select statement, so you must have all 8 in the Group By.

Select first and last record each day

I have a table with an engineerID, DateTimeCreated as DateTime, JobID and AuditTypeID
I need a query shows first (engineerID, JobID with AuditTypeID 1) and last (engineerID, JobID with AuditTypeID 2) on each row of the query.
SELECT TOP (100) PERCENT
dbo.AuditTrail.EngineerId,
dbo.AuditTrail.AuditTypeId,
dbo.Engineers.Name,
dbo.Engineers.EngineerTypeCode,
dbo.AuditTrail.JobId,
CAST(dbo.AuditTrail.DateTimeCreated AS Date) AS _Date
FROM
dbo.AuditTrail
INNER JOIN
dbo.Engineers
ON dbo.AuditTrail.EngineerId = dbo.Engineers.EngineerId
WHERE
(dbo.AuditTrail.AuditTypeId = 1) AND
(dbo.Engineers.EngineerTypeCode = 'p') AND
(dbo.Engineers.EngineerTypeCode = 'p') AND
(DATEPART(mm, dbo.AuditTrail.DateTimeCreated) = 6) AND
(DATEPART(YYYY, dbo.AuditTrail.DateTimeCreated) = 2014)
group by
AuditTrail.engineerID,
JobID,
AuditTypeId,
Engineers.name,
Engineers.EngineerTypeCode,
CAST(dbo.AuditTrail.DateTimeCreated AS Date)
ORDER BY
dbo.AuditTrail.EngineerID DESC
for the first part of my query. Unfortunatly I cannot see to select the first record for each day
Any help will be greatly appreciated
First just get the data you need, including the create date. Then grouping that data by date, select the min of each day. Finally, join the two sets, selecting only the minimum of each day -- that is, the first occurrence of each day.
with
AllMonth( EngineerId, AuditTypeId, Name, EngineerTypeCode, JobId, DateTimeCreated )as(
SELECT TOP (100) PERCENT
a.EngineerId,
a.AuditTypeId,
e.Name,
e.EngineerTypeCode,
a.JobId,
a.DateTimeCreated
FROM dbo.AuditTrail a
JOIN dbo.Engineers e
ON e.EngineerId = a.EngineerId
AND e.EngineerTypeCode = a.EngineerTypeCode
WHERE
a.AuditTypeId = 1
AND a.EngineerTypeCode = 'p'
AND a.DateTimeCreated >= DateAdd( mm, DateDiff( mm, 0, GetDate()), 0)
AND a.DateTimeCreated < DateAdd( mm, DateDiff( mm, 0, GetDate()) + 1, 0)
),
FirstByDay( MinDate )as(
select Min( DateTimeCreated )
from AllMonth
group by cast( DateTimeCreated AS Date )
)
select *
from AllMonth a
join FirstByDay f
on f.MinDate = a.DateTimeCreated
ORDER BY a.EngineerID DESC;
To get the last item of each day, just add a max to FirstByDay and add to the join. Work it into one long row if you really want to.
Btw, didn't I hear a few years back that the later versions of MSSQL ignored top (100) percent? I don't work with it much these days, and my memory is...well, just...somewhere around here...

I have two tables with common Quote_No and I need to sum Qty in Quote_Items with Required by Date in Table Quotes

I am trying to get the sum of "Qty" in a Table A called "Quote_Items" based on a "Required_by_Date" from Table B called Quotes. Both tables have a common "Quote_No" The required date is one month ago.
I have used the following but it produces a NULL, but I cannot see why
select sum(Qty)
from quotes.Quote_Items_Quantities
left outer join quotes.Quotes on (Quote_Required_by_Date = Qty)
WHERE (DatePart(yy, Quote_Required_by_Date) = DatePart(yy, DateAdd(m,1,getdate()))) and
datepart(m,Quote_Required_by_Date) = datepart(m,dateadd(m,1,getdate()))
Any suggestions what I am doing wrong here.
Try this:
SELECT SUM(i.Qty)
FROM Quote_Items i
JOIN Quotes q on i.Quote_No = q.Quote_No
AND CONVERT(varchar, q.Required_by_Date, 112) = CONVERT(varchar, DATEADD(month, -1, getdate()), 112)
or this (equivalent without using JOIN)
SELECT SUM(i.Qty)
FROM Quote_Items i
WHERE EXISTS(SELECT 1 FROM Quotes WHERE Quote_No = i.Quote_No AND CONVERT(varchar, Required_by_Date, 112) = CONVERT(varchar, DATEADD(month, -1, getdate()), 112))
Your query is producing NULL because of the join condition. You have
on Quote_Required_by_Date = Qty
However, the date is not going to match the quantity. Instead, you need to match on the Quote_No, according to your question:
select sum(Qty)
from quotes.Quote_Items_Quantities qiq left outer join
quotes.Quotes q
on q.Quote_Required_by_Date = qiq.Qty
WHERE (DatePart(yy, Quote_Required_by_Date) = DatePart(yy, DateAdd(m,1,getdate()))) and
datepart(m,Quote_Required_by_Date) = datepart(m,dateadd(m,1,getdate()));
You can also simplify your query by using the month() and year() functions:
select sum(Qty)
from quotes.Quote_Items_Quantities qiq left outer join
quotes.Quotes q
on q.Quote_Required_by_Date = qiq.Qty
WHERE year(Quote_Required_by_Date) = year(DateAdd(m, 1, getdate()) and
month(Quote_Required_by_Date) = month(dateadd(m,1,getdate());
Finally, you mind find it useful to use group by and get the results for many months:
select year(Quote_Required_by_Date), month(Quote_Required_by_Date), sum(Qty)
from quotes.Quote_Items_Quantities qiq left outer join
quotes.Quotes q
on q.Quote_Required_by_Date = qiq.Qty
group by year(Quote_Required_by_Date), month(Quote_Required_by_Date)
order by 1 desc, 2 desc;