R Smith, on Monday, January 13, 2020 05:25 PM, wrote...​
> On 2020/01/13 9:42 PM, Jose Isaias Cabrera wrote:​
> > Greetings!​
> >​
> > Please observe the following,​
> >​
> >​
> > create table t (n INTEGER PRIMARY KEY, a, b, c, d, e, idate);​
> >​
> > insert into t (a, b, c, d, e, idate) values ('p001', 1, 2, 'n', 4, 
> > '2019-02-11');​
> >​
> > ...​
> >​
> > p001|1|10|column b changed on 2019-02-12​
> > p002|2|4|column c changed on 2019-02-12​
> > p003|n|y|column d changed on 2019-02-12​
> > sqlite>​
> >​
> > What I would like is to cover all of the dates in the same command, so that 
> > the output is this,​
> >​
> > p001|1|10|column b changed on 2019-02-12​
> > p002|2|4|column c changed on 2019-02-12​
> > p003|n|y|column d changed on 2019-02-12​
> > p004|4|5|column b changed on 2019-02-13​
> > p004|2|3|column c changed on 2019-02-13​
> > p004|y|n|column d changed on 2019-02-13​
> > p005|2|3|column c changed on 2019-02-13​
> > p005|4|8|column e changed on 2019-02-13​
> >​
> > Yes, I know I can get all the dates and build the SQL as I did above, but 
> > is there a way to do this in one call?  Thanks for the help.​
> ​
> ​
> Of course there is :)​
> ​
> Many questions are not clear though.​
> I assumed you are only interested in day-on-day changes, because in many ​
> days there can be many different values, if you measure them all against ​
> the last day, it will look like many changes between day X and the last ​
> day, when really you are probably interested only in the change from one ​
> day to the next day.​
> ​
> I also assumed that the days you will give as the input, let's call that ​
> min date and max date of the report, will refer to the days on which ​
> changed happened - which seems obvious, but the query must change if it ​
> is not the case.​
> ​
> Anyway, here is the SQL to achieve it. I made 2 queries, one in which it ​
> just gets the min and max from your data, and the other in which you can ​
> specify the min and max date. I guess the second one will be more what ​
> you want - the nice t hing is your calling program only needs to adjust ​
> those two values once, nowhere else:​
> ​
> (PS: I left the whole generated output in so you can see at the bottom, ​
> those errors are not errors, but just informing us that SQLite is ​
> creating indexes for those CTE tables, which is great and means this ​
> should be relatively fast  on large datasets even.)​
> ​
> ​
>    -- SQLite version 3.30.1  [ Release: 2019-10-10 ]  on SQLitespeed ​
> version 2.1.3.11.​
> ​
>    -- Script Items: 4          Parameter Count: 0​
>    -- 2020-01-14 00:08:17.875  |  [Info]       Script Initialized, ​
> Started executing...​
>    -- ​
> ================================================================================================​
> ​
> create table t (n INTEGER PRIMARY KEY, a, b, c, d, e, idate);​
> ​
> insert into t (a, b, c, d, e, idate) values​
>   ('p001', 1, 2, 'n', 4, '2019-02-11')​
> ,('p002', 2, 2, 'n', 4, '2019-02-11')​
> ,('p003', 3, 2, 'n', 4, '2019-02-11')​
> ,('p004', 4, 2, 'y', 4, '2019-02-11')​
> ,('p005', 5, 2, 'y', 4, '2019-02-11')​
> ,('p001',10, 2, 'n', 4, '2019-02-12')​
> ,('p002', 2, 4, 'n', 4, '2019-02-12')​
> ,('p003', 3, 2, 'y', 4, '2019-02-12')​
> ,('p004', 4, 2, 'y', 4, '2019-02-12')​
> ,('p005', 5, 2, 'y', 4, '2019-02-12')​
> ,('p001',10, 2, 'n', 4, '2019-02-13')​
> ,('p002', 2, 4, 'n', 4, '2019-02-13')​
> ,('p003', 3, 2, 'y', 4, '2019-02-13')​
> ,('p004', 5, 3, 'n', 4, '2019-02-13')​
> ,('p005', 5, 3, 'y', 8, '2019-02-13')​
> ;​
> ​
> -- This version guesses the min and max dates...​
> WITH DSpan(minDate, maxDate) AS (​
>    SELECT MIN(idate), MAX(idate) FROM t GROUP BY idate​
> ), DDays(dayOldDate, dayNewDate) AS (​
>    SELECT minDate, date(minDate,'+1 day') FROM DSpan​
>    UNION ALL​
>    SELECT dayNewDate, date(dayNewDate,'+1 day') FROM DDays, DSpan WHERE ​
> DDays.dayNewDate, on ​
> ), Chg(a, idate, col, oldVal, newVal) AS (​
>    SELECT DISTINCT tNew.a, tNew.idate, 'b', tOld.b,tNew.b​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.b != tOld.b​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'c', tOld.c,tNew.c​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.c != tOld.c​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'd', tOld.d,tNew.d​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.d != tOld.d​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'e', tOld.e,tNew.e​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.e != tOld.e​
> )​
> SELECT Chg.a, Chg.oldVal, Chg.newVal,​
>         ('Column '||Chg.col||' changed on '||Chg.idate||' from ​
> '||Chg.oldVal||' to '||Chg.newVal||'.') AS Change​
>    FROM Chg​
>   ORDER BY Chg.a, Chg.idate​
> ;​
> ​
> ​
>    -- a    | oldVal | newVal | Change​
>    -- ---- | ------ | ------ | --------------------------------------------​
>    -- p001 |    1   |   10   | Column b changed on 2019-02-12 from 1 to 10.​
>    -- p002 |    2   |    4   | Column c changed on 2019-02-12 from 2 to 4.​
>    -- p003 |    n   |    y   | Column d changed on 2019-02-12 from n to y.​
>    -- p004 |    4   |    5   | Column b changed on 2019-02-13 from 4 to 5.​
>    -- p004 |    2   |    3   | Column c changed on 2019-02-13 from 2 to 3.​
>    -- p004 |    y   |    n   | Column d changed on 2019-02-13 from y to n.​
>    -- p005 |    2   |    3   | Column c changed on 2019-02-13 from 2 to 3.​
>    -- p005 |    4   |    8   | Column e changed on 2019-02-13 from 4 to 8.​
> ​
> ​
> -- This version let's you set it, I chose the last two of the days here.​
> WITH DSpan(minDate, maxDate) AS (​
>    SELECT '2019-02-12', '2019-02-13'​
> ), DDays(dayOldDate, dayNewDate) AS (​
>    SELECT minDate, date(minDate,'+1 day') FROM DSpan​
>    UNION ALL​
>    SELECT dayNewDate, date(dayNewDate,'+1 day') FROM DDays, DSpan WHERE ​
> DDays.dayNewDate, on ​
> ), Chg(a, idate, col, oldVal, newVal) AS (​
>    SELECT DISTINCT tNew.a, tNew.idate, 'b', tOld.b,tNew.b​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.b != tOld.b​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'c', tOld.c,tNew.c​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.c != tOld.c​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'd', tOld.d,tNew.d​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.d != tOld.d​
> UNION ALL​
>    SELECT DISTINCT tNew.a, tNew.idate, 'e', tOld.e,tNew.e​
>      FROM DDays​
>      JOIN t AS tOld ON tOld.idate = DDays.dayoldDate​
>      JOIN t AS tNew ON tNew.idate = DDays.dayNewDate​
>     WHERE tNew.a = tOld.a AND tNew.e != tOld.e​
> )​
> SELECT Chg.a, Chg.oldVal, Chg.newVal,​
>         ('Column '||Chg.col||' changed on '||Chg.idate||' from ​
> '||Chg.oldVal||' to '||Chg.newVal||'.') AS Change​
>    FROM Chg​
>   ORDER BY Chg.a, Chg.idate​
> ;​
> ​
> ​
>    -- a    | oldVal | newVal | Change​
>    -- ---- | ------ | ------ | -------------------------------------------​
>    -- p004 |    4   |    5   | Column b changed on 2019-02-13 from 4 to 5.​
>    -- p004 |    2   |    3   | Column c changed on 2019-02-13 from 2 to 3.​
>    -- p004 |    y   |    n   | Column d changed on 2019-02-13 from y to n.​
>    -- p005 |    2   |    3   | Column c changed on 2019-02-13 from 2 to 3.​
>    -- p005 |    4   |    8   | Column e changed on 2019-02-13 from 4 to 8.​
> ​
>    --   Script Stats: Total Script Execution Time:     0d 00h 00m and ​
> 00.050s​
>    --                 Total Script Query Time:         0d 00h 00m and ​
> 00.009s​
>    --                 Total Database Rows Changed:     15​
>    --                 Total Virtual-Machine Steps: 6990​
>    --                 Last executed Item Index:        4​
>    --                 Last Script Error:​
>    -- ​
> ------------------------------------------------------------------------------------------------​
> ​
>    -- 2020-01-14 00:08:17.900  |  [Success]    Script Success.​
>    -- 2020-01-14 00:08:17.901  |  [Success]    Transaction Rolled back.​
>    -- -------  DB-Engine Logs (Contains logged information from all DB ​
> connections during run)  ------​
>    -- [2020-01-14 00:08:17.826] APPLICATION : Script ​
> E:\Documents\SQLiteAutoScript.sql started at 00:08:17.826 on 14 January.​
>    -- [2020-01-14 00:08:17.890] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.890] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.890] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.890] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.890] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.891] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.891] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.891] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on t(a)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on ​
> DDays(dayOldDate)​
>    -- [2020-01-14 00:08:17.896] ERROR (284) : automatic index on t(a)​
>    -- ​
​
Wow!  Thanks for this.  I had not thought about your questions.  My boss said, 
I need to know all the changes per project whenever it happened. So,... I will 
have to revise my thinking, but I have enough with your help to continue. I am 
going to have to reload SQLitespeed, and try it again. :-)  Thanks.​
​
josé
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to