I have a tablix like so
Two parameters - begin date and end date
Customer Emp Hires Emp Terminations
XYZ 12 2
What's the best way to do the grouping, specifically the column grouping? I'm currently grouping by customer in the row group and then in the hire field, I'm doing a sum(iif(hire_date between begin and end date,1,0)). Same for termination field but using the employee's termination date. (Essentialy a sum(case when then 1 else 0 end) in SQL
Now, since they may run it for an entire month, an employee might fall in both columns (hired and termed in the same month). Is what I'm doing the best way or is there a more correct/more effient way? If what I'm doing is the best way in SSRS, it seems I should do the pivoting in SQL (if possible) instead for better performance overall?
If you are using SQL Server,I would suggest to perform this grouping in SQL query only by passing date parameters as the SQL processing is quite fast than that of SSRS.
This is my personal experience to improve performance of report.
Related
I am hoping someone can help me out with a query that may not be possible in Access.
I have a table with all employees and a query that shows everyone that has tested over an 18 month or so period and growing.
I am trying to figure out how I can do a query in access that will show what employees have not tested on individual dates within a range of dates. For example, if I create a query of the dates 10/1/17 – 10/14/17 then the result I am hoping for is that Jim did not test on 10/1 and 10/5 and Joe didn't test on 10/12.
It works great for a single date as it compares only the results from a single date query against the employee table and whoever is not in both did not test, but only for that date.
This is the SQL view of the single day “did not test” query:
SELECT ESD_EMP_BADGE.LAST_NAME, ESD_EMP_BADGE.FIRST_NAME, ESD_EMP_BADGE.EMPID, ESD_EMP_BADGE.DEPT
FROM ESD_EMP_BADGE LEFT JOIN Yesterday ON ESD_EMP_BADGE.[EMPID] = Yesterday.[EMPID]
WHERE (((ESD_EMP_BADGE.DEPT) Not Like "EXE") AND ((Yesterday.EMPID) Is Null));
For a range, I cannot do it the same way as the single date query because if that person tested at some time during the range of the query a single test in that range will make it seem like that person tested for all dates.
Is there a way that each date can be considered separately within a single query?
There is only one field that is guaranteed to be unique in the employee table that is also in the test records “EMPID”. There is no date field in the employee table.
I hope this is clear enough of an explanation. I think I might be reaching beyond what Access can do.
If I understand correctly what you are looking for - you will first need a dataset of all possible combinations of employees and test dates. This dataset can be generated with a query that includes employees and tests taken tables without a join clause. This is a Cartesian relationship of records - every record in each table joins with each record in the other table.
SELECT Employees.EmpID, EmpTests.TestDate FROM Employees, EmpTests;
Then join that query back to the testing table.
SELECT Query1.EmpID, Query1.TestDate, EmpTests.TestDate
FROM EmpTests RIGHT JOIN Query1 ON (EmpTests.TestDate = Query1.TestDate) AND (EmpTests.EmpID = Query1.EmpID)
WHERE (((Query1.TestDate) Between [start date] And [end date]) AND ((EmpTests.TestDate) Is Null));
I use a number of pre-defined conditions to compare the Date field from Trade table against GETDATE() function to work out the trades for this month, this year, previous year etc.
Now I need to create an additional table, where I will have a set of dates representing the start and the end dates for reporting periods, e.g. the start and end dates of current year reporting, the start and the end dates for previous year reporting etc.
This additional table and Trade table are not joined. In fact the additional table is not linked to anything.
I need to create a new set of pre-defined conditions where Date from Trade table will be compared from the values from the new dates table, i.e. I would like the new conditions to look like the following
Trade.Date < ReportingDates.CurrentYearEndDate
AND
Trade.Date > ReportingDates.CurrentYearStartDate
The condition validates fine, but unfortunately I get the "The query cannot run because it contains incompatible objects. (IES 00008)" error" when I try to execute the condition.
You could use subselects in the predefined condition like:
trade.date between (select currentyearstartdate from reportingdates)
and (select currentyearenddate from reportingdates)
Since reportingdates is not actually joined to anything, it does not need to be in the universe structure. This does have one disadvantage -- it's not obvious from the list of tables that it is actually needed in the universe.
Alternatively, you can create a derived table that joins trade and reportingdates as a cartesian product. The derived table would include all columns from both tables, so your condition would simply be (assuming the derived table is named DT):
dt.date between dt.currentyearstartdate and dt.currentyearenddate
The downside to this approach is that reportingdates is included in all queries, whether it's needed or not, and the SQL can be a little harder to read.
I have a DATETIME field in a mysql table with random entries. I would like to select object groups, and break them apart when there is a four hour gap. Ideally I could return all IDs within each group in an array (or sub-group?).
This seems beyond my SQL skills.
Any interesting solutions?
SQL is meant to perform set operations on data, while what you're asking for involves sequential processing.
So, I'd suggest processing it sequentially, rather than trying to twist SQL to try to do this. I believe that you have two basic choices:
Select data from the table in a stored procedure, using a cursor to process the results.
Execute a select statement from the external, stand-alone language of your choice (Java, C#, Python, PHP...whatever floats your boat), and group the data appropriately there.
You can use MySQL DATE_FORMAT clause.
Example
SELECT CAST(DATE_FORMAT(date,'%Y-%m-%d %k:00:00') AS DATETIME) hour
FROM table
WHERE date = CURRENT_DATE - INTERVAL 4 HOUR
GROUP BY CAST(DATE_FORMAT(date,'%Y-%m-%d %k:00:00') AS DATETIME)
I have an order table that contains dates and amounts for each order, this table is big and contains more that 1000000 records and growing.
We need to create a set of queries to calculate certain milestones, is there a way in mysql to figure out on which date we reached an aggregate milestone of x amount.
For e.g we crossed 1 m sales on '2011-01-01'
Currently we scan the entire table then use the logic in PHP to figure out the date, but it would be great if this could be done in mysql without reading so many records at 1 time.
There maybe elegant approaches, but what you can do is maintain a row in another table which contains, current_sales and date it occurred. Every time you have a sale, increment the value, and store sales date. If the expected milestones(1 Million, 2 Million etc) are known in advance, you can store them away when they occur(in same or different table)
i think using gunner's logic with trigger will be a good option as it reduce your efforts to maintain the row and after that you can send mail notification through trigger to know the milestone status
I am trying to build an access report based on data from multiple different tables within the database.
I have 3 columns which perform calculations, and I am wondering how to put this query together. All 3 columns deal with dates, but calculate them differently.
The first column retrieves the most recent date of action for a userid if the type of action is "B":
select pid, Max(date) as most_recent
from actions
where ref = 'B'
group by pid;
The second column performs a calculation based on 2 fields, one is a date and one is a number in months. I am unsure how to add these two fields so that the number is added to the date as a number of months.
what i have so far is:
select nummonths,Max(lastvisit) from users
the third column I need to select the first date thats in the future for each user (next appointment date), there will be dates before and after this date so its a little difficult:
select uid,date from visits
The code for the last 2 queries needs to be slightly modified, and I was wondering what the best approach would be to join these all together? A type of join?
If you need to build a report with data from the 3 queries, you will need related data to join them. In that case, please send the structure of the tables.
If you need to show 3 lists in one report, you can use subreports: create a new empty report. In design mode, you can add 3 subreports from the toolbox bar. To each of the subreport assign the record source property to the corresponding sql.
regards
I am unsure how to add these two fields so that the number is added to the date as a number of months.
Use the DateAdd() function:
SELECT DateAdd("m", 2, LastVisit) FROM ...
Results in a date two months from the LastVisit date.