Recursive SQL method to add to auto increment

I am a SQL starter. I have a problem which is quite complicated for me and the story is quite long.

  • The first table is the users table that stores information about the user.
  • The second table is the transactions table that stores the user's transaction.
create table nl_users
(
    userid      int not null primary key,
    datejoin    datetime not null,
    referrer    int not null,
    pointsbal   float not null default 0
)

create table nl_loyaltrans
(
    loyaltransid        varchar(15) not null primary key,
    userid              int not null,
    datetran            datetime not null,
    loyalprogid         varchar(20) not null,
    loyalruleid         varchar(20) not null,
    trantype            char(1) not null,
    trandescp           varchar(100) null,
    points              int not null,
)

insert into nl_users values (79, GETDATE(), 0, 0)
insert into nl_users values (80, GETDATE(), 77, 0)
insert into nl_users values (77, GETDATE(), 5, 0)
insert into nl_users values (5, GETDATE(), 0, 0)

insert into nl_loyaltrans values ('2017052300001', 79, GETDATE(), 'SOCINVEST', 'POSTMSG', 'E', 'Earned Points', 5)
insert into nl_loyaltrans values ('2017052300003', 80, GETDATE(), 'SOCINVEST', 'POSTMSG', 'E', 'Earned Points', 5)

      

The operation I am trying to achieve, I will give directions to the users who are "posting" and ALL ITS corresponding referrers . For each of the referrers, the result is less than the previous ones.

For example: --user 5> 77> 80

If user 80 earned 5 points,
user 77 earns 4 points and
user 5 earns 3 points

I have made a recursive output of my desired result, but I cannot tell that the referrer is associated with their child.

Points assigned to each TIER referrer, and the direct person is maintained by another table. In this table there is a key of the logotype, loyalty and rule, which should know which points should be assigned to the referrer for the points received by their child.

create table nl_loyalruledet
(
    loyalprogid     varchar(20) not null,
    loyalruleid     varchar(20) not null,
    rulelevel       int not null,
    methodtype      char(1) not null,
    flat            float not null default 0
)

      

Here's my request:

;WITH parents
AS (
    SELECT u.userid
        ,u.referrer
        ,lt.loyalprogid
        ,lt.loyalruleid
        ,cast(1 AS INT) AS rulelevel
    FROM nl_loyaltrans lt
    LEFT JOIN nl_users u ON lt.userid = u.userid

    UNION ALL

    SELECT c.userid
        ,c.referrer
        ,CAST(loyalprogid AS VARCHAR(20))
        ,CAST(loyalruleid AS VARCHAR(20))
        ,cast((
                row_number() OVER (
                    ORDER BY c.userid
                    ) + 1
                ) AS INT) AS rulelevel
    FROM nl_users c
    INNER JOIN parents p ON p.referrer = c.userid -- this is the recursion
    )
SELECT *
FROM parents

      

desired result ->

userid  referrer loyalprogid loyalruleid rulelevel  points
79      0        SOCINVEST   POSTMSG     1          5
80      77       SOCINVEST   POSTMSG     1          5
77      5        SOCINVEST   POSTMSG     2          4
5       0        SOCINVEST   POSTMSG     3          3

      

I can get points from joining nl_loyalruledet to the result set.

I cannot get the correct level of rules, because of its recursive method I guess.

+3


source to share


1 answer


Try this below. I used dateran column for ordering.

For complexity, I added another entry to nl_loyaltrans.

insert into nl_loyaltrans 
values ('2017052300004', 77, GETDATE(), 'SOCINVEST', 'POSTMSG', 'E', 'Earned Points', 6)

      

Now click next query



;WITH parents
AS (
    SELECT u.userid
        ,u.referrer
        ,lt.loyalprogid
        ,lt.loyalruleid
        ,cast(1 AS INT) AS rulelevel
        ,lt.datetran
        ,LT.points
    FROM nl_loyaltrans lt
    LEFT JOIN nl_users u ON lt.userid = u.userid

    UNION ALL

    SELECT c.userid
        ,c.referrer
        ,CAST(loyalprogid AS VARCHAR(20))
        ,CAST(loyalruleid AS VARCHAR(20))
        , P.rulelevel +1
        ,P.datetran
        ,p.points-1
    FROM nl_users c
    INNER JOIN parents p ON p.referrer = c.userid -- this is the recursion
    )
SELECT userid,referrer,loyalprogid,loyalruleid,rulelevel,points
FROM parents
ORDER BY datetran , rulelevel

      

Results:

+--------+----------+-------------+-------------+-----------+--------+
| userid | referrer | loyalprogid | loyalruleid | rulelevel | points |
+--------+----------+-------------+-------------+-----------+--------+
|     79 |        0 | SOCINVEST   | POSTMSG     |         1 |      5 |
|     80 |       77 | SOCINVEST   | POSTMSG     |         1 |      5 |
|     77 |        5 | SOCINVEST   | POSTMSG     |         2 |      4 |
|      5 |        0 | SOCINVEST   | POSTMSG     |         3 |      3 |
|     77 |        5 | SOCINVEST   | POSTMSG     |         1 |      6 |
|      5 |        0 | SOCINVEST   | POSTMSG     |         2 |      5 |
+--------+----------+-------------+-------------+-----------+--------+

      

+2


source







All Articles