Insert data in ssrs table in the query - sql

I would like to insert some data in the ssrs table.
I would like to show it like this here:
How can I add these data in my query in SSRS. I have no possibility to change something in the database.
| P1|P2 |P3 |P4 |P5 |P6 |P7 |P8
Group A|84%|87%|81%|81%|79%|96%|86%|88%
Group B|66%|22%|79%|64%|53%|94%|5% |23%
The Problem is:
Last week on wednesday the database did not recorded the data from Group A and Group B. And I have no possibility to correct/add the missing data in the database. And thats why I would like to add these missed data in my query and show it in the report.
My query:
SELECT *
FROM (
Select
intervaldate as Datum
,tsystem.Name as Name
,team as group
,SUM(GoodUnits) As Goods
,SUM(TheoreticalUnits) As Units
from tCount inner join tsystem ON tCount.systemid = tsystem.id
where IntervalDate >= #StartDateTime AND IntervalDate <= #EndDateTime
group by intervaldate
) c
inner join
(
SELECT
sh.Date as Datum,
sc.Name as Name
FROM tHistory sh
INNER JOIN tSchedule sc ON (sc.ID = sh.ScheduleID)
WHERE Scheduled != 0
) p ON p.Name = c.Name
When I realized that the data was not recorded I did written down the data on paper.

To add manual data to your posted query, you can use UNION ALL and VALUES like so:
First make sure you get your 'additional data' correct on its own. Try this example:
SELECT Datum,Name,[Group],Goods,Units
FROM (
VALUES
(CAST('2015-01-01' AS DATE),'AName','A',10.32,20.76),
(CAST('2015-01-01' AS DATE),'AName','B',12.72,16.15)
) AS ExtraData(Datum,Name,[Group],Goods,Units);
I am making many assumptions here as you have not provided enough info in your question.
Anyway if that is correct, then you simply attach it to your original data with UNION ALL
SELECT Datum,Name,[Group],Goods,Units
FROM (
Select
intervaldate as Datum
,tsystem.Name as Name
,team as [Group]
,SUM(GoodUnits) As Goods
,SUM(TheoreticalUnits) As Units
from tCount inner join tsystem ON tCount.systemid = tsystem.id
where IntervalDate >= #StartDateTime AND IntervalDate <= #EndDateTime
group by intervaldate
) c
inner join
(
SELECT
sh.Date as Datum,
sc.Name as Name
FROM tHistory sh
INNER JOIN tSchedule sc ON (sc.ID = sh.ScheduleID)
WHERE Scheduled != 0
) p ON p.Name = c.Name
/* Original query ends. Now add more data */
UNION ALL
SELECT Datum,Name,[Group],Goods,Units
FROM (
VALUES
(CAST('2015-01-01' AS DATE),'AName','A',10.32,20.76),
(CAST('2015-01-01' AS DATE),'AName','B',12.72,16.15)
) AS ExtraData(Datum,Name,[Group],Goods,Units);

Related

Take the last in the query

I have a query like this:
Select *
From Table1 as ad
inner join Table2 as u
on u.employee_ident=ad.employee_ident
inner join Table3 as t
On u.employee_ident=t.employee_ident and u.hire_date=t.hire_date
where DATEDIFF(day,t.term_date,GETDATE() )>=60 AND u.status in ('nohire','1') and u.company_group_abbr_name='ABC'
order by
t.term_date asc
Table3 for the same user has more than one term_date. I want that when I run this query in the moment that the compare will be done in DATEDIFF(day,t.term_date,GETDATE() )>=60 in the part of t.term_date it will take the last one. Actually when I run it it makes the compare with the first one that it finds.
So from the dates 2018, 2020, and 2022 it compares with 2018 and I want it to make the compare with 2022 which is the most recent one. How can I do this?
Try something like this:
WITH T3Latest (
employee_ident,
hire_date,
term_date,
term_rank
)
AS (
SELECT employee_ident,
hire_date,
term_date,
RANK() OVER (
PARTITION BY employee_ident ORDER BY term_date DESC
) term_rank
FROM Table3
)
SELECT *
FROM Table1 AS ad
INNER JOIN Table2 AS u ON u.employee_ident = ad.employee_ident
INNER JOIN T3Latest AS t ON u.employee_ident = t.employee_ident
AND u.hire_date = t.hire_date
WHERE t.term_rank = 1
AND DATEDIFF(day, t.term_date, GETDATE()) >= 60
AND u.STATUS IN (
'nohire',
'1'
)
AND u.company_group_abbr_name = 'ABC'
ORDER BY t.term_date ASC;

SQL Statement Issue combining 4 tables to get the correct information to display

I am having trouble figuring this one out. I'm using MS SQL 2008 and trying to add the total tech hours from the unbilled table and the billed tables and group them together. I also need to exclude rows for the billed hours based on the report header on a third table if the billed report is voided. I then need to grab the tech names from a 4th table. The unbilled table is SCQReportLabors which lists all the labor records. SCReportLabors table lists all the billed labor records. SCReports is the billed report header which I need to figure out if the VoidID column is null. ShAgents table holds the tech names. Below is what I currently have and I know it doesn't work but it's what I've got so far. For my output data I woul like a TotalHours column and a TechName column. If I end up with a billed total, unbilled total and techname column I can live with that as well. I've been staring at this for a little while and need some perspective and advice. Thanks in advance for any help.
SELECT a.TotalHours, c.PrefFullName AS TechName
FROM (SELECT SUM(LaborHours)+SUM(OvertimeHours)+SUM(TravelHours) AS TotalHours, TechnicianID
FROM SCReportLabors
LEFT OUTER JOIN SCReports d ON a.ReportID = d.ReportID
WHERE d.VoidID IS NULL
GROUP BY TechnicianID) a
JOIN (SELECT SUM(LaborHours)+SUM(OvertimeHours)+SUM(TravelHours) AS TotalHours, TechnicianID
FROM SCQReportLabors
GROUP BY TechnicianID) b
ON a.TechnicianID = b.TechnicianID
LEFT OUTER JOIN ShAgents c ON a.TechnicianID = c.AgentID
ORDER BY c.PrefFullName
This query should capture all data and handles null hours.
SELECT
A.PrefFullName AS 'TechName',
(ISNULL(B.TotalHours, 0) + ISNULL(C.TotalHours, 0)) AS 'Total Hours'
FROM
ShAgents AS A
LEFT OUTER JOIN
(
SELECT
(
SUM(ISNULL(LaborHours, 0)) +
SUM(ISNULL(OvertimeHours, 0)) +
SUM(ISNULL(TravelHours, 0))
) AS 'TotalHours',
TechnicianID
FROM
SCReportLabors AS tA
LEFT OUTER JOIN SCReports AS tB
ON tA.ReportID = tB.ReportID
WHERE
tB.VoidID IS NULL
GROUP BY
TechnicianID
) AS B
ON A.AgentID = B.TechnicianID
LEFT OUTER JOIN
(
SELECT
(
SUM(ISNULL(LaborHours, 0)) +
SUM(ISNULL(OvertimeHours, 0)) +
SUM(ISNULL(TravelHours, 0))
) AS 'TotalHours',
TechnicianID
FROM
SCQReportLabors
GROUP BY
TechnicianID
) AS C
ON A.AgentID = C.TechnicianID
ORDER BY
A.PrefFullName
I made the two main queries a UNION query and also touched up on JOIN for the VOID column.
SELECT SQ1.TotalHours, SHA.PrefFullName AS TechName
FROM
(
SELECT SUM(TOTALHOURS) AS TotalHours, TechnicianID
(SELECT SUM(LaborHours)+SUM(OvertimeHours)+SUM(TravelHours) AS TotalHours, TechnicianID
FROM SCReportLabors L
JOIN SCReports RPTS
ON L.ReportID = RPTS.ReportID
WHERE RPTS.VoidID IS NULL
GROUP BY TechnicianID)
UNION ALL
(SELECT SUM(LaborHours)+SUM(OvertimeHours)+SUM(TravelHours) AS TotalHours, TechnicianID
FROM SCQReportLabors
GROUP BY TechnicianID
)
) SQ
GROUP BY TechnicianID
JOIN ShAgents SHA
ON SQ.TechnicianID = SHA.AgentID
ORDER BY SHA.PrefFullName

How to determine two different aggregate dates on employee attendance data?

I Need help to implement employee attendance sheet. Presently am having employee attendance i.e
Query:
SELECT c.First_name + c.Middle_name + c.last_name AS employeename,
b.Device_Person_id,a.Dept_Id,Date1,
CASE WHEN b.Device_Person_id IS NOT NULL
THEN 'P'
ELSE 'A' END AS status
FROM Emp_setting a
LEFT OUTER JOIN (SELECT Device_Person_id, MAX(logDateTime) AS Date1
FROM tempDeviceLogs
GROUP BY Device_Person_id) b
ON a.personal_id = b.Device_Person_id
LEFT OUTER JOIN persons_profile c
ON c.pesonal_id=a.personal_id
Result:
employeename Device_person_id dept_id date1 status
MEHABOOB NULL 4 NULL A
UDAY NULL 26 NULL A
SHANKRAYYA NULL 10 NULL A
BASAVARAJ NULL 24 NULL A
BHIMAPPA 5 10 2014-05-23 14:14:00.000 P
i.e. Employeename BHIMAPPA is present on 2014-05-23.
NOW I want the list of employees who is present on 2014-05-23.
Please help?
Assuming that logDateTime indicates the presence of the employee, and given that the current derived table returns the MAX() of this field (presumably the last time the employee was detected) you would need another join to the tempDeviceLogs table to do the filtering. You could do the filtering at the same time with an INNER JOIN, viz:
...
INNER JOIN (SELECT Device_Person_id
FROM tempDeviceLogs
WHERE logDateTime >= '2014-05-23' and logDateTime < '2014-05-24') x
ON x.Device_Person_id = a.personal_id
Edit
Given that you want to SELECT the date as well, I'm assuming you want to parameterize it / use it for a range. And making yet another assumption about your SqlServer version being >= 2008, cast the DateTime to a Date and group by it:
SELECT c.First_name + c.Middle_name + c.last_name AS employeename,
b.Device_Person_id,a.Dept_Id, Date1 as DateTimeLastSeen,
x.logDate As DatePresent,
CASE WHEN b.Device_Person_id IS NOT NULL THEN 'P' ELSE 'A' END AS status
FROM Emp_setting a
LEFT OUTER JOIN (SELECT Device_Person_id, MAX(logDateTime) AS Date1
FROM tempDeviceLogs
GROUP BY Device_Person_id) b
ON a.personal_id = b.Device_Person_id
LEFT OUTER JOIN persons_profile c
ON c.pesonal_id=a.personal_id
INNER JOIN (SELECT Device_Person_id, CAST(logDateTime AS DATE) as logDate
FROM tempDeviceLogs
GROUP BY Device_Person_id, CAST(logDateTime AS DATE)) x
ON x.Device_Person_id = a.personal_id
WHERE
logDate BETWEEN '2014-05-01' AND '2014-05-23';
This could also be done with a DISTINCT. If you have an earlier version of SqlServer, use a hack like this to obtain the date part of a DateTime (in the select + group)
Create a variable to hold the date which you are looking for.
DECLARE #cutOffDate DATE
SET #cutOffDate = '23-05-2014'
Then add to the end of your statement
Where Date1 = #cutOffDate

SQL Query For Customers Not Used For Last 3 Years

I THINK I'm having some trouble.
I'm trying to query 2 tables for customers that haven't been used on the table for the last 3 Years. The data consists of data ranging for 7+ years, so customers are used multiple times.
I think the issue with my current query: It's finding data of customers not used in the last 3 years... but it's not accounting for if there is also data of the customer within the last 3 years as well.
Can someone possibly help me? I'm guessing the answer is to use only the data of the customer with the latest date and ignore previous data.
SELECT DISTINCT
tbl_Customer.CustomerID
, tbl_Customer.CustomerName
, Table1.ImportDate
, Table2.ImportDate
FROM
tbl_Customer
LEFT JOIN
Table1 ON tbl_Customer.CustomerName = Table1.CustomerName
LEFT JOIN
Table2 ON tbl_Customer.CustomerName = Table2.CustomerName
WHERE
(((DateAdd("yyyy", 3, [Table2].[ImportDate])) < Now())
AND
((DateAdd("yyyy", 3, [Table1].[ImportDate])) < Now()))
ORDER BY
Table1.ImportDate DESC,
Table2.ImportDate DESC;
The core problem with the initial query is that, for no imports (which will happen for "no order" customers) the condition
DateAdd("yyyy", 3, ImportDate) < Now()
--> DateAdd("yyyy", 3, NULL) < Now()
--> NULL < Now()
--> NULL (or not true)
is not true. A simple fix is to add a guard
([Table1].[ImportDate] IS NULL
OR DateAdd("yyyy", 3, [Table1].[ImportDate]) < Now())
around such expressions or to coalesce the NULL value before using it.
The ordering will also be wrong, as that means order by one value and then the other, not "by the greater of both" values. Compare with
ORDER BY
IIF(Table1.ImportDate > Table2.ImportDate, Table1.ImportDate, Table2.ImportDate)
However, I would use a LEFT JOIN on customers/orders, GROUP BY with a MAX on the order dates. Then you can use that result (as a derived subquery) to complete the query asked fairly trivially.
SELECT
c.CustomerID
, MAX(o.ImportDate) as lastImport
FROM tbl_Customer as c
-- The UNION is to simply "normalize" to a single table.
-- (Also, shouldn't the join be on a customer "ID"?)
LEFT JOIN (
SELECT CustomerName, ImportDate from Table1
UNION
SELECT CustomerName, ImportDate from Table2) as o
ON c.CustomerName = o.CustomerName
GROUP BY c.CustomerID
Then,
SELECT s.CustomerID
FROM (thatSubQuery) as s
WHERE
-- no orders
s.lastImport IS NULL
-- only old orders
OR DateAdd("yyyy", 3, s.lastImport) < Now()
ORDER BY s.lastImport
(YMMV with MS Access, this will work in a "real" database ;-)
SELECT DISTINCT
tbl_Customer.CustomerID,
tbl_Customer.CustomerName,
Table1.ImportDate,
Table2.ImportDate
FROM (tbl_Customer
LEFT JOIN Table1
ON tbl_Customer.CustomerName = Table1.CustomerName)
LEFT JOIN Table2
ON tbl_Customer.CustomerName = Table2.CustomerName
WHERE DateAdd("yyyy",3,[Table2].[ImportDate]) < Now()
AND DateAdd("yyyy",3,[Table1].[ImportDate]) < Now()
AND tbl_Customer.CustomerID NOT IN (
SELECT DISTINCT
tbl_Customer.CustomerID,
FROM (tbl_Customer
LEFT JOIN Table1
ON tbl_Customer.CustomerName = Table1.CustomerName)
LEFT JOIN Table2
ON tbl_Customer.CustomerName = Table2.CustomerName
WHERE DateAdd("yyyy",3,[Table2].[ImportDate]) >= Now()
AND DateAdd("yyyy",3,[Table1].[ImportDate]) >= Now()
)
ORDER BY Table1.ImportDate DESC , Table2.ImportDate DESC;
Based on what I can infer from your query about your data structure, I think you want something like this:
DECLARE #CutOff DateTime
SET #CutOff = DATEADD(y, -3 GETDATE())
SELECT tbl_Customer.CustomerID, tbl_Customer.CustomerName
WHERE (CustomerName IN
(SELECT CustomerName FROM Table1 WHERE ImportDate < #CutOff))
OR
(CustomerName IN
(SELECT CustomerName FROM Table2 WHERE ImportDate < #CutOff)))
AND CustomerName NOT IN
(SELECT CustomerName FROM Table1 WHERE ImportDate > #CutOff)
AND CustomerName NOT IN
(SELECT CustomerName FROM Table2 WHERE ImportDate > #CutOff)

Combining Multiple SQL Views ON Year & Month

I have a SQL Server database (2012 express) with many tables.
I have produced three different VIEWS based on different combinations of the underlying tables.
Each of these views consists of three columns, Year, Month & Total
The Total column in each of the 3 Views is of a different measure.
What I want to be able to do is to combine the three Totals into a single View
I have attempted this with the following script -
SELECT b.[Year], b.[Month], b.Fees AS [Billing],
f.Estimate AS [Estimate],
w.Fees AS [WIP]
FROM MonthlyBillingTotals AS b
FULL JOIN MonthlyFeeEstimates AS f
ON (b.[Year] = f.[Year] AND b.[Month] = f.[Month])
FULL JOIN MonthlyInstructionsWIP AS w
ON (b.[Year] = w.[Year] AND b.[Month] = w.[Month])
ORDER BY b.[Year], b.[Month]
Originally I tried INNER JOINS but of course unless the Year / Month combo existed in the first view (MonthlyBillingTotals) then it did not appear in the combined query. I therefore tried FULL JOINS, but the problem here is that I get some NULLS in the Year and Month columns, when they do not exist in the first view (MonthlyBillingTotals).
If the data in the three Views is as follows -
Then what I want is -
And even better (if it is possible) -
with the missing months filled in
You could try building the full list of Months/Years from your tables using a UNION subquery, and then use that to drive your joins.. Something like this:
SELECT a.[Year], a.[Month], b.Fees AS [Billing],
f.Estimate AS [Estimate],
w.Fees AS [WIP]
FROM (SELECT a.[Year], a.[Month] FROM MonthlyBillingTotals AS a
UNION
SELECT b.[Year], b.[Month] FROM MonthlyFeeEstimates AS b
UNION
SELECT c.[Year], c.[Month] FROM MonthlyInstructionsWIP AS c) AS a
LEFT OUTER JOIN MonthlyBillingTotals AS b
ON (a.[Year] = b.[Year] AND a.[Month] = b.[Month])
LEFT OUTER JOIN MonthlyFeeEstimates AS f
ON (a.[Year] = f.[Year] AND a.[Month] = f.[Month])
LEFT OUTER JOIN MonthlyInstructionsWIP AS w
ON (a.[Year] = w.[Year] AND a.[Month] = w.[Month])
ORDER BY a.[Year], a.[Month]
This is completely untested, but see if this solves your problems:
SELECT b.[Year], b.[Month], Coalesce(b.Fees, '0') AS [Billing],
Coalesce(f.Estimate,'0') AS [Estimate],
Coalesce(w.Fees,'0') AS [WIP]
FROM MonthlyBillingTotals AS b
LEFT JOIN MonthlyFeeEstimates AS f
ON (b.[Year] = f.[Year] AND b.[Month] = f.[Month])
LEFT JOIN MonthlyInstructionsWIP AS w
ON (b.[Year] = w.[Year] AND b.[Month] = w.[Month])
ORDER BY b.[Year], b.[Month]
The Coalesce function puts in a '0' value if nothing is found, and left joins should only join parts of MonthlyFeeEstimates and MonthlyInstructionsWIP when the year and month match.
You could set up a small date table with year and month and left join the views with that, and use the ISNULL(variable,0) function to replace NULL with 0. Another option instead of a date table would be to use a common table expression to generate a date range to join with. In any case I suggest you look up the date table (or numbers table), it can be a really useful tool.
Edit: added an example on how a date table can be created (for reference):
declare #year_month table (y int, m int)
;with cte as (
select cast('2000-01-01' as datetime) date_value
union all
select date_value + 1
from cte
where date_value + 1 < '2010-12-31'
)
insert #year_month (y, m)
select distinct year(date_value), month(date_value)
from cte
order by 1, 2
option (maxrecursion 0)
select * from #year_month