查看: 4631|回复: 14

[SQL] 【讨论】求一关于互相推荐的SQL

[复制链接]
论坛徽章:
9
奥运会纪念徽章:羽毛球
日期:2012-10-08 11:33:492013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:47:53马上加薪
日期:2014-02-18 16:47:53马上加薪
日期:2015-01-13 21:26:15优秀写手
日期:2015-02-12 06:00:15慢羊羊
日期:2015-03-04 14:53:332015年新春福章
日期:2015-03-06 11:58:39
发表于 2015-1-8 23:51 | 显示全部楼层 |阅读模式
表数据如下:
推荐人 被推荐人  推荐时间(例子数据只是打个比方,真实如日常时间 )
a            b             1
b           a              2
c           d              3
d           c              4
e            f              5
f            e              6
g           z               7
h           i               8
...

要求:把互相推荐的用户(如a和b等)找出来,再根据推荐时间,然后找出互相推荐的一组(如,a和b)里的最早那条。。。,
互相推荐的用户我可以通过自连接找出来,但是,根据推荐时间,找最早那条我还没想出比较好的方法,
希望各位能提供下建议。谢谢。

我想要的结果如下,如果有更好的方法也可以。。
推荐人 被推荐人  推荐时间  是否互相推荐 序号
a            b             1           是              1
b           a              2           是              1
c           d              3           是              2
d           c              4           是              2
e            f              5           是              3
f            e              6           是              3

g           z               7          否           
h           i               8          否
...

论坛徽章:
400
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2015-1-8 23:52 | 显示全部楼层
找最早那条  min

使用道具 举报

回复
论坛徽章:
9
奥运会纪念徽章:羽毛球
日期:2012-10-08 11:33:492013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:47:53马上加薪
日期:2014-02-18 16:47:53马上加薪
日期:2015-01-13 21:26:15优秀写手
日期:2015-02-12 06:00:15慢羊羊
日期:2015-03-04 14:53:332015年新春福章
日期:2015-03-06 11:58:39
 楼主| 发表于 2015-1-8 23:55 | 显示全部楼层
〇〇 发表于 2015-1-8 23:52
找最早那条  min

不好意思,我之前没说清楚。是找出互相推荐的一组里的最早那条记录而不是全部数据里的最早那条。

使用道具 举报

回复
论坛徽章:
535
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2015-1-8 23:59 | 显示全部楼层
SELECT LEAST(T1.COL1,T1.COL2),GREATEST(T1.COL1,T1.COL2),MIN(TIME)
  FROM T T1,T T2
WHERE (T1.COL1,T1.COL2) IN ((T2.COL2,T2.COL1))
GROUP BY LEAST(T1.COL1,T1.COL2),GREATEST(T1.COL1,T1.COL2);

使用道具 举报

回复
论坛徽章:
9
奥运会纪念徽章:羽毛球
日期:2012-10-08 11:33:492013年新春福章
日期:2013-02-25 14:51:242014年新春福章
日期:2014-02-18 16:47:53马上加薪
日期:2014-02-18 16:47:53马上加薪
日期:2015-01-13 21:26:15优秀写手
日期:2015-02-12 06:00:15慢羊羊
日期:2015-03-04 14:53:332015年新春福章
日期:2015-03-06 11:58:39
 楼主| 发表于 2015-1-9 00:10 | 显示全部楼层
newkid 发表于 2015-1-8 23:59
SELECT LEAST(T1.COL1,T1.COL2),GREATEST(T1.COL1,T1.COL2),MIN(TIME)
  FROM T T1,T T2
WHERE (T1.COL1 ...

WHERE (T1.COL1,T1.COL2) IN ((T2.COL2,T2.COL1))
--
这种用法比较少见,虽然大概看懂意思,有没有比较详细的介绍啊?或者提供下关键词我去搜。谢了。

使用道具 举报

回复
论坛徽章:
400
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
发表于 2015-1-9 00:19 | 显示全部楼层
iscogeek 发表于 2015-1-9 00:10
WHERE (T1.COL1,T1.COL2) IN ((T2.COL2,T2.COL1))
--
这种用法比较少见,虽然大概看懂意思,有没有比较 ...

有了这么好的例子,还用搜吗

使用道具 举报

回复
论坛徽章:
535
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
发表于 2015-1-9 00:49 | 显示全部楼层
iscogeek 发表于 2015-1-9 00:10
WHERE (T1.COL1,T1.COL2) IN ((T2.COL2,T2.COL1))
--
这种用法比较少见,虽然大概看懂意思,有没有比较 ...

第一层括号表示要比较的是一组多个列不是单个列。
直接写等号不支持比较多个列,IN却是支持的,类似 WHERE COL IN (VAL1,VAL2,VAL3,...)
这里要比较的只有一组那么就是COL IN (VAL1)。这就是第二层括号。

使用道具 举报

回复
认证徽章
论坛徽章:
41
生肖徽章:鼠
日期:2013-12-06 14:15:45生肖徽章:牛
日期:2013-12-06 14:15:45生肖徽章:虎
日期:2013-12-06 14:15:45生肖徽章:兔
日期:2013-12-06 14:15:45生肖徽章:龙
日期:2013-12-06 14:15:45生肖徽章:蛇
日期:2013-12-06 14:15:45生肖徽章:马
日期:2013-12-06 14:15:45生肖徽章:羊
日期:2013-12-06 14:15:45生肖徽章:猴
日期:2013-12-06 14:15:45生肖徽章:鸡
日期:2013-12-06 14:15:45
发表于 2015-1-9 08:59 | 显示全部楼层

WITH T1 AS (
SELECT 'A' A , 'B' B , 1 DT FROM DUAL UNION ALL
SELECT 'B' A , 'A' B , 2 DT FROM DUAL UNION ALL  
SELECT 'C' A , 'D' B , 3 DT FROM DUAL UNION ALL  
SELECT 'D' A , 'C' B , 4 DT FROM DUAL UNION ALL  
SELECT 'E' A , 'F' B , 5 DT FROM DUAL UNION ALL  
SELECT 'F' A , 'E' B , 6 DT FROM DUAL UNION ALL  
SELECT 'G' A , 'Z' B , 7 DT FROM DUAL UNION ALL  
SELECT 'H' A , 'I' B , 8 DT FROM DUAL
)
,T2 AS (
SELECT A,B FROM T1
INTERSECT
SELECT B,A FROM T1
)
SELECT T1.A, T1.B ,T1.DT
       ,CASE WHEN EXISTS (SELECT * FROM T2 WHERE T2.A = T1.A AND T2.B = T1.B) THEN 'Y' ELSE 'N' END YN
       ,MIN(T1.DT) OVER(PARTITION BY LEAST(T1.A,T1.B),GREATEST(T1.A,T1.B)) MIN_DT  -- 此处用了Newkid 的
FROM T1;

A B         DT YN     MIN_DT
- - ---------- -- ----------
A B          1 Y           1
B A          2 Y           1
C D          3 Y           3
D C          4 Y           3
E F          5 Y           5
F E          6 Y           5
G Z          7 N           7
H I          8 N           8


后来一想, 直接这样就行。

WITH T1 AS (
SELECT 'A' A , 'B' B , 1 DT FROM DUAL UNION ALL
SELECT 'B' A , 'A' B , 2 DT FROM DUAL UNION ALL  
SELECT 'C' A , 'D' B , 3 DT FROM DUAL UNION ALL  
SELECT 'D' A , 'C' B , 4 DT FROM DUAL UNION ALL  
SELECT 'E' A , 'F' B , 5 DT FROM DUAL UNION ALL  
SELECT 'F' A , 'E' B , 6 DT FROM DUAL UNION ALL  
SELECT 'G' A , 'Z' B , 7 DT FROM DUAL UNION ALL  
SELECT 'H' A , 'I' B , 8 DT FROM DUAL
)
SELECT T1.A, T1.B ,T1.DT
       ,CASE WHEN COUNT(T1.A)OVER(PARTITION BY LEAST(T1.A,T1.B),GREATEST(T1.A,T1.B)) > 1 THEN 'Y' ELSE 'N' END YN
       ,MIN(T1.DT) OVER(PARTITION BY LEAST(T1.A,T1.B),GREATEST(T1.A,T1.B)) MIN_DT  
FROM T1;

使用道具 举报

回复
认证徽章
论坛徽章:
72
秀才
日期:2019-05-24 13:29:27秀才
日期:2019-03-04 14:02:03秀才
日期:2019-03-04 14:02:03秀才
日期:2019-03-04 14:02:03秀才
日期:2019-03-04 14:01:25秀才
日期:2018-12-05 13:58:28秀才
日期:2018-12-05 13:52:27秀才
日期:2018-11-13 15:18:40秀才
日期:2018-11-13 15:18:40秀才
日期:2018-11-13 15:18:40
发表于 2015-1-9 10:00 | 显示全部楼层
本帖最后由 sse_zero 于 2015-1-9 10:04 编辑
newkid 发表于 2015-1-9 00:49
第一层括号表示要比较的是一组多个列不是单个列。
直接写等号不支持比较多个列,IN却是支持的,类似 WHE ...

学习了。真不错,以为只能T1.COL1||T1.COL2=T2.COL2||T2.COL1,这么写才行,真没想到T1.COL1,T1.COL2)IN((T2.COL2,T2.COL1))这个方法。

使用道具 举报

回复
论坛徽章:
126
ITPUB元老
日期:2007-07-04 17:27:50会员2007贡献徽章
日期:2007-09-26 18:42:10现任管理团队成员
日期:2011-05-07 01:45:08优秀写手
日期:2015-01-09 06:00:14版主7段
日期:2015-07-16 02:10:00
发表于 2015-1-9 10:27 | 显示全部楼层
这种问题也可以算是老问题了

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

SACC2019中国系统架构师大会

【数字转型 架构演进】SACC2019中国系统架构师大会,7折限时优惠重磅来袭!
2019年10月31日~11月2日第11届中国系统架构师大会(SACC2019)将在北京隆重召开。四大主线并行的演讲模式,1个主会场、20个技术专场、超千人参与的会议规模,100+来自互联网、金融、制造业、电商等领域的嘉宾阵容,将为广大参会者提供一场最具价值的技术交流盛会。

限时七折期:2019年8月31日前


----------------------------------------

大会官网>>
TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表