SQL中的行上的累积列表操作

时间:2017-09-29 07:02:13

标签: sql sql-server

我有一个场景,我需要将特定日期的值列表与同一个人的前一天进行比较。而且每天我都需要保持连续两天的差异。

这是销售人员的数据,他们每天都会从他们城镇的整个房屋清单中找到几所房子。

以下是我的数据:

房屋

{
  "dependencies": {
    "async": "^2.5.0",
    "axios": "^0.16.2",
    "classnames": "^2.2.5",
    "date-diff": "^0.1.3",
    "jwt-decode": "^2.2.0",
    "lodash": "^4.17.4",
    "react": "^15.6.1",
    "react-bootstrap": "^0.31.2",
    "react-bootstrap-table": "^4.0.2",
    "react-dom": "^15.6.1",
    "react-redux": "^5.0.6",
    "react-router": "^4.2.0",
    "react-router-dom": "^4.2.2",
    "react-scripts": "1.0.12",
    "react-select": "^1.0.0-rc.5",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0",
    "shortid": "^2.2.8",
    "validator": "^8.1.0"
  },
  "scripts": {
    "start": "react-scripts-with-stylus start src/stylesheets/menu.styl",
    "build": "react-scripts-with-stylus build src/stylesheets/menu.styl",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  },
  "proxy": "http://localhost:8081",
  "devDependencies": {
    "babel": "^6.23.0",
    "babel-cli": "^6.24.1",
    "babel-core": "^6.25.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "create-react-app-stylus": "^1.1.1",
    "webpack": "^3.5.5"
  }
}

访问:

 Select Distinct House_id from tbl_houses;

现在,我有两个不同的表:

Select sales_person_id, Date, visited_house_id;

而且,销售人员访问的数据如下:

House_id    
1
2
3
4
5

销售人员可以访问已经访问过的房屋,并且多个销售人员可以在同一天访问同一栋房屋。对此没有限制。

并且,所需的输出如下:

sales_person_id  Date visited_house
1              12/6/16   1
1              12/6/16   2
2              12/6/16   1
2              13/6/16   3
3              12/6/16   3
1              13/6/16   1
1              13/6/16   3

我们如何在sql中实现这一目标?

2 个答案:

答案 0 :(得分:1)

对于SQL Server(您可以更改顶部的CTE以使用您喜欢的任何日期范围):

WITH cteDates
AS
(
    SELECT CAST(GETDATE() AS date) DT
    UNION
    SELECT CAST(GETDATE() - 1 AS date)
)

SELECT
    SP.sales_person_id
    , D.[DT] [Date]
    , '[' + LEFT(V.Visited, LEN(V.Visited) - 1) + ']' Visited
    , '[' + LEFT(NV.NotVisited, LEN(NV.NotVisited) - 1) + ']' Visited
FROM
    cteDates D
    CROSS JOIN (SELECT DISTINCT sales_person_id FROM tbl_visits) SP
    OUTER APPLY
    (
        SELECT
            CAST(
                (
                    SELECT CAST(visited_house_id AS varchar) + ','
                    FROM tbl_visits
                    WHERE
                        sales_person_id = SP.sales_person_id
                        AND [Date] = D.DT
                    ORDER BY visited_house_id
                    FOR XML PATH ('')
                )
            AS varchar) Visited
    ) V
    OUTER APPLY
    (
        SELECT
            CAST(
                (
                    SELECT CAST(House_id AS varchar) + ','
                    FROM tbl_houses
                    WHERE House_id NOT IN
                        (
                            SELECT visited_house_id
                            FROM tbl_visits
                            WHERE
                                sales_person_id = SP.sales_person_id
                                AND [Date] = D.DT
                        )
                    ORDER BY House_id
                    FOR XML PATH ('')
                )
            AS varchar) NotVisited
    ) NV
ORDER BY
    sales_person_id
    , [Date]

答案 1 :(得分:1)

请查看以下可以帮助您的小代码:

SELECT DISTINCT
       H.sales_person_id,
       H.Date,
       Visited_Houses = STUFF(
                             (
                                 SELECT ','+CONVERT(NVARCHAR(MAX), houseid)
                                 FROM history
                                 WHERE [sales_person_id] = H.sales_person_id
                                       AND [Date] = H.Date FOR XML PATH('')
                             ), 1, 1, '[')+']',
       Not_Visited_Houses = STUFF(
                                 (
                                     SELECT ','+CONVERT(NVARCHAR(MAX), TT.House_id)
                                     FROM
                                     (
                                         SELECT HS1.House_id,
                                                H1.sales_person_id
                                         FROM house HS1
                                              LEFT JOIN #history H1 ON H1.houseid = HS1.House_id
                                                                       AND H1.sales_person_id = H.sales_person_id AND H1.Date = H.Date 
                                     ) TT
                                     WHERE TT.sales_person_id IS NULL FOR XML PATH('')
                                 ), 1, 1, '[')+']'
FROM house HS
     INNER JOIN #history H ON H.houseid = HS.House_id;

期望输出:

sales_person_id Date       Visited_Houses   Not_Visited_Houses 
--------------- ---------- ---------------- -------------------
1               2016-06-12 [1,2]            [3,4,5]
1               2016-06-13 [1,3]            [2,4,5]
2               2016-06-12 [1]              [2,3,4,5]
2               2016-06-13 [3]              [1,2,4,5]
3               2016-06-12 [3]              [1,2,4,5]

注意:以上输出与您提供的数据相符。

希望,它会对你有帮助。