我正在尝试根据日期
从单个列中提取父和子ID Cust_id ID Date
75407014 603 2018-04-27
79807014 603 2018-04-30
75407016 604 2018-04-23
79807016 604 2018-04-30
75407018 605 2018-04-24
79807018 605 2018-04-30
75407020 606 2018-04-24
79807020 606 2018-04-30
75407014 608 2018-04-27
我想排除id = 608,因为只有一行,我的执行输出引用父和子id
Select Row_number () over (partition by Cust_id, id order by date ) rn
我的预期输出:
Parent_id Child_id
75407014 79807014
75407016 79807016
75407018 79807018
75407020 79807020
因此,第一个日期的Cust_id将是parent_id,下一个日期将是child_id.ID是customer_id的公共链接列
非常感谢你的帮助
答案 0 :(得分:1)
您可以使用row_number()
功能
with t as (
select *,
row_number() over (partition by id order by date) Seq
from table t
where exists (select 1 from table where id = t.id group by id having count(*) > 1)
)
select (case when seq = 1 then Cust_id end) Parent_id,
(case when seq = 2 then Cust_id end) Child_id
from t
where seq in (1,2);
答案 1 :(得分:1)
您可以lead
与partition by id
一起使用以获得所需的输出。
对于SQL Server 2012及更高版本
select *
from (select [cust_id],
lead([cust_id])
over(partition by id order by date) as Child_id
from tablename t1)t
where child_id is not null
<强> DEMO 强>
<强>输出强>
+----------+----------+
| Cust_id | Child_id |
+----------+----------+
| 75407014 | 79807014 |
+----------+----------+
| 75407016 | 79807016 |
+----------+----------+
| 75407018 | 79807018 |
+----------+----------+
| 75407020 | 79807020 |
+----------+----------+
对于旧版本的SQL Server ,您可以使用子查询查找如下所示的潜在客户。
select *
from (select [cust_id],
(select top 1 [cust_id]
from tablename t2
where t2.id = t1.id
and t2.date > t1.date
order by t2.date) as Child_id
from tablename t1)t
where child_id is not null
答案 2 :(得分:1)
基于示例数据? 这是一种简单的方法,也是一种更先进的方法。
请参阅下面的示例代码段:
declare @TestTable table (Cust_id int, ID int, [Date] date);
insert into @TestTable (Cust_id, ID, [Date]) values
(75407014, 603, '2018-04-27'),
(79807014, 603, '2018-04-30'),
(75407016, 604, '2018-04-23'),
(79807016, 604, '2018-04-30'),
(75407018, 605, '2018-04-24'),
(79807018, 605, '2018-04-30'),
(75407020, 606, '2018-04-24'),
(79807020, 606, '2018-04-30'),
(75407014, 608, '2018-04-27');
--
-- Method 1: A simple self-join on ID and Date
-- This assumes that there are maximum 2 records per ID
--
select t1.Cust_id as Parent_id, t2.Cust_id as Child_id
from @TestTable t1
join @TestTable t2 on (t2.ID = t1.ID and t2.[Date] > t1.[Date]);
--
-- Method 2: use a CTE with a row_number and self-join the CTE
--
;WITH CTE as (
select
ID,
row_number() over (partition by ID order by [Date], Cust_id) as rn,
Cust_id
from @TestTable t
)
select t1.Cust_id as Parent_id, t2.Cust_id as Child_id
from CTE t1
join CTE t2 on (t1.ID = t2.ID and t1.rn = 1 and t2.rn > 1);
第二种方法允许每个父母有超过1个孩子。
答案 3 :(得分:0)
请试试这个
;WITH CTE(Cust_id,ID,[Date ])
AS
(
SELECT 75407014,603,'2018-04-27' UNION ALL
SELECT 79807014,603,'2018-04-30' UNION ALL
SELECT 75407016,604,'2018-04-23' UNION ALL
SELECT 79807016,604,'2018-04-30' UNION ALL
SELECT 75407018,605,'2018-04-24' UNION ALL
SELECT 79807018,605,'2018-04-30' UNION ALL
SELECT 75407020,606,'2018-04-24' UNION ALL
SELECT 79807020,606,'2018-04-30' UNION ALL
SELECT 75407014,608,'2018-04-27'
)
,CTE_Final
AS
(
SELECT Cust_id
,ID
,[Date ]
,DENSE_RANK()OVER(ORDER BY ID) SEQ
FROM CTE
)
SELECT Parent_id
,Child_id
FROM
(
SELECT SUBSTRING(Cust_id,0,CHARINDEX(',',Cust_id)) AS Parent_id,
SUBSTRING(Cust_id,CHARINDEX(',',Cust_id)+1,LEN(Cust_id))AS Child_id
FROM
(
SELECT DISTINCT STUFF((SELECT DISTINCT ', '+CAST( Cust_id AS VARCHAR(10))
FROM CTE_Final i WHERE i.SEQ=o.SEQ
FOR XML PATH ('')),1,1,'') AS Cust_id
FROM CTE_Final o
)dt
)Dt2
WHERE Dt2.Parent_id <> ''
ORDER BY Parent_id
结果
Parent_id Child_id
--------------------
75407014 79807014
75407016 79807016
75407018 79807018
75407020 79807020
答案 4 :(得分:0)
This query works if ID values repeat twice
SELECT * INTO TemP FROM
(
SELECT 75407014 Cust_id, 603 ID, '2018-04-27'Date UNION
SELECT 79807014 Cust_id, 603 ID, '2018-04-30'Date UNION
SELECT 75407016 Cust_id, 604 ID, '2018-04-23'Date UNION
SELECT 79807016 Cust_id, 604 ID, '2018-04-30'Date UNION
SELECT 75407018 Cust_id, 605 ID, '2018-04-24'Date UNION
SELECT 79807018 Cust_id, 605 ID, '2018-04-30'Date UNION
SELECT 75407020 Cust_id, 606 ID, '2018-04-24'Date UNION
SELECT 79807020 Cust_id, 606 ID, '2018-04-30'Date UNION
SELECT 75407014 Cust_id, 608 ID, '2018-04-27'Date
)A
SELECT *,ROW_number() OVER (PARTITION BY ID ORDER BY Date) RNO INTO #Tem
FROM TEMP
SELECT K.Cust_id,L.cust_id
FROM #Tem K
INNER JOIN #Tem L
ON K.ID = L.ID AND K.RNO < L.RNO