SQL:比较列以获得集合的精确匹配
我有一张这样的桌子:SQL:比较列以获得集合的精确匹配,sql,sql-server,tsql,analytics,ssms,Sql,Sql Server,Tsql,Analytics,Ssms,我有一张这样的桌子: RN ID1 ID2 Name Source 1 W76544 945297 1_W_HO HO 2 W76544 945297 1_W_INT Int 1 W76547 945299 3_W_HO HO 2 W76547 945678 3_W_INT Int 1 W76561 NULL Dev_U_W
RN ID1 ID2 Name Source
1 W76544 945297 1_W_HO HO
2 W76544 945297 1_W_INT Int
1 W76547 945299 3_W_HO HO
2 W76547 945678 3_W_INT Int
1 W76561 NULL Dev_U_W AD
2 W76561 207283 Dev_W_HO HO
3 W76561 207283 Dev_W_INT Int
1 W76562 207284 Dev_R_HO HO
2 W76562 207284 Dev_R_INT Int
3 W76562 NULL Dev_U_R AD
1 W76563 NULL Prd_U_W AD
2 W76563 NULL Prd_W_HO HO
3 W76563 NULL Prd_W_INT Int
RN ID1 ID2 Matched Name Source
1 W76544 945297 Yes 1_W_HO HO
2 W76544 945297 Yes 1_W_INT Int
1 W76547 945299 No 3_W_HO HO
2 W76547 945678 No 3_W_INT Int
1 W76561 NULL No Dev_U_W AD
2 W76561 207283 No Dev_W_HO HO
3 W76561 207283 No Dev_W_INT Int
1 W76562 207284 No Dev_R_HO HO
2 W76562 207284 No Dev_R_INT Int
3 W76562 NULL No Dev_U_R AD
1 W76563 NULL Empty Prd_U_W AD
2 W76563 NULL Empty Prd_W_HO HO
3 W76563 NULL Empty Prd_W_INT Int
SELECT m.RN,
m.ID1,
m.ID2,
CASE WHEN NOT EXISTS (SELECT 1 FROM MyTable WHERE ID1 = m.ID1 AND ID2 IS NOT NULL) THEN 'Empty'
ELSE CASE WHEN COUNT(*) OVER(PARTITION BY m.ID1, m.ID2) > 1 THEN 'Yes'
ELSE 'No'
END
END "Matched",
m.Name,
m.Source
FROM MyTable m
我试图找出我们如何确定ID1和ID2集之间的精确匹配。例如,此示例完全匹配:
RN ID1 ID2 Name Source
1 *W76544 945297* 1_W_HO HO
2 *W76544 945297* 1_W_INT Int
我希望结果如下所示:
RN ID1 ID2 Name Source
1 W76544 945297 1_W_HO HO
2 W76544 945297 1_W_INT Int
1 W76547 945299 3_W_HO HO
2 W76547 945678 3_W_INT Int
1 W76561 NULL Dev_U_W AD
2 W76561 207283 Dev_W_HO HO
3 W76561 207283 Dev_W_INT Int
1 W76562 207284 Dev_R_HO HO
2 W76562 207284 Dev_R_INT Int
3 W76562 NULL Dev_U_R AD
1 W76563 NULL Prd_U_W AD
2 W76563 NULL Prd_W_HO HO
3 W76563 NULL Prd_W_INT Int
RN ID1 ID2 Matched Name Source
1 W76544 945297 Yes 1_W_HO HO
2 W76544 945297 Yes 1_W_INT Int
1 W76547 945299 No 3_W_HO HO
2 W76547 945678 No 3_W_INT Int
1 W76561 NULL No Dev_U_W AD
2 W76561 207283 No Dev_W_HO HO
3 W76561 207283 No Dev_W_INT Int
1 W76562 207284 No Dev_R_HO HO
2 W76562 207284 No Dev_R_INT Int
3 W76562 NULL No Dev_U_R AD
1 W76563 NULL Empty Prd_U_W AD
2 W76563 NULL Empty Prd_W_HO HO
3 W76563 NULL Empty Prd_W_INT Int
SELECT m.RN,
m.ID1,
m.ID2,
CASE WHEN NOT EXISTS (SELECT 1 FROM MyTable WHERE ID1 = m.ID1 AND ID2 IS NOT NULL) THEN 'Empty'
ELSE CASE WHEN COUNT(*) OVER(PARTITION BY m.ID1, m.ID2) > 1 THEN 'Yes'
ELSE 'No'
END
END "Matched",
m.Name,
m.Source
FROM MyTable m
分类。。。Match='Yes',当具有相同ID1的所有组与具有相同ID2的所有组匹配时。Match='No',当具有相同ID1的组不是全部匹配到类似ID2,就是某些ID1的匹配,但集中的其他组根本不匹配到ID2时。Match='Empty',当具有相同ID1的所有组与ID2完全不匹配时
p、 s.RN是由ID1划分和排序的行号
谢谢
@BaconBits,这似乎是你的问题:
1 W10151820 NULL No DEV_U_W AD
2 W10151820 212405 Yes DEV_W_HO HO
3 W10151820 212405 Yes DEV_W_INTL Int
你能这样做吗:
RN ID1 ID2 Name Source
1 W76544 945297 1_W_HO HO
2 W76544 945297 1_W_INT Int
1 W76547 945299 3_W_HO HO
2 W76547 945678 3_W_INT Int
1 W76561 NULL Dev_U_W AD
2 W76561 207283 Dev_W_HO HO
3 W76561 207283 Dev_W_INT Int
1 W76562 207284 Dev_R_HO HO
2 W76562 207284 Dev_R_INT Int
3 W76562 NULL Dev_U_R AD
1 W76563 NULL Prd_U_W AD
2 W76563 NULL Prd_W_HO HO
3 W76563 NULL Prd_W_INT Int
RN ID1 ID2 Matched Name Source
1 W76544 945297 Yes 1_W_HO HO
2 W76544 945297 Yes 1_W_INT Int
1 W76547 945299 No 3_W_HO HO
2 W76547 945678 No 3_W_INT Int
1 W76561 NULL No Dev_U_W AD
2 W76561 207283 No Dev_W_HO HO
3 W76561 207283 No Dev_W_INT Int
1 W76562 207284 No Dev_R_HO HO
2 W76562 207284 No Dev_R_INT Int
3 W76562 NULL No Dev_U_R AD
1 W76563 NULL Empty Prd_U_W AD
2 W76563 NULL Empty Prd_W_HO HO
3 W76563 NULL Empty Prd_W_INT Int
SELECT m.RN,
m.ID1,
m.ID2,
CASE WHEN NOT EXISTS (SELECT 1 FROM MyTable WHERE ID1 = m.ID1 AND ID2 IS NOT NULL) THEN 'Empty'
ELSE CASE WHEN COUNT(*) OVER(PARTITION BY m.ID1, m.ID2) > 1 THEN 'Yes'
ELSE 'No'
END
END "Matched",
m.Name,
m.Source
FROM MyTable m
丑陋如罪恶,但我认为这应该有效。我认为使用分析函数可能更容易:
select id1, id2,
(case when cnt_1 = cnt2 and min_1_2 = max_1_2 and min_2_1 = max_2_1 and
cnt_1 = cnt_2_notnull
then 'Yes'
when cnt_2_notnull > 0
then 'No'
else 'Empty'
end) as flag
from (select t.id1, t.id2,
count(id1) over (partition by id2) as cnt_2_notnull,
count(*) over (partition by id1) as cnt_1,
count(*) over (partition by id2) as cnt_2,
min(id1) over (partition by id2) as min_1_2,
max(id1) over (partition by id2) as max_1_2,
min(id2) over (partition by id1) as min_2_1,
max(id2) over (partition by id1) as max_2_1
from table t
) t;
逻辑是计算id1和id2的每个维度上的值的数量,并比较每个维度上的最小值和最大值。为了保持事物干净、轻巧且易于理解,将来我将使用CTE来计算匹配的参数 然后我将把结果合并在一起 工作示例: 试试这个:
Create table t(id int, c char(1))
Insert into t values
(1, 'a'),
(1, 'a'),
(2, 'b'),
(2, null),
(3, null),
(3, null),
(4, 'c'),
(4, 'd')
;with cte as(
select id, count(*) c1, count(c) c2, count(distinct c) c3 from t
group by id)
select t.id, t.c, ca.m from t
Cross apply(select case when c2 = 0 and c3 = 0 then 'empty'
when c1 = c2 and c3 = 1 then 'yes'
else 'no' end as m
from cte where cte.id = t.id) ca
输出:
id c m
1 a yes
1 a yes
2 b no
2 (null) no
3 (null) empty
3 (null) empty
4 c no
4 d no
这个怎么样?请用您的表名替换“YourTableName here”后再试一次好吗 具有 A作为 选择 X.ID1,X.ID2, 按点击次数计数1 从你的表名这里 按X.ID1、X.ID2分组 计数1>1的 , B作为 选择 X.ID1, SUMCASE当X.ID2为空时,则0或1以命中结束, SUMCASE当X.ID2为空时,则1或0结束为空 从你的表名这里 按X.ID1分组 计数1>1的 选择 X.RN,X.ID1,X.ID2, 案例 当A.Hits=B.为空时,则为“空” 当A.Hits=B.Hits+B.Nulls时,则为“是” 否则“不” 结束为[匹配], X[名称],X[来源] 从…起 你的表名在这里 左接A 在…上 A.ID1=X.ID1 A.ID2=X.ID2或A.ID2为空,X.ID2为空 B.ID1=X.ID1上的左连接B;
您的示例数据、解释和期望的输出似乎不匹配。看看W76563。在您的示例数据中,RN1和2在ID1中都有一个值,但根据您的解释,它们只有在没有值时才应该为空。我想你可以在这里用一个分区来利用count distinct,但你的输出不清楚。非常接近,但似乎无法正确识别我编辑问题时使用的示例。也许我跑错了,但这似乎不起作用,将大多数情况标记为“否”。选择的答案简洁而漂亮。更好的练习更多