SQL SD:确定两个团队之间最近的共同过去对手
我需要一些帮助来编写一个相当复杂的Oracle SQL查询 我有一个表,其中包含两支球队之间进行的比赛列表,列如下: 比赛日期 主队varchar226, 反对党varchar226队, 分数差38 我还创建了一个索引,它只是表中每一行每一个游戏的唯一ID,称为“索引” 大约有30支球队参加比赛,已经进行了5000多场比赛 对于每一排的每一场比赛,我希望能够确定第三支球队,称为共享对手,这是最近几天主队和对手队共享的对手。然后,我想计算这些历史比赛中主队对共享对手和对方队对共享对手在同一行上的得分差异,作为主队和对方队之间当前比赛的详细信息 到目前为止,我的尝试是这样的SQL SD:确定两个团队之间最近的共同过去对手,sql,oracle,Sql,Oracle,我需要一些帮助来编写一个相当复杂的Oracle SQL查询 我有一个表,其中包含两支球队之间进行的比赛列表,列如下: 比赛日期 主队varchar226, 反对党varchar226队, 分数差38 我还创建了一个索引,它只是表中每一行每一个游戏的唯一ID,称为“索引” 大约有30支球队参加比赛,已经进行了5000多场比赛 对于每一排的每一场比赛,我希望能够确定第三支球队,称为共享对手,这是最近几天主队和对手队共享的对手。然后,我想计算这些历史比赛中主队对共享对手和对方队对共享对手在同一行上的得
SELECT
A.GAME_DATE,
A.GAME_NUMBER,
A.INDEXING,
A.HOME_TEAM,
A.OPP_TEAM,
B.OPP_TEAM AS SHARED_OPP,
B.SCORE_DIFF AS OPP_SCORE_DIFF,
C.SCORE_DIFF AS HOME_SCORE_DIFF,
MIN((A.GAME_DATE - B.GAME_DATE)+ (A.GAME_DATE - C.GAME_DATE) + ABS(B.GAME_DATE - C.GAME_DATE)) AS TOTAL_DATE_DIFF
FROM
TEAM_SUMMARY_1 A
LEFT JOIN TEAM_SUMMARY_1 B ON A.OPP_TEAM = B.HOME_TEAM
LEFT JOIN TEAM_SUMMARY_1 C ON A.HOME_TEAM = C.HOME_TEAM
WHERE
B.OPP_TEAM <> A.HOME_TEAM AND
A.OPP_TEAM <> C.OPP_TEAM AND
B.OPP_TEAM = C.OPP_TEAM AND
ABS(B.GAME_DATE - C.GAME_DATE) < 5 AND
A.GAME_DATE - B.GAME_DATE < 20 AND
A.GAME_DATE - B.GAME_DATE > 0 AND
A.GAME_DATE - C.GAME_DATE < 20 AND
A.GAME_DATE - C.GAME_DATE > 0
GROUP BY
A.GAME_DATE,
A.GAME_NUMBER,
A.INDEXING,
A.HOME_TEAM,
A.OPP_TEAM,
B.OPP_TEAM,
B.SCORE_DIFF,
C.SCORE_DIFF
ORDER BY
A.GAME_DATE,
A.HOME_TEAM,
A.OPP_TEAM
在某种程度上,这段代码确实返回了我想要的,但是应用于总日期差的最小值不起作用
我不介意我是否必须分多个步骤来做这件事,但目前我似乎无法在头脑中对这个过程进行概念化。任何帮助都将不胜感激 看看这一点,并将其应用到表结构中 使用表格时,分数可以是正值或负值,也可以是0表示平局
CREATE TABLE dbo.Game
(
PlayDate DATETIME,
HomeTeam INT,
OpposingTeam INT,
Score INT
)
使用的查询
WITH GAME AS
(
SELECT ROW_NUMBER() OVER (ORDER BY G1.PlayDate) I, * FROM dbo.Games G1
)
, SHARED AS
(
SELECT
G.I,
G.HomeTeam,
G.OpposingTeam,
H.HomeTeam AS H,
H.OpposingTeam AS H2,
H.I AS HI,
ROW_NUMBER() OVER (PARTITION BY G.I ORDER BY H.I DESC) AS A
FROM GAME G
LEFT JOIN GAME H ON
(G.OpposingTeam = H.OpposingTeam OR G.OpposingTeam = H.HomeTeam)
AND G.HomeTeam <> H.HomeTeam
AND G.HomeTeam <> H.OpposingTeam
WHERE G.I > H.I
)
SELECT G.*, H.HI
FROM GAME G
LEFT JOIN SHARED H ON G.I = H.I
WHERE A = 1 OR A IS NULL
ORDER BY G.I
日期逻辑有点不同,但可以避免日期的减法:
-- CTE to exchange home and guest teams.
WITH dup AS (
SELECT team_home AS one
, team_guest AS two
, match_date AS match_date
FROM matches
UNION ALL
SELECT team_guest AS one
, team_home AS two
, match_date AS match_date
FROM matches
)
SELECT m0.*
, p1.two AS onetwo, p1.match_date AS onedate
, p2.two AS twotwo, p2.match_date AS twodate
FROM matches m0
-- all other previous matches for home player
JOIN dup p1 ON p1.one = m0.team_home AND p1.two <> m0.team_guest AND p1.match_date < m0.match_date
-- all other previous matches for guest player
JOIN dup p2 ON p2.one = m0.team_guest AND p2.two <> m0.team_home AND p2.match_date < m0.match_date AND p1.two = p2.two
WHERE 1=1
-- suppres older other matches, retaining only the most recent one.
AND NOT EXISTS ( SELECT 1
FROM dup px
JOIN dup py ON py.two = px.two
WHERE px.one = p1.one AND py.one = p2.one
AND px.match_date < m0.match_date AND (px.match_date > p1.match_date OR px.match_date > p2.match_date)
AND py.match_date < m0.match_date AND (py.match_date > p2.match_date OR py.match_date > p1.match_date)
)
ORDER BY
m0.team_home
, m0.match_date
, p1.match_date DESC, p2.match_date DESC
;
您能添加表结构、关系、示例数据、预期输出和您的DBMS sql server、mysql、oracle等吗?理想情况下,您已经尝试过的查询Hanks Honeybacker,我已经尽可能多地添加了。恐怕这是我第一次发帖子,所以我不确定要求。左加入团队总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结总结;你只需要匹配的团队。但是在WHERE子句中提到B.xxx和C.xxx将有效地导致左连接充当普通连接以供将来参考:在我看来,很可能有两个最近的共享对手。
-- CTE to exchange home and guest teams.
WITH dup AS (
SELECT team_home AS one
, team_guest AS two
, match_date AS match_date
FROM matches
UNION ALL
SELECT team_guest AS one
, team_home AS two
, match_date AS match_date
FROM matches
)
SELECT m0.*
, p1.two AS onetwo, p1.match_date AS onedate
, p2.two AS twotwo, p2.match_date AS twodate
FROM matches m0
-- all other previous matches for home player
JOIN dup p1 ON p1.one = m0.team_home AND p1.two <> m0.team_guest AND p1.match_date < m0.match_date
-- all other previous matches for guest player
JOIN dup p2 ON p2.one = m0.team_guest AND p2.two <> m0.team_home AND p2.match_date < m0.match_date AND p1.two = p2.two
WHERE 1=1
-- suppres older other matches, retaining only the most recent one.
AND NOT EXISTS ( SELECT 1
FROM dup px
JOIN dup py ON py.two = px.two
WHERE px.one = p1.one AND py.one = p2.one
AND px.match_date < m0.match_date AND (px.match_date > p1.match_date OR px.match_date > p2.match_date)
AND py.match_date < m0.match_date AND (py.match_date > p2.match_date OR py.match_date > p1.match_date)
)
ORDER BY
m0.team_home
, m0.match_date
, p1.match_date DESC, p2.match_date DESC
;