Standing Orders with SQL / HQL - sql

I implemented an own program to manage my incomes and expenses some years ago. However, I realized that I need some kind of "standing orders" - incomes or expenses which repeat monthly, quarterly or yearly. I would add them in an own table (with the value, description, start and end date, repetition rate, ...). But how do I query them with SQL/HQL in a smart way? For example: I want all incomes for a given month. Now I have to run through all entries and check somehow whether the start date plus a multiple of the repetition rate "hits" the current month. Seems to me very cumbersome. Is there an easy way to implement such operations?

Sorry for answering my own question, but in the meantime I think that it is not that difficult. Even when using HQL it is possible to calculate the number of months between two dates (if not with an existing function, it can still be done in the HQL expression using an obvious formula). Of course one has to handle the case correctly with days which exist in one month but not in the other (e.g., february), but this is a detail which can likely be ignored in my case.
Knowing the number of months between the current month, a simple modulo expression can check whether the current month is "hit" by the standing order. The rest is simple.

Related

Add column of customer's past purchase total at time of current purchase and find rate of purchases that are from a returning customer - SQL

I am working with a table containing the purchase history for a shop. There is a purchase id, a date column and a customer id. I am trying (without much success so far) to do two things:
Add a column which for each purchase tells how many purchases the customer made before this (in the last month). I started by joining the table on itself but haven't got much further. I know I'll need to somehow filter the date so it only counts purchases before this date and not more than a month ago. Any suggestions on a simple way to tackle this?
The second thing I would like to see is what the weekly rate of returning customer transactions is. That is, what proportion of the purchases are by someone who purchased recently (in the last month). Ideally I would be able to graph this so from my sql queries I would like to end up with a date, weekly total (the 7 days up to the date) and weekly rate. I have been reading up on rolling windows and to be honest am having a bit of trouble getting my head around it. My SQL level is still quite low unfortunately. Any tips on a relatively simple way to do this would be much appreciated.
Thanks
I would need to see your data structure for the table(s) to better answer your question. But right off the top of my head is seems like you just need a simple SELECT COUNT.
So something like this would return all transactions from a single customer made in the past month:
SELECT COUNT(purchase_id)
FROM purchases
WHERE customer_id='some_customer_id'
AND date >= DATEADD(m, -1, GETDATE());
As for your second question you would probably want to setup a job (jenkins, ect..) that would run a query every month. The results of which you would plot. Checkout https://oss.oetiker.ch/rrdtool/ for graphing

DAX sum different DateTime

I have a problem here, i would like to sum the work time from my employee based on the data (time2 - time 1) daily and here is my query:
Effective Minute Work Time = 24. * 60 * (LASTNONBLANK(time2,0) -FIRSTNONBLANK(time1,0))
It works daily, but if i drill up to weekly / monthly data it show the wrong sum as it shown below :
What i want is summary of minute between daily different times (time2-time1)
Thanks for your help :)
You have several approaches you can take: the hard way or the easier way :). The harder (at least for me :)) is to use DAX to do this. You would:
1) create a date table,
2) Use the DAX calculate function to evaluate your last non-blank and first non-blank values (you might need to use calculate table, but I'm not sure; DAX experts jump in). Then subtract one vs. the other.
This will give you correct values for a given day for a given person. You can enforce the latter condition by putting a 'has one value' guard on the person name so that your measure informs the report author if they're not using it right.
Doing the same for dates is a little trickier. In the example you show you are including the date in the row grouping. But if you change your mind and want instead to have 'total hours worked by person' or 'total hours worked by everyone' you're not done with modelling yet.
Your next step is to use calculate table in combination with calculate to create a measure that returns the total. You'll use calculate table so you evaluate each date and the hours worked on that date by person. Then you'll use calculate to summarize that all down to a single number. If you're not careful with your DAX (or report authoring) you might mix which person you're summarizing for so that your first/last non blank are not at the person level. It gets intense quickly.
Your easier solution, though it might be more limited in its application - depends really on your scenario - is to use the query to transform the data into a summary by day and person using the group by command. This will give you a row per person per day with their start and end times. Then you can quickly calculate the hours worked on that day. Then you can quite easily build visuals on top of the summary data. Of course you give up some of the flexibility of the having a proper data model. However if you have a date table, a person table, and your summary table and then setup your relationships correctly you can achieve answers to the most common questions.

OptaPlanner: deliveryman going from multiple suppliers to customers

I'm new to OptaPlanner, and seen how some problems can be solved fairly easily by modifying from the very useful sets of example. I'm trying to figure out what is the best way to model my problem.
I have a group of deliverymen, and their job is to deliver supplies from multiple suppliers to multiple customers. The tricky part is that the customers requirements and suppliers supplies are range values that varies from month to month. And I also have the option to hire temp deliverymen if the supplies and demands of the month is too high. End result is to maximize profit for each month.
What category of optimization problem am I facing, and I'm struggling to find the best way to model this problem. Any suggestions?
Put in a number of temp deliverymen as normal deliverymen with a boolean temp=true, and have your score constraints penalize those more (I presume a higher soft weight as the soft score will be your profit).
This is basically the pickup and delivery variation of the VRP example. Some of our users have adjusted the VRP example to this already (see some of the other questions here on stackoverflow tagged with optaplanner). Basically the trick is to write a score constraint that understands that the "load" of a vehicle changes through its route (but it should always be less than its "capacity").
You can schedule 1 month (or 1 week or less or 2 months or more) at a time, but you can also do "continuous planning" (if months affect each other like in nurse rostering, but I doubt that's the case here) (if so, see the optaplanner video on youtube) to plan a window.

Core Data or NSDictionary with multiple date entries (about 800+ each year)? What would be the most easy to implement?

I'm trying to figure the best approach to solve this problem.
--
I have a "History" table that,
lists ALL years that have data.
If a user clicks a given Year, it segues to a new Table and,
lists ALL months that have data.
Clicking a given month, shows a new table that,
lists ALL days that have data.
Clicking a specific day, shows a list of one or multiple Time Stamps.
--
What is the best approach to solve this?
If user creates a Time Stamp. I need to insert it with today's date.
I also need to have the ability that if a user,
Deletes a given year. Everything in that year is deleted.
That same way,
Deleting a month, deletes everything in that month, for it's particular year.
And so on, to the point where the user should be able to delete Individual Time Stamps.
--
I thought I would Use a Dictionary with key for the "year". 2012, 2013, ...
And each retrieving another Dictionary with key for the "month", 1, 2, 3, 4, ...
And so on ... and so on ...
I also thought I could make a model using Core Data.
A Class Year representing the "Year" entity, having a relation to many possible Months, and each month, having a relation to many possible days, and days to Time *Stamps*.
And last,
I thought of creating a model with only two Entities.
Entries, with only one attribute "Date", that has a to-many relationship to "Time Stamps", receiving All the possible Time Stamps for that given day.
I am new to iOS programming. So this is all theory for me. But I did follow some Core Data tutorials and others working with NSDictionaries, protocols delegates and so on.
The "Dig In" approach as I go trough, seems more elegant. Specially because I think I could delete a particular given object in a cascade manner?
Do any of these make sense? Or is there a more obvious easy way to go about it? Also, please consider in the answer what would be easier to implement if a user chooses to delete a given entry in the "tree"
Any help is most appreciated.
Thank you advance!
Nuno
If you are going to rely on Core Data or any database engine, the best way to solve this is to use the database itself.
I see two possible solutions (there is more of course). The first, the simplest :
Entity
- timestamp
- year
- month
- day
- all_the_stuff_you_need
Make year, month and day readonly, updated along timestamp. Indexes: year, year+month, year+month+day. Easy call.
That way, you can very simple query the database, asking it to return the entities you need and only the entities you need.
A more complex setup would be:
Entity
- timestamp
- all_the_stuff_you_need
- year -> Year
- month -> Month
- day -> Day
Year
- year
- entities ->> Entity
Month
- month
- entities ->> Entity
Day
- day
- entities ->> Entity
So basically, 3 data domains for the years, months and days, months and days being immutable.
That structure is more complex, but it gives a better view of your data. You have a direct access to more information on your data as the data domains are explicit and well defined.
A third solution would be to create a date entity with year, month and day, with one entry per day. A middle ground between the two solutions above. Less interesting I think, but hey, it may suit your needs anyway.

track sales for week/month and find the best sellers

Lets say I have a website that sells widgets. I would like to do something similar to a tag cloud tracking best sellers. However, due to constantly aquiring and selling new widgets, I would like the sales to decay on a weekly time scale.
I'm having problems puzzling out how store and manipulate this data and have it decay properly over time so that something that was an ultra hot item 2 months ago but has since tapered off doesn't show on top of the list over the current best sellers. What would be the logic and database design for this?
Part 1: You have to have tables storing the data that you want to report on. Date/time sold is obviously key. If you need to work in decay factors, that raises the question: for how long is the data good and/or relevant? At what point in time as the "value" of the data decayed so much that you no longer care about it? When this point is reached for any given entry in the database, what do you do--keep it there but ensure it gets factored out of all subsequent computations? Or do you archive it--copy it to a "history" table and delete it from your main "sales" table? This is relevant, as it has to be factored into your decay formula (as well as your capacity planning, annual reporting requirements, and who knows what all else.)
Part 2: How much thought has been given to the decay formula that you want to use? There's no end of detail you can work into this. Options and factors to wade through include but are not limited to:
Simple age-based. Everything before the cutoff date counts as 1; everything after counts as 0. Sum and you're done.
What's the cutoff date? Precisly 14 days ago, to the minute? Midnight as of two Saturdays ago from (now)?
Does the cutoff date depend on the item that was sold? If some items are hot but some are not, does that affect things? What if you want to emphasize some things (the expensive/hard to sell ones) over others (the fluff you'd sell anyway)?
Simple age-based decays are trivial, but can be insufficient. Time to go nuclear.
Perhaps you want some kind of half-life, Dr. Freeman?
Everything sold is "worth" X, where the value of X is either always the same or varies on the item sold. And the value of X can decay over time.
Perhaps the value of X decreased by one-half every week. Or ever day. Or every month. Or (again) it may vary depending on the item.
If you do half-lifes, the value of X may never reach zero, and you're stuck tracking it forever (which is why I wrote "part 1" first). At some point, you probably need some kind of cut-off, some point after which you just don't care. X has decreased to one-tenth the intial value? Three months have passed? Either/or but the "range" depends on the inherent valud of the item?
My real point here is that how you calculate your decay rate is far more important than how you store it in the database. So long as the data's there that the formalu needs to do it's calculations, you should be good. And if you only need the last month's data to do this, you should perhaps move everything older to some kind of archive table.
you could just count the sales for the last month/week/whatever, and sort your items according to that.
if you want you can always add the total amonut of sold items into your formula.
You might have a table which contains the definitions of the pointing criterion (most sales, most this, most that, etc.), then for a given period, store in another table the attribution of points for each of the criterion defined in the criterion table. Obviously, a historical table will be used to store the score for each sellers for a given period or promotion, call it whatever you want.
Does it help a little?