Identify the occurrence of more than one value for a combination of 2 Key Fields - multiple-records

I have a Microsoft SQL Server 2017 Table with a structure similar to this:
id | i_id | item_name | date1 | date2 | date3 | date4 | date5 |...
---+------+--------------+------------+------------+------------+------------+------------+---
1 | 1234 | item_a | 01/01/2019 | NULL | 01/03/2019 | NULL | NULL |...
1 | 1234 | item_a | NULL | 01/02/2019 | NULL | 01/04/2019 | 01/05/2019 |...
1 | 1234 | item_b | 01/10/2019 | 01/12/2019 | NULL | NULL | NULL |...
1 | 1234 | item_b | NULL | NULL | 01/15/2019 | NULL | NULL |...
1 | 1234 | item_b | NULL | NULL | NULL | 01/22/2019 | 01/27/2019 |...
2 | 1235 | item_a | 02/01/2019 | NULL | NULL | NULL | NULL |...
2 | 1235 | item_a | 02/02/2019 | NULL | NULL | 02/07/2019 | NULL |...
2 | 1235 | item_a | NULL | NULL | 02/05/2019 | NULL | NULL |...
2 | 1235 | item_b | 02/12/2019 | 02/14/2019 | 02/16/2019 | 02/20/2019 | 02/25/2019 |...
2 | 1235 | item_b | NULL | NULL | NULL | NULL | 02/26/2019 |...
3 | 1236 | item_a | 02/28/2019 | 03/01/2019 | NULL | NULL | NULL |...
3 | 1236 | item_a | NULL | NULL | 03/03/2019 | NULL | NULL |...
3 | 1236 | item_b | NULL | NULL | NULL | 03/05/2019 | NULL |...
3 | 1236 | item_b | NULL | NULL | NULL | 03/07/2019 | 03/10/2019 |...
I would like find out when a Date (not necessarily even the same date), is present for a combination of 'id' and 'i_id'.
For example all dates for 'id' 1234 are fine, as there is a single date for each combination of 'id' and 'i_id'. However, 'id' 1235 has 2 dates for the combination of 1235 and item_a under column 'date1'. Likewise, 'id' 1235 has 2 dates for the combination of 1235 and item_b under column 'date5'. Lastly, 'id' 1236 has 2 dates for the combination of 1236 and item_b under column 'date4'.
My need is to identify when such multiple records appear against each 'id' and 'i_id' combination and better still, obtain a count of how may times this occurs. If I can list just the records found with more than one date per 'id' and 'i_id' combination, then that would be ideal.
I'm still working at improving my SQL skills, so I'm not sure how the listing out of identified multiple records would best be structured, but perhaps a similar Table structure with just the identified multiple records listed.
Any assistance possible would be appreciated! Thanks.

Related

count() column in a row having specific value SQL

Rollno|24-4-2019| 25-4-2019 | 26-4-2019 | 27-4-2019 |tot.present]|tot.absent|
========================================================================
1 |Present | Absent | Present | Absent | ? | ?
2 |Present | Present | Present | Absent | ? | ?
3 |Present | Absent | Present | Absent | ? | ?
4 |Absent | Present | Present | Absent | ? | ?
5 |Present | Absent | Present | Absent | ? | ?
6 |Present | Present | Present | Absent |
7 |Present | Present | Present | Absent |
how to count the number of presents and absents for a specific rollno.

SQL/SSJS count events in timeline

I've got this two tables, representing Email send and open events:
TABLE1 (SENDS)
------------------------------------------------
| ReceiptId | JobId | SK | LogDate |
|-----------|-------|------|---------------------|
| 0000001 | 67789 | 4151 | 6/4/2018 3:21:48 AM |
|-----------|-------|------|---------------------|
| 0000002 | 67789 | 4151 | 6/4/2018 4:15:50 AM |
|-----------|-------|------|---------------------|
| 0000003 | 67789 | 4151 | 6/4/2018 9:42:04 AM |
|-----------|-------|------|---------------------|
| 0000004 | 67789 | 4151 | 6/4/2018 7:28:09 PM |
------------------------------------------------
TABLE2 (OPENS)
-------------------------------------
| JobId | SK | LogDate |
|-------|------|----------------------|
| 67789 | 4151 | 6/4/2018 7:31:42 AM |
|-------|------|----------------------|
| 67789 | 4151 | 6/4/2018 11:32:52 AM |
|-------|------|----------------------|
| 67789 | 4151 | 6/4/2018 2:12:03 PM |
|-------|------|----------------------|
| 67789 | 4151 | 6/4/2018 5:14:37 PM |
-------------------------------------
I need a SQL query or 'Server-Side Javascript Script' to get the count of Opens from TABLE2, where (TABLE1.JobId = TABLE2.JobId & TABLE1.SK = TABLE2.SK), grouped by TABLE1.ReceiptId, considering that the 'open' date will be allways higher than 'send' date, and the last email sent will be the first one on email inbox so will be the first one to be opened by the user.
So we need to match every 'Open' event with the last-sent unopened email, or with the last email sent if there is not any unopened email. 'Sent-Opened' logic is represented on this schema:
So the result table for the two tables above would be:
RESULT TABLE
-----------------------------------------
| ReceiptId | JobId | SK | Opens Count |
|-----------|-------|------|--------------|
| 0000001 | 67789 | 4151 | 1 |
|-----------|-------|------|--------------|
| 0000002 | 67789 | 4151 | 1 |
|-----------|-------|------|--------------|
| 0000003 | 67789 | 4151 | 2 |
|-----------|-------|------|--------------|
| 0000004 | 67789 | 4151 | 0 |
-----------------------------------------
EDIT: Marketing Cloud allows to use SSJS as well. Both SSJS or SQL could be a solution for me.
Thank you very much in advance.

MDX moving average by group

I'm using a software named spotfire in which I can set "custom expressions" with MDX. By the way, it isn't a requirement to know this software to answer this question. I expect general answers that could help other people as well even if they don't use spotfire.
I need to get the moving average for each group. I have a lot of groups, I can't make a table per group.
Below is an example of my table:
ID | GROUP | DATE | VALUE | MVG_AVG
------------------------------------------
a | A | 05/10 | 5 |
b | B | 05/10 | 4 |
c | A | 05/11 | 9 |
d | B | 05/11 | 7 |
e | B | 05/12 | 7 |
f | B | 05/13 | 7 |
g | A | 05/12 | 1 |
h | B | 05/14 | 1 |
I found the LastPeriods function, but I can't get it work for each group. I use n=3 for the function.
Here is the same table with expected results for moving average :
ID | GROUP | DATE | VALUE | MVG_AVG
------------------------------------------
a | A | 05/10 | 5 | 5 #because no previous value (for group A)
b | B | 05/10 | 4 | 4
c | A | 05/11 | 9 | 5 # =(5+9+1)/3
d | B | 05/11 | 7 | 6
e | B | 05/12 | 7 | 7
f | B | 05/13 | 7 | 5
g | A | 05/12 | 1 | 1 #because no next value (for group A)
h | B | 05/14 | 1 | 1
Here is my current custom expression in Spotfire, it doesn't take into account groups:
Sum([VALUE]) OVER (LastPeriods(3,[DATE])) / 3

JSPrit deliver sooner rather than later if at destination

Picking up multiple shipments, dropping off at central location. Problem is, sometimes the vehicle fills up and drops things off at central location, but only enough to finish the route. I'd like it to drop off everything it has if it is already at the depot.
See below, it delivers job #3 to the depot, leaving 4 other items in the vehicle (which has a capacity of 5). Then picks up the final thing, before delivering everything.
+--------------------------------------------------------------------------------------------------------------------------------+
| detailed solution |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 1 | vehicle | start | - | undef | 0 | 0 |
| 1 | vehicle | pickupShipment | 3 | 353 | 1253 | 3527 |
| 1 | vehicle | pickupShipment | 2 | 1253 | 2153 | 3527 |
| 1 | vehicle | pickupShipment | 4 | 2582 | 3482 | 7819 |
| 1 | vehicle | pickupShipment | 6 | 3801 | 4701 | 11012 |
| 1 | vehicle | pickupShipment | 5 | 4701 | 5601 | 11012 |
| 1 | vehicle | deliverShipment | 3 | 5945 | 6845 | 14455 |
| 1 | vehicle | pickupShipment | 1 | 7025 | 7925 | 16248 |
| 1 | vehicle | deliverShipment | 2 | 8104 | 9004 | 18042 |
| 1 | vehicle | deliverShipment | 4 | 9004 | 9904 | 18042 |
| 1 | vehicle | deliverShipment | 6 | 9904 | 10804 | 18042 |
| 1 | vehicle | deliverShipment | 5 | 10804 | 11704 | 18042 |
| 1 | vehicle | deliverShipment | 1 | 11704 | 12604 | 18042 |
| 1 | vehicle | end | - | 12604 | undef | 18042 |
+--------------------------------------------------------------------------------------------------------------------------------+
What's a good way to model some time or monetary cost that assures shipments do no spend any unnecessary time in the vehicle? All I want is an optimal route to pick up / drop off shipments.

Split joined result set to rows

Have a stored procedure which process records from certain tables. To store some result generated by join operation there is a temporary table.
Table A
+----+------+--------+
| id | name | number |
+----+------+--------+
| 1 | John | 123 |
| 2 | Tim | 567 |
| 3 | Bill | 789 |
| 4 | Jim | 345 |
+----+------+--------+
Table B
+----+------+--------+
| id | code | number |
+----+------+--------+
| 1 | LK | 123 |
| 2 | CN | 123 |
| 3 | BN | 789 |
| 4 | IN | 345 |
+----+------+--------+
Table Temp
+----+------+-----+------+--------+
| id | name | age | code | number |
+----+------+-----+------+--------+
| 1 | John | 54 | LK | 123 |
| 1 | John | 54 | CK | 123 |
| 3 | Bill | 26 | BN | 789 |
| 4 | Jim | 78 | IN | 345 |
+----+------+-----+------+--------+
Converted the table Temp result set to JSON.
[{"id":1,"name":"John","code":"LK","number":123}, {"id":2,"name":"John","code":"CK","number":123}, {"id":3,"name":"Bill","code":"BN","number":789}, {"id":4,"name":"Jim","code":"IN","number":345}]
I need to split the records to show it on view as below.
+------------+-----+------+--------+
| name | age | code | number |
+------------+-----+------+--------+
| John | 54 | | |
| | | LK | 123 |
| | | CK | 123 |
| Bill | 26 | | |
| | | BN | 789 |
| Jim | 78 | | |
| | | IN | 345 |
+------------+-----+------+--------+
[{"name":"John","age":54}, {"code":"LK","number":123}, {"code":"CK","number":123}, {"name":"Bill","age":26}, {"code":"BN","number":789}, {"name":"Jim","age":78}, {"code":"IN","number":345}]
What is an effective way, split the JSON or is it possible to generate such result set by querying table Temp in MySQL?
-- query wanted
select
if(name = #last_name, '', #last_name := name) as name,
if(age = #last_age, '', #last_age := age) as age,
code,
number
from
(
(select name, age, code, number from t)
union
(select distinct name, age, '', '' from t)
order by 1,2,3,4
) as t2 cross join (select #last_name := null, #last_age := null ) param;
Demo:
SQL:
-- data
create table t(id int, name char(20), age int, code char(20), number int);
insert into t values
( 1 , 'John' , 54 , 'LK' , 123 ),
( 1 , 'John' , 54 , 'CK' , 123 ),
( 3 , 'Bill' , 26 , 'BN' , 789 ),
( 4 , 'Jim' , 78 , 'IN' , 345 );
select * from t;
-- query wanted
select
if(name = #last_name, '', #last_name := name) as name,
if(age = #last_age, '', #last_age := age) as age,
code,
number
from
(
(select name, age, code, number from t)
union
(select distinct name, age, '', '' from t)
order by 1,2,3,4
) as t2 cross join (select #last_name := null, #last_age := null ) param
;
Output:
mysql> select * from t;
+------+------+------+------+--------+
| id | name | age | code | number |
+------+------+------+------+--------+
| 1 | John | 54 | LK | 123 |
| 1 | John | 54 | CK | 123 |
| 3 | Bill | 26 | BN | 789 |
| 4 | Jim | 78 | IN | 345 |
+------+------+------+------+--------+
4 rows in set (0.00 sec)
mysql> -- query wanted
mysql> select
-> if(name = #last_name, '', #last_name := name) as name,
-> if(age = #last_age, '', #last_age := age) as age,
-> code,
-> number
-> from
-> (
-> (select name, age, code, number from t)
-> union
-> (select distinct name, age, '', '' from t)
-> order by 1,2,3,4
-> ) as t2 cross join (select #last_name := null, #last_age := null ) param
-> ;
+------+------+------+--------+
| name | age | code | number |
+------+------+------+--------+
| Bill | 26 | | |
| | | BN | 789 |
| Jim | 78 | | |
| | | IN | 345 |
| John | 54 | | |
| | | CK | 123 |
| | | LK | 123 |
+------+------+------+--------+
7 rows in set (0.00 sec)
To me this seems more like a formatting the output question, rather than how to query the database, so I would rather use js on the client side to format the output in this way.
If I really wanted to use sql, then honestly, I would not use the temp table. I would rather create another query based on the 2 original tables with a union and order the final resultset. All you would have to do on the client side is to hide the id column:
(select id, name, age, null as code, null as number
from a)
union
(select id, null, null, code, number
from b)
order by id asc, name desc

Resources