SELECT Agents Who Have Not Been Evaluated (by week) - sql

Trying to pull list of agents that have not been Evaluated (Scored) in the past week. I'm getting the Agent_Name, but when checking list of Evaluations, their names are appearing in the Evaluation list.
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent
left outer join dbo.crr crr
on agent.id = crr.agentfk
left outer join dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null
and crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0);

You need to move the condition on crr to the on clause:
select agent.firstname + ' ' + agent.lastname Agent_Name
from dbo.agent agent left outer join
dbo.crr crr
on agent.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0) left outer join
dbo.evaluation eval
on crr.id = eval.crrfk
where eval.crrfk is null ;
I'm not sure why you need the evaluation table, if the data is in crr. I mean, this should do the same thing (assuming you are using the right date):
select (a.firstname + ' ' + a.lastname) as Agent_Name
from dbo.agent a left outer join
dbo.crr
on a.id = crr.agentfk and
crr.localtime >= Dateadd(Day, Datediff(Day, 0, Dateadd(D, -7, Current_Timestamp)), 0)
where crr.id is null ;

Related

How would you write this SQL query without the use of a temp table?

I am having difficulty running this query in Power Bi because it uses a temporary table. How would I write this without a temp table?
SELECT Convert(varchar,TT1.POST_DATE,110) as 'POST_DATE',
COUNT (DISTINCT TT1.TRAN_DATE) as 'NO_DAYS_ENTERED',
HP4.EMPLOYEE_CODE,
HP4.EMPLOYEE_NAME,
HP4.EMPLOYEE_NAME + ' (' + LEFT(HB6.OFFC_DESC,3) + ')' as 'EMPLOYEE_NAME_2',
TT1.OFFC,
HB6.OFFC_DESC,
HP4.GRAD_YEAR,
TB1.RANK_CODE,
TR1.RANK_DESC
into #tempG1
FROM TAT_TIME TT1
LEFT JOIN HBM_PERSNL HP4 ON TT1.TK_EMPL_UNO = HP4.EMPL_UNO
INNER JOIN TBM_PERSNL TB1 on HP4.EMPL_UNO = TB1.EMPL_UNO
INNER JOIN TBL_RANK TR1 on TB1.RANK_CODE = TR1.RANK_CODE
INNER JOIN HBL_OFFICE HB6 on HP4.OFFC = HB6.OFFC_CODE
WHERE TB1.RANK_CODE IN ('4')
AND HP4.INACTIVE = 'N'
AND TT1.POST_DATE >= DATEADD(month, -3, GETDATE())
GROUP BY TT1.POST_DATE, HP4.EMPLOYEE_CODE, HP4.GRAD_YEAR, HP4.EMPLOYEE_NAME, TT1.OFFC, TB1.RANK_CODE, TR1.RANK_DESC, HB6.OFFC_DESC
select G1.EMPLOYEE_NAME,
G1.EMPLOYEE_NAME_2,
datediff(day, min(G1.POST_DATE), max(G1.POST_DATE)) * 1.0 / nullif(count(*) - 1, 0) as 'AVG_FREQ'
from #tempG1 G1
group by G1.EMPLOYEE_NAME, G1.EMPLOYEE_NAME_2
drop table #tempG1
You need to refer query of #tempG1 as an inline view in your main SQL.
Try this -
select G1.EMPLOYEE_NAME,
G1.EMPLOYEE_NAME_2,
datediff(day, min(G1.POST_DATE), max(G1.POST_DATE)) * 1.0 / nullif(count(*) - 1, 0) as 'AVG_FREQ'
from (SELECT Convert(varchar,TT1.POST_DATE,110) as 'POST_DATE',
COUNT (DISTINCT TT1.TRAN_DATE) as 'NO_DAYS_ENTERED',
HP4.EMPLOYEE_CODE,
HP4.EMPLOYEE_NAME,
HP4.EMPLOYEE_NAME + ' (' + LEFT(HB6.OFFC_DESC,3) + ')' as 'EMPLOYEE_NAME_2',
TT1.OFFC,
HB6.OFFC_DESC,
HP4.GRAD_YEAR,
TB1.RANK_CODE,
TR1.RANK_DESC
FROM TAT_TIME TT1
LEFT JOIN HBM_PERSNL HP4 ON TT1.TK_EMPL_UNO = HP4.EMPL_UNO
INNER JOIN TBM_PERSNL TB1 on HP4.EMPL_UNO = TB1.EMPL_UNO
INNER JOIN TBL_RANK TR1 on TB1.RANK_CODE = TR1.RANK_CODE
INNER JOIN HBL_OFFICE HB6 on HP4.OFFC = HB6.OFFC_CODE
WHERE TB1.RANK_CODE IN ('4')
AND HP4.INACTIVE = 'N'
AND TT1.POST_DATE >= DATEADD(month, -3, GETDATE())
GROUP BY TT1.POST_DATE, HP4.EMPLOYEE_CODE, HP4.GRAD_YEAR, HP4.EMPLOYEE_NAME, TT1.OFFC, TB1.RANK_CODE, TR1.RANK_DESC, HB6.OFFC_DESC
) G1
group by G1.EMPLOYEE_NAME, G1.EMPLOYEE_NAME_2

Joining two tables on columns that don't equal

I have a equipment table and a downtime table that I am wanting to join, I am wanting to display all the equipment and the downtime hours. If there is no downtime for a certain piece of equipment then I want to display a zero in the rows where value is null. This is what I have below. It only gives me the equipment that has downtime in the other table.
Select a.EquipNbr,
ISNULL(Sum(a.Downtime),0)
From MobileDowntime (nolock) a
Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and
b.EquipNbr <> 'Clean Shop' and
a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0) and DATEADD(month, DATEDIFF(month, -1, getDate()), -1)
Group By a.EquipNbr
Order by a.EquipNbr Asc
example of what I am trying to accomplish.. But the downtime table on captures data on change so there might not be any downtime for that piece of equipment for the whole month.
66 total pieces of equipment
Equipment / Downtime
1717 57
1723 0
1724 0
1725 50
1728 0
1734 35
1738 0
You want a left join and to move conditions on the MobileDowntime table to the on clause:
Select e.EquipNbr, coalesce(sum(md.Downtime), 0)
From MblEquip e left join
MobileDowntime md
on md.EquipNbr = e.EquipNbr and
md.DateTm between DATEADD(month, DATEDIFF(month, 0, getDate()), 0) and DATEADD(month, DATEDIFF(month, -1, getDate()), -1)
where e.DelFlg = 0 and e.EquipNbr <> 'Clean Shop'
group by e.EquipNbr
order by e.EquipNbr Asc;
Note that I replaced your table aliases (hopefully correctly). a and b are meaningless. Instead, I used abbreviations for the table names.
Final Answer
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr != 'Clean Shop'
AND
(
a.datetm is null or
(a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
and DATEADD(month, DATEDIFF(month, -1, getDate()), -1) )
)
Group By b.EquipNbr Order by b.EquipNbr Asc
Fiddle: https://dbfiddle.uk/?rdbms=sqlserver_2012&fiddle=cc2c2cce139cda7d7c5878d6c967da34
Step by Step
Step 1:
What you need to do is to use an outer-join, and a function that replaces NULL with zero (that you are doing).
So as a first step you would do the following:
Select b.EquipNbr, ISNULL((a.Downtime),0) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Step 2: With Group by
Following, you can add the group by to get the following:
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr != 'Clean Shop'
Group By b.EquipNbr Order by b.EquipNbr Asc
The final part is the where condition using the dates.
Update
The conversion error I think was because of the numerical comparison != .
I did an experiment and converted the Varchar to Int.
Then I changed the != to not like.
Select b.EquipNbr, Sum(ISNULL((a.Downtime),0)) From MobileDowntime (nolock) a
RIGHT OUTER Join MblEquip (nolock) b on a.EquipNbr = b.EquipNbr
Where b.DelFlg = 0 and b.EquipNbr not like 'Clean Shop'
AND
(
a.datetm is null or
(a.DateTm Between DATEADD(month, DATEDIFF(month, 0, getDate()), 0)
and DATEADD(month, DATEDIFF(month, -1, getDate()), -1) )
)
Group By b.EquipNbr Order by b.EquipNbr Asc
You can use left outer join in which it will show null when there is no downtime hours

ms sql subquery different where clause same tables

I'm trying to build the following query:
SELECT
COUNT(dbo.[Order].OrderID) AS Orders,
SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS Revenue,
SUM(dbo.OrderLine.Shipping) AS Expr1,
DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)) AS RevenueDate,
(SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping)) / COUNT(dbo.[Order].OrderID) AS RevenuePerOrder,
SUM(dbo.OrderLine.Qty) AS Qty
FROM
dbo.[Order]
INNER JOIN dbo.OrderLine ON dbo.[Order].OrderID = dbo.OrderLine.OrderID
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue
WHERE (dbo.[Order].OrderStatusID IN (2))
AND (dbo.[Order].PaymentDate >= CONVERT(DATETIME, '02/03/2014', 103))
AND (dbo.[Order].PaymentDate <= CONVERT(DATETIME, '08/03/2014', 103))
AND (dbo.[Order].WebsiteID = 2)
GROUP BY DATEADD(dd, 0, DATEDIFF(dd, 0, dbo.[Order].PaymentDate)), dbo.[Order].WebsiteID
The Sub Query/second INNER JOIN is where things fail, is this something I can do? I want to get Bulk Order Revenue as a another column in the same result set.
Hope this makes sense.
Thanks,
Michael
It looks like your are not specifying what key to join on for your second inner join.
INNER JOIN (
SELECT SUM(dbo.OrderLine.SubTotal) + SUM(dbo.OrderLine.Shipping) - SUM(dbo.OrderLine.Discount) AS BulkRevenue
FROM dbo.OrderLine
INNER JOIN dbo.[Order] ON dbo.OrderLine.OrderID = dbo.[Order].OrderID
WHERE BulkOrder = 1) bulkrevenue ON bulkrevenue.___ = table.____
This may be a case where an outer apply, or cross apply will better suit your needs (I believe your current operation of sums will display the same for every row, not sure if that is intended) see http://sqlserverplanet.com/sql-2005/cross-apply-explained

convert non-ANSI join operators

I've just upgraded my SQL Server database from 2000 to 2005 with compatibility mode 90, and I now find I have some queries using non-ANSI join operators, which are not fully supported in SQL Server 2005. So I need to convert the following code to ANSI-compliant form.
FROM gaf (nolock),
gaf_dress as D (nolock index = pkgaf_DRESS_GUM),
gaf_dress as M (nolock index = pkgaf_DRESS_GUM),
mobile (nolock index = pkmobileID),
Quest (nolock index = pkQuestID)
WHERE
gaf.ID = mobile.ID
and gaf.DRESS_GUM_1 *= D.DRESS_GUM
and gaf.DRESS_GUM_2 *= M.DRESS_GUM
and gaf.ID *= Quest.ID
and gaf.RECORD=1
and na2.PURPOSE <> 'Doore'
and gaf.PD_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime, convert(varchar(6),
getdate(), 112) + '01')))
Any help would be highly appreciated.
I tried this one before
FROM Name (nolock)inner join mobile
on Name.ID = Demographics.ID left outer join NA1
on Name.ADDRESS_NUM_1 = NA1.ADDRESS_NUM left outer join NA2
on Name.ADDRESS_NUM_2 = NA2.ADDRESS_NUM left outer join ACSW
on Name.ID = ACSW.ID
;with Name_Address (nolock,(index(pkName_AddressADDRESS_NUM)))as NA1
;with Name_Address (nolock, (index(pkName_AddressADDRESS_NUM))as NA2 ;with mobile(nolock,
(index (pkmobileID))
;with ACSW (nolock, (index (pkACSWID)))
WHERE gaf.MEMBER_RECORD=1
and na2.PURPOSE <> 'MAIN'
and gaf.PAID_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime,
convert(varchar(6), getdate(), 112) + '01')))
But it’s throw me this error “Msg 102, Level 15, State 1, Line 302
Incorrect syntax near '('.”
FROM gaf
INNER JOIN mobile ON gaf.ID = mobile.ID
LEFT JOIN gaf_dress as D ON and gaf.DRESS_GUM_1 = D.DRESS_GUM
LEFT JOIN gaf_dress as M ON gaf.DRESS_GUM_2 = M.DRESS_GUM AND M.PURPOSE <> 'Doore'
LEFT JOIN Quest ON gaf.ID = Quest.ID
WHERE gaf.RECORD=1
AND gaf.PD_THRU > dateadd(dd, -1, dateadd(mm, -13, convert(datetime, convert(varchar(6),
getdate(), 112) + '01')))

Group data by month

I want to group by results of sales by YEAR-MONTH. My current query which does the results looks like :
SELECT Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2)) AS Mjesec,
e.employeekey,
Sum(s.totalcost) AS SalesAmount
FROM factsales s
INNER JOIN dimstore st
ON s.storekey = st.storekey
INNER JOIN dimemployee e
ON e.employeekey = st.storemanager
WHERE s.datekey BETWEEN '2007-01-01' AND '2007-01-05'
GROUP BY e.employeekey,
Cast(Year(s.datekey) AS VARCHAR(4)) + '-'
+ Cast(Month(s.datekey) AS VARCHAR(2))
ORDER BY employeekey
I am wondering if there are any other better and more elegant way to achieve same results? Perhaps, more friendly format for DateTime in c#?
Much more efficient to strip time by using date math than converting to a string. Also much more efficient to leave the particular string formatting to the end (or better yet, doing it in C# using Format()).
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
),
d AS
(
SELECT m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
)
SELECT
Mjesec = CONVERT(CHAR(7), m, 120),
employeekey,
SalesAmount
FROM d
ORDER BY employeekey;
If you can do the formatting in your app, then you can collapse this to:
;WITH c AS
(
SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
)
SELECT Mjesec = m, employeekey, SalesAmount = SUM(totalcost)
FROM c
GROUP BY m, employeekey
ORDER BY employeekey;
Or even:
SELECT Mjesec = DATEADD(MONTH, DATEDIFF(MONTH, 0, s.datekey), 0),
e.employeekey, s.totalcost
FROM dbo.factsales AS s
INNER JOIN dbo.dimstore AS st
ON s.storekey = st.storekey
INNER JOIN dimemployee AS e
ON e.employeekey = st.storemanager
WHERE s.datekey >= '20070101' AND s.datekey < '20070106'
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, s.datekey, 0), 0), e.employeekey
ORDER BY employeekey;
Do:
SELECT CONVERT(CHAR(7),s.DateKey,120) AS Mjesec....
FROM ....
GROUP BY CONVERT(CHAR(7),s.DateKey,120)....
ORDER BY EmployeeKey