Getting multiple date ranges between SQL query and adding up the data accordingly - sql

I need to select a certain range of dates after I have already completed the query SELECT * FROM <DB>.
For example:
var (date string
views int
impressions int)
for query.Next() {
err := query.Scan(&date, &views, &impressions)
// handle the err
// get the range of dates for each month
// add up all the views and impressions in that specific range
}
The 'date' var will obviously be all of the dates in the database query.
Dates are formatted as: 2017-10-01 (October 1st as an example) and there are about 300 in October and 100 in November.
From here, I need to add up all the values (views and impressions), but only per date range.
So I would get something like:
2017-10-01 to 2017-10-31 has 54 impressions
2017-10-01 to 2017-10-07 has 5 impressions as an example.
Any idea how I'd come about this issue?

So, the best bet in these cases is to use a map-style strategy to keep track. For example, a map[date]data would allow you to keep a unique entry for each date. Dates, however, have a beneficial optimization, in that they can easily be represented by integers (the day of the year), and the number of options is small enough to not be a memory issue. This means we can use a slice instead of a map and get the benefits of ordering (Go maps are randomly ordered in a for loop) while still using it like a map. For example:
type Data struct {
// fields
}
const dateFormat = "2006-01-02" // only parse the date
dayStats := make([]Data, 366) // account for leap years
for query.Next() {
var datestr string // can make this a time.Time, if your date format scans properly
var dr Data
if err := query.Scan(datestr, /* other fields */ ); err != nil {
log.Fatal(err)
}
date, err := time.Parse(datestr)
if err != nil {
log.Fatal(err)
}
dayStats[date.YearDay()].someField += dr.someField
dayStats[date.YearDay()].someOtherField += dr.someOtherField
// other fields...
}
Now let's say we want to calculate the stats between a 01 October and 31 October:
start := time.Date(2017, time.October, 1, 0, 0, 0, 0, time.UTC)
end := time.Date(2017, time.October, 31, 0, 0, 0, 0, time.UTC)
var total Data
for day := start.YearDay(); day <= end.YearDay(); day++ {
total.someField += dayStats[day].someField
total.someOtherField += dayStats[day].someOtherField
// other fields...
}

Related

Finding the time complexity of a solution to "Number of ways to make change" problem

The question is as follows
Given an array of distinct positive integers and a target sum, find the total number of ways that the elements in the array can be summed up to produce the target sum. The sum can also be achieved by summing up duplicate numbers.
Here's the soluton
func main() {
denoms := []int{1, 2, 5}
return numberOfWaysToMakeChangeHelper(n, 0, denoms, []int{}, 0)
}
func numberOfWaysToMakeChangeHelper(n int, sum int, denoms []int, coins []int, startIndex int) int {
if sum == n {
log.Println(coins)
return 1
}
ways := 0
for i := startIndex; i < len(denoms); i++ {
coin := denoms[i]
if coin + sum > n {
continue
}
ways += numberOfWaysToMakeChangeHelper(n, sum + coin, denoms, append(coins, coin), i)
}
return ways
}
Can anyone help me figure out the time complexity of the above solution ?
I think the answer is (length of the array) x (target sum) as the recursion stack would at max grow to the size of the target sum and at each frame in the stack a for loop iterates over the array.

how to perform dynamic subtraction of a list of numbers with a specific value

My idea is to subtract each value from my list through the value of a variable, for example:
var subtraction = 250
var list = mutableListOf(300, 200, 100)
Then, using the 250 of the subtraction variable,
you can dynamically subtract each value of the item,
from the last to the first, so with that 250 the program should return: -> list(300, 50).
Where 250 is subtracted from item 100 (last item) and then "150" remains from the value "250",
and the remaining 150 is subtracted from 200 (second item) and remains 50,
thus zeroing out the value of "250" and the program stop.
Getting (300, 50) -> 50 which comes from 200 (second item).
As if I was going through my list of numbers, subtracting item by item through the value of a variable, from last to first.
Your question still needs further clarification:
What should be the output if subtraction = 700?
What should be the output if subtraction = 600?
What should be the output if subtraction = 100?
The following can be a starting point to solve your question:
fun subtraction() {
var subtraction = 250
var list = mutableListOf(300, 200, 100)
// Loop the list in Reverse order
for (number in list.indices.reversed()) {
subtraction -= list[number] // Subtract the last number
// If subtraction is greater than zero, continue and remove the last element
if (subtraction > 0)
list.removeAt(number)
else {
// It subtraction is less than or equal to zero,
// remove the last element, append the final subtraction result,
// and stop the loop
list.removeAt(number)
list.add(abs(subtraction))
break
}
}
// If the subtraction result is still positive after whole list has been processed,
// append it back to the list
// if (subtraction > 0)
// list.add(subtraction)
println(list)
}
Output
[300, 50]
The question isn't very clear, but as I understand it: OP wants to modify a list of numbers, subtracting a fixed amount from each, and removing those for which the result would be negative.
If so, it can be done very simply:
list.replaceAll{ it - subtraction }
list.removeIf{ it < 0 }
However, instead of mutating the existing list, it would probably be more common to create a new one:
val newList = list.map{ it - subtraction }.filter{ it >= 0 }
Or, if you need to avoid creating a temporary list:
val newList = list.mapNotNull{ (it - subtraction).takeIf{ it >= 0 } }
A solution with foldRight using a Pair as accumulator:
val list = listOf(300, 200, 100)
val subtraction = 250
val result = list
.foldRight(subtraction to emptyList<Int>()) { item, (diff, list) ->
when {
diff > item -> diff - item to emptyList()
else -> 0 to listOf(item - diff) + list
}
}
.second
println(result) // Output: [300, 50]

Getting Time range between non intersecting ranges

I have the following timelines :
7 a.m --------------------- 12 a.m. 2 am .................. 10 a.m
10-------11 3------5
closed closed
the output should be the non-intersecting time ranges:
7-10 a.m, 11 -12 a.m, 2-3 p.m, 5-10 p.m
I tried to minus and subtract method for Ranges but didn't work
A tricky part could be the following case
7 a.m --------------------- 12 a.m. 2 am .................. 10 a.m
10----------------------------------------5
closed
the output should be the non-intersecting time ranges:
7-10 a.m, 5-10 p.m
Any Idea for kotlin implementation?
I tried to minus and subtract method for Ranges but didn't work
Sounds like a pretty common case and I suspect there are some existing algorithms for it, but nothing comes out of top of my head.
My idea is to first transform both lists of ranges into a single list of opening/closing "events", ordered by time. The start of an opening range increases the "openess" by +1 while its end decreases it (-1). Start of a closing range also decreases "openess" while its end increases it. Then we iterate the events in the time order, keeping the information on what is the current "openess" level. Whenever the "openess" level is 1, that means we are in the middle of an opening range, but not inside a closing range, so we are entirely open.
Assuming both lists of ranges are initially properly ordered, as in your example, I believe it should be doable in linear time and even without this intermediary list of events. However, such implementation would be pretty complicated to cover all possible states, so I decided to go with a simpler solution which is I believe O(n * log(n)). Also, this implementation requires that opening ranges do not overlap with each other, the same for closing ranges:
fun main() {
// your first example
println(listOf(Range(7, 12), Range(14, 22)) - listOf(Range(10, 11), Range(15, 17)))
// second example
println(listOf(Range(7, 12), Range(14, 22)) - listOf(Range(10, 17)))
// two close rangs "touch" each other
println(listOf(Range(8, 16)) - listOf(Range(10, 11), Range(11, 13)))
// both open and close range starts at the same time
println(listOf(Range(8, 16)) - listOf(Range(8, 12)))
}
data class Range(val start: Int, val end: Int)
operator fun List<Range>.minus(other: List<Range>): List<Range> {
// key is the time, value is the change of "openess" at this time
val events = sortedMapOf<Int, Int>()
forEach { (start, end) ->
events.merge(start, 1, Int::plus)
events.merge(end, -1, Int::plus)
}
other.forEach { (start, end) ->
events.merge(start, -1, Int::plus)
events.merge(end, 1, Int::plus)
}
val result = mutableListOf<Range>()
var currOpeness = 0
var currStart = 0
for ((time, change) in events) {
// we were open and now closing
if (currOpeness == 1 && change < 0) {
result += Range(currStart, time)
}
currOpeness += change
// we were closed and now opening
if (currOpeness == 1 && change > 0) {
currStart = time
}
}
return result
}

In ANTLR how should I implement a Visitor with state / context?

I'm trying to write a simple ANTLR parser to handle date adjustment, so for example I could write: +1w+1d to mean "traverse a week and a day", or MIN(+30d, +1m) to mean "30 days from the input date, or 1 month, whichever is sooner". These rules should be composable, so MIN(+30d, +1m)+1d means "the day after (30 days from the input date, or 1 month from the input date, whichever is sooner)" and +1dMIN(+30d, +1m) means "30 days from (the day after the input date) or 1 month after (the day after the input date) whichever is sooner".
[I appreciate the examples here are relatively trite - the real grammar needs to understand about weekends, holidays, month boundaries etc, so it might be things like "one month after(the end of the input date's month or the Friday after the input date - whichever comes first)" etc etc]
The code I want to write is:
DateAdjutmeParser parser = buildFromString("MAX(+30d,+1m)");
ParseTree tree = parser.rootNode();
return new MyVisitor().visit(tree, LocalDate.of(2020,4,23)); //Not allowed extra parameters here.
The problem is how exactly can I pass the "context Date"? I can't store it in the MyVisitor class as a member since the visit() call is recursive and that would overwrite the context. I could build up a parallel set of objects that did have the right methods, but that seems a lot of boilerplate.
Is there an ANTLR solution?
More details:
This is the Visitor I'd like to write:
public class MyVisitor extends DateAdjustBaseVisitor<LocalDate> {
#Override
public LocalDate visitOffsetRule(DateAdjustParser.OffsetRuleContext ctx) {
LocalDate contextDate = ???; //
return contextDate.plus(Integer.valueOf(ctx.num.toString()), ChronoUnit.valueOf(ctx.unit.toString()));
}
#Override
public LocalDate visitMinMaxRule(DateAdjustParser.MinMaxRuleContext ctx) {
LocalDate contextDate = ???; //
LocalDate left = this.visitChildren(ctx.left, contextDate);
LocalDate right = this.visitChildren(ctx.right, contextDate);
if(ctx.type.getText().equals("MIN")) {
return left.compareTo(right) > 0 ? left : right;
} else {
return left.compareTo(right) < 0 ? left : right;
}
}
}
here's my grammar:
grammar DateAdjust;
rootNode: offset+;
offset
: num=NUMBER unit=UNIT #OffsetRule
| type=( MIN | MAX ) '(' left=offset ',' right=offset ')' #MinMaxRule
;
UNIT: [dwmy]; //Days Weeks Months Years
NUMBER: [+-]?[0..9]+;
MAX: 'MAX';
MIN: 'MIN';
Not an Antlr-specific solution, but a typical DSL solution is to use a scoped state table (aka symbol table) to accumulate the results of an AST/CST walk.
See this answer for an implementation. Another exists in the Antlr repository.

Count the number of null value per column with pentaho

I've got a csv file that contain more than 60 columns and 2 000 000 lines, I'm trying to count the number of null value per variable (per column) then to do the sum of that new row to get the number total of null value in the entire csv. For example if we got this file in input:
We expect this other file in output:
I know how to count the number of null value per line but, I didn't figure out how to count the number of null value per column.
There has to be a better way to do this, but I made a really nasty JavaScript which does the job.
It has some problems for different column types, as it doesn't set the column type. (It should set all columns to integer, but I don't know if that is possible from JavaScript.)
You have to run Identify last row in a stream first, and save it to the column last (or change the script).
var nulls;
var seen;
if (!seen) {
// Initialize array
seen = 1;
nulls = [];
for (var i = 0; i < getInputRowMeta().size(); i++) {
nulls[i] = 0;
}
}
for (var i = 0; i < getInputRowMeta().size(); i++) {
if (row[i] == null) {
nulls[i] += 1;
}
// Hack to find empty strings
else if (getInputRowMeta().getValueMeta(i).getType() == 2 && row[i].length() == 0) {
nulls[i] += 1;
}
}
// Don't store any values
trans_Status = SKIP_TRANSFORMATION;
// Only store the nulls at the last row
if (last == true) {
putRow(nulls);
}
Please drag and drop below steps in to canvas.
step1: Add constants: create one variable called constant and value = 1
step2: Filter Rows: you have filter null values of all columns.
step3: Group by: here group by field constant variable
aggregates section we have to specify remaining columns like ct_inc.And type is Number of Values (N)
If you have any doubts feel free to ask.
skype_id : panabakavenkatesh