SQL中基于Common ID的列值组合
Posted
技术标签:
【中文标题】SQL中基于Common ID的列值组合【英文标题】:Combination of Column Values in SQL Based on Common ID 【发布时间】:2020-12-18 08:08:08 【问题描述】:感谢您的帮助!我正在使用 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
有不止一行时,我希望以以下格式查看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 表没有隐式顺序。如果您想强制执行一个命令(如“from 和 'to' 所暗示的那样),您需要至少包含一个可用于派生该排序的其他列。 【参考方案1】:首先,您需要另一列。一种可用于识别该人访问这些地点的顺序。 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
(对错别字等道歉,我正在打电话)
【讨论】:
谢谢!很抱歉我刚加入后无法投票。以上是关于SQL中基于Common ID的列值组合的主要内容,如果未能解决你的问题,请参考以下文章