How to get records month wise on rollover calender - sql

I am using following query to get records count on month wise and it is working fine:
SELECT MONTH(dte_cycle_count) MONTH, COUNT(*) COUNT
FROM inventory
WHERE YEAR(dte_cycle_count)='2021' --OR (MONTH(dte_cycle_count) = '1' OR MONTH(dte_cycle_count) = '12')
GROUP BY MONTH(dte_cycle_count);
Problem:
Now I need to bind rollover calendar so user can scroll or click on next or previous button the next 12 Months record will be visible.
eg. Current month is MARCH, So default records will be from APR2020 to MARCH2021. If user click on previous then records will come MAR2020 to FEB2021.
How I can achieve this?
Please let me know if need more information. I will try my best to provide.

I think what you are after is a date list from which to join to your inventory table.
Like a numbers table, build a static table with columns for date, year, month, populated from whenever you need to far in the future.
You then select from this, applying your filtering range critera, and join to your inventory table.
For an efficient query, ideally your inventory table should have the relevant date portions eg year and month stored to match.
You don't want to be using functions on a datetime to extract the year or month as this is not sargable and will not allow any index to be used for a seek lookup.

Related

Displays dates less than the current day's date

In my program, I have a data grid view. I make some amounts due for payment today. I made a display of the amounts that are due and have not been paid (late) I want a code that displays the dates less than the current date of the day I tried that following code but it only fetches the lower days and does not look For the month or year if it is greater or not than the current day's date
tbl = db.readData("SELECT * from Payments where date_batch < CONVERT(varchar(50),GetDate(), 103)", "");
DgvSearch.DataSource = tbl;
The problem with the previous code is that it doesn't fetch the date lower by day, month and year.
Fetches the date less than the current date in terms of day only I want in terms of day, month and year
Ok, so I'm going to assume date_batch is a VARCHAR(10) or similar and contains data like:
28/12/2021
29/11/2021
30/08/2021
31/12/2021
As you can see these "strings that look like dates to a human" are in order. They are not in date order, they are in alphabetical order. Big difference - SQLServer sorts strings alphabetically. When you ask for strings "less than x" it uses alphabetical sorting rules to determine "less than"-ness
Don't stores dates in a string. SQLServer has several date specific datatypes. Use them.
The following process will dig you out of the hole you've dug yourself into:
ALTER TABLE Payments ADD COLUMN BatchDate DATE;
UPDATE Payments SET BatchDate = TRY_CONVERT(Date, date_batch, 103);
Now go look at your table and sanity check it:
SELECT * FROM payments WHERE batchdate is null and date_batch is not null
This shows any dates that didn't convert. Correct their wonky bad data and run the update again.
Do another select, of all the data, and eyeball it; does it look sensible? Do you have any dates that have been put in as 02/03/2021 when they should have been 03/02/2021 etc
Now your table is full of nice dates, get rid of the strings;
ALTER TABLE Payments DROP COLUMN date_batch;
Maybe rename the column, but in SQLServer and c# WeCallThingsNamesLikeThis, we_dont_call_them_names_like_this
sp_rename 'Payments.BatchDate', 'date-batch', 'COLUMN';
Now you can do:
SELECT * FROM payments WHERE batchDate < GetDate()
And never again store dates in a string

Running an Access query on a FILTERED table

I have some related tables that I want to run a Totals/Group By query on.
My "Tickets" table has a field called "PickDate" which is the date that the order/ticket was fulfilled.
I want to group by the weekday (name) (a calculated field) so that results for certain customers on the same day of the week are grouped. Then the average ticket completion time can be calculated per customer for each weekday. It would look something like the following.
--CustName---Day---AvTime
Customer 1 - MON - 72.3
- TUE - 84.2
- WED - 110.66
..etc
..etc
..etc
Customer 2 ..
This works fine but the problem I am having is that when this query is run, it works on every record from the tickets table. There are some reasons that, for certain reports, the data that it the query is referencing should be restricted between a date range; for example to track a change in duration over a number of weeks.
In the query properties, there is a property, "filter", to which I can add a string such as:
"([qryCustomerDetails].[PickDate] Between #11/1/2021# And #11/14/2021#)"
to filter the results. The only issue is that since each date is unique, the "group by" of like days such as "Monday" is overridden by this unique date "11/1/2021". The query only works when the PickDate is removed as a field. However, then I can't access it to filter by it.
What I want to achieve would be the same as; in the "Tickets" table itself filtering the results between two dates and then having a query that could run on that filtered table.
Is there any way that I could achieve this?
For reference here is the SQL of the query.
FROM tblCustomers INNER JOIN tblTickets ON tblCustomers.CustomerID = tblTickets.CustomerID
GROUP BY tblCustomers.Customer, WeekdayName(Weekday([PickDate]),False,1), tblCustomers.Round, Weekday([PickDate])
ORDER BY tblCustomers.Round, Weekday([PickDate]);
You probably encountered two issues. The first issue is that to filter results in a totals query by un totaled fields you use HAVING rather than WHERE. the second issue is that calculated fields like Day don't exist at the time of the query. You can't say having Day > Mon. Instead you must repeat the calculation of Day: Having CalculateDay(PickDate) > Monday
The designer will usually figure out whether you want having or where automatically. So here is my example:
this gives you the SQL:
SELECT Tickets.Customer, WeekdayName(Weekday([PickDate])) AS [Day], Avg(Tickets.Time) AS AvTime
FROM Tickets
GROUP BY Tickets.Customer, WeekdayName(Weekday([PickDate])), Tickets.PickDate
HAVING (((Tickets.PickDate) Between #11/16/2021# And #11/17/2021#))
ORDER BY Tickets.PickDate;

How to right click table to show values?

In a pivot table that plots values against a timeline it is possible to right-click the table, select "Show values as..." and have them appear as a percentage of a particular day.
I'm trying to recreate the same behaviour using DAX measures: I would like to have a measure that shows each day's price as a percentage of the first day of the year.
I've successfully created a measure that correctly identifies the first date of the year, i.e. the baseline:
FDate:=CALCULATE(FIRSTDATE(Prices[Date]),ALLEXCEPT('Calendar','Calendar'[Year]))
However, I can't figure out how to use this FDate to get that day's price (needed as the baseline for further calculations):
CALCULATE([Sum of Price], ALLEXCEPT('Calendar','Calendar'[Year]), FILTER('Prices', 'Prices'[Date]=[FDate])) returns each day's price, not the first date's.
CALCULATE([Sum of Price], FILTER(ALLEXCEPT('Calendar','Calendar'[Year]),'Calendar'[Date]=[FDate])) ignores the YEAR report filter and returns the price of the very first date in my calendar table and not the first date in the year I've filtered for.
Any pointer in the right direction would be greatly appreciated!
Thanks
Here's the solution:
VAR FirstDate = [FDate]
RETURN(
CALCULATE([Price],
FILTER(ALLEXCEPT('Calendar','Calendar'[Year]),'Calendar'[Date]=FirstDate))
)
Variables allow you to define measure in a certain filter context but to leave it unaffected by subsequent filter contexts - that at least is my layman's understanding.
More info here: https://www.sqlbi.com/articles/variables-in-dax/

PowerPivot: Aggregating 'SAMEPERIODLASTYEAR' Sales by Year, Qtr etc

I've created a new measure which uses [TotalSales] and 'SAMEPERIODLASTYEAR' to calculate the previous year's sales, see below:
=CALCULATE([TotalSales], SAMEPERIODLASTYEAR(Dates[Date]))
This all works fine if I create a pivot that displays individual dates (e.g. 01/01/2015) and then the new measure 'previous year sales' value next to it. My problem occurs when I want to change the pivot and display previous year sales by year, quarter or month - with any of these options I get no sales value.
I'm using a 'Dates' table which is linked to the Sales table.
Am I right in thinking I can re-aggregate sales in this way? I have seen an error message which says something about not been able to aggregate a non-contiguous value or date.
I've had a good look to see if anyone else has experienced the same problem, but can't see anything. Any guidance would be helpful.
Regards,
Martyn
Yes you can re-aggregate in this way. Your formula is correct would handles the changes to the aggregation level.
I would check that your 'Dates' table is marked as a date table. Ensure that the year, quarter & months are in this date table and not in your Sales table. Make sure that your date table has one record for each day between the beginning of your sales data set and the end. Check behavior in Power View if you are using Excel 2013.

Query to get Daywise on the month selected

I have an MS Access database table datetime column. When I select a particular month (say, July), I have to get datewise data in that month.
The output should appear in the same format as the attached image.
Every Employee who comes in on a particular date should display “P” for that day. If the Employee doesn’t come in on a particular day (like Sat or Sun), then I have to display “WO” for that day.
When an Employee has not come in (like Sat or Sun), then there is no entry in the log table for that date.
How could an Access query be written to obtain this output? I am using an MS Access 2003 database.
Edit: we have to use TRANSFORM and PIVOT, but the issue is when an employee is not available (Sat, Sun) we still need to show data in the output.
Set up a query that reads EmpID and CheckTime from the first table, and adds one additional column:
DateWise: IIf(Weekday([CheckTime])=1 Or Weekday([CheckTime])=7,"WO","P")
You will need an additional table with every date of the year in it (we'll call it YearDates). Left join that table to your query like so:
Select YD.YearDates, Q2.* from YearDates YD LEFT JOIN Query2 Q2 ON YD.YearDates = DATEVALUE(Q2.CheckTime)
The DATEVALUE will strip the time off your dates in CheckTime so they will match date against date.