SQL 中基于公共 ID 的列值组合
Combination of Column Values in SQL Based on Common ID
感谢您的帮助!我正在使用 MS SQL Server 17 并尝试按 ID 分组并根据共享 ID 在第二列中查找常见配对。大多数其他问题涉及查找多列之间的任意组合。
这是一些示例数据:
/* Create sample data */
DROP TABLE IF EXISTS example
CREATE TABLE example (
PersonID int,
Place varchar(50)
)
INSERT INTO example (PersonID, Place)
VALUES (1, 'home'), (2, 'work'), (3, 'gym'), (1, 'grocery'), (1, 'home'), (2, 'gym'), (3, 'work'),
(4, 'school'), (2, 'gym'), (3, 'gym'), (4, 'home'), (4, 'school'), (4, 'work'), (5, 'bar')
SELECT * FROM example
Order by PersonID asc
每当 PersonID
有多于一行时,我希望以下列格式(对于 Sankey 图表)查看 Place
的常见配对。
from | to | count
____________________________
gym | gym | 2
gym | work | 2
school | school | 1
home | home | 1
school | work | 1
grocery | home | 1
一对可以是同一个地方,例如PersonID == 1
去了 'home'
两次,但我只需要从-到格式的两个配对。
到目前为止,我已经尝试了 STRING_AGG 函数,但我很难将其限制为双向配对。非常感谢您的帮助,如果这是一个之前已经解决的简单答案,我深表歉意。
尝试:
/* Next, let's try to make our Sankey data (from, to, count) */
DROP TABLE IF EXISTS temp_example
SELECT t.combination, COUNT(*) AS value
INTO temp_example
FROM (SELECT STRING_AGG(Place, ',') within group (order by Place) combination
FROM example
GROUP BY PersonID
HAVING COUNT(*) >= 2
) t
GROUP BY t.combination
ORDER BY value desc
首先,您需要另一列。一个可以用来识别这个人访问这些地方的顺序。 SQL 表是无序的,因此您插入数据的顺序不够。比如加个时间戳列什么的?
然后,使用 LAG() 找出每一行之前访问过的地方。之后就是一个简单的 GROUP BY。
WITH
lagged AS
(
SELECT
*,
LAG(place) OVER (PARTITION BY PersonID ORDER BY aTimestampOrSomething) AS prevPlace
FROM
example
)
SELECT
prevPlace,
place,
COUNT(*)
FROM
lagged
(对打字错误等表示歉意,我在 phone)
感谢您的帮助!我正在使用 MS SQL Server 17 并尝试按 ID 分组并根据共享 ID 在第二列中查找常见配对。大多数其他问题涉及查找多列之间的任意组合。
这是一些示例数据:
/* Create sample data */
DROP TABLE IF EXISTS example
CREATE TABLE example (
PersonID int,
Place varchar(50)
)
INSERT INTO example (PersonID, Place)
VALUES (1, 'home'), (2, 'work'), (3, 'gym'), (1, 'grocery'), (1, 'home'), (2, 'gym'), (3, 'work'),
(4, 'school'), (2, 'gym'), (3, 'gym'), (4, 'home'), (4, 'school'), (4, 'work'), (5, 'bar')
SELECT * FROM example
Order by PersonID asc
每当 PersonID
有多于一行时,我希望以下列格式(对于 Sankey 图表)查看 Place
的常见配对。
from | to | count
____________________________
gym | gym | 2
gym | work | 2
school | school | 1
home | home | 1
school | work | 1
grocery | home | 1
一对可以是同一个地方,例如PersonID == 1
去了 'home'
两次,但我只需要从-到格式的两个配对。
到目前为止,我已经尝试了 STRING_AGG 函数,但我很难将其限制为双向配对。非常感谢您的帮助,如果这是一个之前已经解决的简单答案,我深表歉意。
尝试:
/* Next, let's try to make our Sankey data (from, to, count) */
DROP TABLE IF EXISTS temp_example
SELECT t.combination, COUNT(*) AS value
INTO temp_example
FROM (SELECT STRING_AGG(Place, ',') within group (order by Place) combination
FROM example
GROUP BY PersonID
HAVING COUNT(*) >= 2
) t
GROUP BY t.combination
ORDER BY value desc
首先,您需要另一列。一个可以用来识别这个人访问这些地方的顺序。 SQL 表是无序的,因此您插入数据的顺序不够。比如加个时间戳列什么的?
然后,使用 LAG() 找出每一行之前访问过的地方。之后就是一个简单的 GROUP BY。
WITH
lagged AS
(
SELECT
*,
LAG(place) OVER (PARTITION BY PersonID ORDER BY aTimestampOrSomething) AS prevPlace
FROM
example
)
SELECT
prevPlace,
place,
COUNT(*)
FROM
lagged
(对打字错误等表示歉意,我在 phone)