maxDPD in last 6 months based on account - sql-server-2008

I have these columns: year_month (201403,201404,...201602,201603), ID_account (123,456,789), DPD (some numbers). For ID_account I need to find max_DPD in last 6 months as max_DPD. Like this (SSMS2008):
year_month || ID_account || DPD || max_DPD
----------------------------------------------------
201403 || 123 || 30 || 30
201404 || 123 || 0 || 30
201405 || 123 || 45 || 45
201406 || 123 || 1 || 45
201403 || 456 || 0 || 0
201404 || 456 || 12 || 12
201405 || 456 || 20 || 20
201406 || 456 || 0 || 20
201403 || 789 || 0 || 0

Related

Is there a way to concatenate a column of data if 2 other columns equal each other?

I am trying to find a way to concatenate a column of data if 2 other columns equal each other using google apps scrip. I have a formula that does this: "ARRAYFORMULA(TEXTJOIN(" | ",True,IF($A$2:A=D2,$B$2:$B,"")))" but it is very slow when looking at large data sets.
Here is what I have right now.
function my_concat() {
var ssraw = SpreadsheetApp.openById("1blPwXgg1DTJCTxmWikU5b0IZUgDxxQR13WbN7UI4_Yo");
var sheetraw = ssraw.getSheetByName("TEST");
var range = sheetraw.getRange("B2:B");
var data = range.getValues();
var last = range.getLastRow();
for(var i = 2; i < data.length; i++){
var range1 = sheetraw.getRange(i,1).getValue();
var range2 = sheetraw.getRange(i,4).getValues();
if(range1 == range2){
var data1 = (data[i] + " | " + data[i]);
sheetraw.getRange('C' + 2 + ':C' + last).setValue(data1);
}
}
}
Here is a link to my g-sheet https://docs.google.com/spreadsheets/d/1blPwXgg1DTJCTxmWikU5b0IZUgDxxQR13WbN7UI4_Yo/edit#gid=1418632603
When I ran the scrip I got looping information went line by line and concatenated what was in that line.
What I got: Chicken, Breast Strips - 10 Ounce (oz) | Chicken, Breast Strips - 10 Ounce (oz)
What I am expecting: Chicken, Breast Strips - 10 Ounce (oz) | Sauce, Ponzu - 6 Milliliter (ml) | Sauce, Sweet Thai Chili - 1 Ounce (oz) | Garlic, Unpeeled - 1 Clove | Lime - 1 Piece (pc) | Peanut Butter - 1.15 Ounce (oz) | Cucumber, Persian - 1 Piece (pc) | Korean Chili Flakes - 1 Teaspoon (tsp) | Cilantro - 0.25 Ounce (oz) | Quinoa, White - 0.5 Cup (c) | Stock Concentrate, Chicken - 9.6 Gram (g)
If A = D C = B | C
function my_concat() {
const ss = SpreadsheetApp.getActive();
const sh = ss.getSheetByName("TEST");
const data = sh.getRange("A2:D" + sh.getLastRow()).getValues();
let o = data.map((r, i) => {
if (r[0] == r[3]) {
r[2] = `${r[1]} | ${r[2]}`;//this doesn't work with table markdown
}
return [r[2]];
})
sh.getRange(2,3,o.length,o[0].length).setValues(o)
}
Data Before:
A
B
C
D
1
COL1
COL2
COL3
COL4
2
8
18
2
13
3
17
18
8
17
4
2
0
6
2
5
2
10
13
2
6
3
18
6
3
7
6
5
15
18
8
5
12
4
10
9
2
12
16
10
10
2
17
3
17
After:
A
B
C
D
1
COL1
COL2
COL3
COL4
2
8
18
2
13
3
17
18
18 , 8
17
4
2
0
0 , 6
2
5
2
10
10 , 13
2
6
3
18
18 , 6
3
7
6
5
15
18
8
5
12
4
10
9
2
12
16
10
10
2
17
3
17
I modified the code a bit to use commas so it would work with table markdown

Calculations for time elapsed in days

I have a spreadsheet with multiple sheets each sheet has the same layout with Date in column "A" and Time Elapsed in column "P" I need to calculate days between column A and today on all four sheets. If checkbox in column "N" is set to true then instead calculate column "O" from "A".
So far I have been able to code this bit but, need help getting over the hurdle.
function getDateDifference(event) {
var ss = event.source;
var s = ss.getSheetByName('Alpha'); // I need this to run on all four pages
var r = event.source.getActiveRange();
var startDate = sheet.getRange(3,1).getValue();
var endDate = new Date();
var duration = (endDate - startDate)
var r = event.source.getActiveRange();
if (r.getColumn() == 14 && r.getValue() == true) {
var endDate = sheet.getRange(3, 15);
var duration = (endDate - startDate);
sheet.getRange(3, 16).setValue(duration);
}
else {sheet.getRange(3, 16).setValue(duration);}
}
Example sheet for reference
https://docs.google.com/spreadsheets/d/1OKFoS17le-Y5SAOecoLE4EJxiKqKVjRLRHtMzwHNwxM/edit?usp=sharing
Calculate Diff in Days for selected sheets
function calcdiffindays() {
const ss = SpreadsheetApp.getActive();
const incl = ['Alpha', 'Sheet2', 'Sheet3'];//Add the desired sheet names
const dt = new Date();
const dtv = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());
ss.getSheets().filter(sh => ~incl.indexOf(sh.getName())).forEach(s => {
s.getRange(3, 1, s.getLastRow() - 2, s.getLastColumn()).getValues().forEach((r, i) => {
if (r[13] == true) {
let d = new Date(r[0]);
let dv = new Date(d.getFullYear(), d.getMonth(), d.getDate());
s.getRange(i + 3, 15).setValue(DiffInDays(dtv, dv));
}
})
})
}
function DiffInDays(Day1,Day2) {
if(Day1 && Day2 && (Object.prototype.toString.call(Day1) === '[object Date]') && (Object.prototype.toString.call(Day2) === '[object Date]')) {
var day=86400000;
var t1=new Date(Day1).valueOf();
var t2=new Date(Day2).valueOf();
var d=Math.abs(t2-t1);
var days=Math.floor(d/day);
//Logger.log(days);
return days;
} else {
throw 'Invalid Inputs';
}
}
Test Sheet:
COL1
COL2
COL3
COL4
COL5
COL6
COL7
COL8
COL9
COL10
COL11
COL12
COL13
COL14
COL15
7/1/2022
2
3
4
5
6
7
8
9
10
11
12
13
TRUE
3
7/2/2022
3
4
5
6
7
8
9
10
11
12
13
14
TRUE
4
7/3/2022
4
5
6
7
8
9
10
11
12
13
14
15
TRUE
5
7/4/2022
5
6
7
8
9
10
11
12
13
14
15
16
TRUE
6
7/5/2022
6
7
8
9
10
11
12
13
14
15
16
17
TRUE
7
7/6/2022
7
8
9
10
11
12
13
14
15
16
17
18
TRUE
8
7/7/2022
8
9
10
11
12
13
14
15
16
17
18
19
TRUE
9
7/8/2022
9
10
11
12
13
14
15
16
17
18
19
20
TRUE
10
7/9/2022
10
11
12
13
14
15
16
17
18
19
20
21
TRUE
11
7/10/2022
11
12
13
14
15
16
17
18
19
20
21
22
TRUE
12
7/11/2022
12
13
14
15
16
17
18
19
20
21
22
23
TRUE
13
7/12/2022
13
14
15
16
17
18
19
20
21
22
23
24
TRUE
14
7/13/2022
14
15
16
17
18
19
20
21
22
23
24
25
TRUE
15
7/14/2022
15
16
17
18
19
20
21
22
23
24
25
26
TRUE
16
7/15/2022
16
17
18
19
20
21
22
23
24
25
26
27
FALSE
7/16/2022
17
18
19
20
21
22
23
24
25
26
27
28
TRUE
18
7/17/2022
18
19
20
21
22
23
24
25
26
27
28
29
FALSE
7/18/2022
19
20
21
22
23
24
25
26
27
28
29
30
TRUE
20
7/19/2022
20
21
22
23
24
25
26
27
28
29
30
31
FALSE
7/20/2022
21
22
23
24
25
26
27
28
29
30
31
32
TRUE
22
You appeared to be attempting to use a trigger. However, you did not specify a trigger and there were no triggers defined in your spreadsheet. So I went without triggers.
An onEdit Version:
function onEdit(e) {
const sh = e.range.getSheet();
const incl = ['Alpha', 'Sheet2', 'Sheet3'];//Add the desired sheet names
const idx = incl.indexOf(sh.getName())
if (~idx && e.range.columnStart == 14 && e.range.rowStart > 2 && e.value == "TRUE") {
const dt = new Date();
const dtv = new Date(dt.getFullYear(), dt.getMonth(), dt.getDate());
let d = new Date(sh.getRange(e.range.rowStart, 1).getValue());
let dv = new Date(d.getFullYear(), d.getMonth(), d.getDate());
e.range.offset(0, 1).setValue(DiffInDays(dtv, dv));
}
}
To insert timestamps in column O when the checkboxes in column N are ticked, use a timestamping script such as yetAnotherTimestamp_ with these parameters:
// [START modifiable parameters]
{
sheetName: /^(Alpha|Beta|Charlie|Delta)$/i,
watchColumn: ['N'],
stampColumn: ['O'],
watchRowStart: 3,
watchRowEnd: +Infinity,
timestampFormat: 'yyyy-MM-dd',
overwriteTimestamp: true,
eraseTimestampOnDelete: true,
},
// [END modifiable parameters]
Then put this formula in cell P2:
=arrayformula(
{
"Days Elapsed";
if( N3:N = "Yes", O3:O - A3:A, iferror(1/0) )
}
)
The formula will give the number of days between the timestamp and the form submission in the rows where a checkbox is ticked.

The number of matches between two rows mysql

So, this is the challenge:
I have two tables:
Etalon:
+-----+-----+-----+-----+----+
| e1 | e2 | e3 | e4 | e5 |
+-----+-----+-----+-----+----+
| 01 | 02 | 03 | 04 | 05 |
+-----+-----+-----+-----+----+
And Candidates:
+-----+----+-----+-----+-----+----+----+
| ID | c1 | c2 | c3 | c4 | c5 | nn |
+-----+----+-----+-----+-----+----+----+
| 00 | 03 | 08 | 02 | 01 | 06 | ** |
+-----+----+-----+-----+-----+----+----+
| 01 | 05 | 04 | 03 | 02 | 01 | ** |
+-----+----+-----+-----+-----+----+----+
| 02 | 06 | 07 | 08 | 09 | 10 | ** |
+-----+----+-----+-----+-----+----+----+
| 03 | 08 | 06 | 09 | 02 | 07 | ** |
+-----+----+-----+-----+-----+----+----+
What request should I use, to find and save (in nn column) the number of matches between two rows (e1, e2, e3, e4, e5 and c1, c2, c3, c4, c5) for each row in table candidate?
Should be the next result:
Candidates:
|-----|----|-----|-----|-----|-----|----|
| ID | c1 | c2 | c3 | c4 | c5 | nn |
|-----|----|-----|-----|-----|-----|----|
| 00 | 03 | 08 | 02 | 01 | 06 | 03 |
|-----|----|-----|-----|-----|-----|----|
| 01 | 05 | 04 | 03 | 02 | 01 | 05 |
|-----|----|-----|-----|-----|-----|----|
| 02 | 06 | 07 | 08 | 09 | 10 | 00 |
|-----|----|-----|-----|-----|-----|----|
| 03 | 08 | 06 | 09 | 02 | 07 | 01 |
|-----|----|-----|-----|-----|-----|----|
The result for nn is:
0 - no matches
1,2,3,4,5 - numbers of matches
How can I achieve that?
The objective is to establish a maximal partial matching between the master row and each row of the client table without regard to the respective column identities.
The idea is to abstract away from the column ids by representing the column contents in another way. As you indicated that the value domain is {1, ..., 10}, one may choose the first 10 prime numbers {p_1, ...,p_10} = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 }, mapping i to p_i. The comparisons will be based on the product of the mapped column values. This approach exploits the uniqueness of prime factorization, ie. every positive integer factorizes into a unique multi-set of prime numbers.
A one-pass standalone sql update statement is rather cumbersome to write down, therefore we create a temporary table that contains the products of the mapped values:
CREATE TEMPORARY TABLE t_pp (
id NUMBER
, mp_candidates NUMBER
, mp_etalon NUMBER
, nn NUMBER
);
INSERT INTO t_pp ( id, mp_candidates, mp_etalon )
SELECT id
, CASE c1
WHEN 1 THEN 2
WHEN 2 THEN 3
WHEN 3 THEN 5
WHEN 4 THEN 7
WHEN 5 THEN 11
WHEN 6 THEN 13
WHEN 7 THEN 17
WHEN 8 THEN 19
WHEN 9 THEN 23
WHEN 10 THEN 29
ELSE 31
END
* CASE c2 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE c3 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE c4 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE c5 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
mp_candidates
, CASE e1
WHEN 1 THEN 2
WHEN 2 THEN 3
WHEN 3 THEN 5
WHEN 4 THEN 7
WHEN 5 THEN 11
WHEN 6 THEN 13
WHEN 7 THEN 17
WHEN 8 THEN 19
WHEN 9 THEN 23
WHEN 10 THEN 29
ELSE 31
END
* CASE e2 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE e3 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE e4 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
* CASE e5 WHEN 2 THEN 3 WHEN 3 THEN 5 WHEN 4 THEN 7 WHEN 5 THEN 11 WHEN 6 THEN 13 WHEN 7 THEN 17 WHEN 8 THEN 19 WHEN 9 THEN 23 WHEN 10 THEN 29 ELSE 31 END
mp_etalon
, 0 nn
FROM candidates
CROSS JOIN etalon
;
Now for pass #2 - counting matches:
UPDATE t_pp
SET nn =
CASE WHEN mp_candidates MOD 2 = 0 AND mp_etalon MOD 2 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 3 = 0 AND mp_etalon MOD 3 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 5 = 0 AND mp_etalon MOD 5 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 7 = 0 AND mp_etalon MOD 7 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 11 = 0 AND mp_etalon MOD 11 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 13 = 0 AND mp_etalon MOD 13 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 17 = 0 AND mp_etalon MOD 17 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 19 = 0 AND mp_etalon MOD 19 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 23 = 0 AND mp_etalon MOD 23 = 0 THEN 1 ELSE 0 END
+ CASE WHEN mp_candidates MOD 29 = 0 AND mp_etalon MOD 29 = 0 THEN 1 ELSE 0 END
;
Finally, transferring the results to the original table and cleaning up:
UPDATE candidates c
set nn = ( SELECT p.nn FROM t_pp p WHERE p.id = c.id )
;
DELETE TEMPORARY TABLE t_pp;
Some more notes:
The scheme as shown assumes that cell values are unique within each row. However, it can easily be extended to allow formultiple occurrences of values.
In principle, this can be wrapped in a single sql statement - for obvious reasons this is not recommended.
Rdbms other than mysql follow the sql standard and provide the WITH clause that obviates the need for a temporaray table.
The value 31 in the ELSE branch of the above CASE expressions is a dummy value.

incrementing records with same date

i have to autonumer fields with same date an i honestly have no idea how to :(
(what i have)
ID|| DATE || PID
1 || 2014 01 01 || 1
2 || 2014 01 01 || 2
3 || 2014 01 02 || 3
4 || 2014 01 02 || 4
(what i need)
ID|| DATE || PID
1 || 2014 01 01 || 1
2 || 2014 01 01 || 2
3 || 2014 01 02 || 1
4 || 2014 01 02 || 2
If you want to add a new record and If ID is auto increment:
INSERT INTO table_name(DATE, PID)
VALUES ( [YOUR_DATE], (SELECT MAX(PID) from table_name where DATE=[YOUR_DATE]) + 1)
Change [YOUR_DATE] with the date you want to insert

MySQL - Ignoring values at the beginning and end of a table, with group and ordering

Hopefully someone can help with this... I have a table that contains the following data:
Table Data
|| *id* || *showid* || *presenterid* || *hourofday* || *dayofweek*
|| 24 || 53 || 91 || 23 || 5
|| 23 || 53 || 91 || 22 || 5
|| 22 || 52 || 90 || 21 || 5
|| 21 || 52 || 90 || 20 || 5
|| 20 || 52 || 90 || 19 || 5
|| 19 || 63 || 88 || 18 || 5
|| 18 || 71 || 86 || 17 || 5
|| 17 || 71 || 86 || 16 || 5
|| 16 || 71 || 86 || 15 || 5
|| 15 || 71 || 86 || 14 || 5
|| 14 || 49 || 75 || 13 || 5
|| 13 || 49 || 75 || 12 || 5
|| 12 || 49 || 75 || 11 || 5
|| 11 || 49 || 75 || 10 || 5
|| 10 || 48 || 74 || 9 || 5
|| 9 || 48 || 74 || 8 || 5
|| 8 || 48 || 74 || 7 || 5
|| 7 || 48 || 74 || 6 || 5
|| 6 || 54 || 91 || 5 || 5
|| 5 || 54 || 91 || 4 || 5
|| 4 || 54 || 91 || 3 || 5
|| 3 || 54 || 91 || 2 || 5
|| 2 || 54 || 91 || 1 || 5
|| 1 || 70 || 87 || 0 || 5
HourofDay is a value between 0 and 23 which relates to the Hour of the Day (PHP Date), with Dayofweek being the number equivalent of the day of the week (PHP Date).
I currently have a query which groups all the data by Show ID and Presenter ID and then returns the data ordered by hourofday. With the group showing the first entry with the lowest hourofday value
SQL QUERY
SELECT
*
FROM
(
SELECT
*
FROM
schedule_timings
ORDER BY
hourofday ASC
) as my_table_tmp
GROUP BY
showid,
presenterid
ORDER BY
hourofday ASC
Query Result:
|| *id* || *showid* || *presenterid* || *hourofday* || *dayofweek*
|| 1 || 53 || 91 || 0 || 5
|| 2 || 54 || 91 || 1 || 5
|| 7 || 48 || 74 || 6 || 5
|| 11 || 49 || 75 || 10 || 5
|| 15 || 71 || 86 || 14 || 5
|| 19 || 63 || 88 || 18 || 5
|| 20 || 52 || 90 || 19 || 5
Now this pulls the data as would be expected. However there are values that roll over:
|| *id* || *showid* || *presenterid* || *hourofday* || *dayofweek*
|| 24 || 53 || 91 || 23 || 5
|| 23 || 53 || 91 || 22 || 5
|| 1 || 70 || 87 || 0 || 5
And the group by is grouping all of these together. But as they are seperated by other values and the hour of the day is not sequential i need these to show up seperatly.
I have had a look round and found some sequential grouping solutions (http://www.artfulsoftware.com/infotree/queries.php, search "Find blocks of unused numbers")
but i have no clue about how to best implement them.
I do not mind having to do the grouping all Server Side, but would prefer not to.
Cheers in Advance
Alan
You aren't using any aggregate functions, so I don't think you actually need Group by. Instead, I think what would work better would be a single select with multiple order bys. I think you would get the results you're looking for with:
SELECT
*
FROM
schedule_timings
ORDER BY
show_id, presenter_id, hourofday ASC