我有两个表:
Game and Developer
“我的游戏”表具有以下列:
Release Date Origin Date DeveloperID
并且我的Developer表具有以下列:
DevId Games
有了数据,这些表可能看起来像这样:
Game:
Release Date Origin Date GameId
11/20/2017 11/09/2015 G-1
06/07/1999 03/04/1995 G-2
08/31/2015 02/09/2010 G-3
Developer表可能类似于:
DevId Games
D-1 G-1, G-2
D-2 G-3
D-3 G1, G2, G3
游戏可以具有多个值,并且它们是在下拉列表中选择的。
我想在Games值和Game表的GameId之间创建一个关系,并连接与开发人员关联的每个Game的发布日期和原始日期。
所以对于D1,我想要类似的东西
D1 Dates - 11/20/2017, 11/09/2017, 06/07/1999, 03/04/1995 since G-1 and G-2 are associated with D1
D2 Dates - only 08/31/2015, 02/09/2010
D3 Dates - 11/20/2017, 11/09/2015, 06/07/1999, 03/04/1995, 08/31/2015, 092/09/2010 since all of the Games are associated with this Dev.
我现在所拥有的并没有削减。分组不正确,仅列出了6行作为
11/20/2017
11/09/2015
06/07/1999
03/04/1995
08/31/2015
02/09/2010
这是我的尝试:
SELECT [Origin Date] & ',' & [Release Date] FROM Game INNER JOIN Developer ON Game.GameId = Developer.Games.Value;
任何帮助将不胜感激
答案 0 :(得分:1)
这假定游戏数限制为3。如果不是这种情况,则可能必须编写另一个子查询来查找最大游戏数并构造等效的列数。
WITH cte AS
(
SELECT DevID, g_1, g_2, g_3
FROM
(
SELECT DevID, ROW_NUMBER() OVER() AS row_num1 FROM DevID
) a
LEFT JOIN
(
SELECT a[1] AS g_1, a[2] AS g_2, a[3] AS g_3, ROW_NUMBER() OVER() AS row_num2
FROM
(
SELECT STRING_TO_ARRAY(games, ',')
FROM DevID
) AS dt(a)
) b
ON a.row_num1 = b.row_num2
)
SELECT DevId, ARRAY_AGG(release_date) AS release_dates, ARRAY_AGG(origin_date) AS origin_dates
FROM
(
SELECT DevID, game, Release_date, Origin_date
FROM
(
SELECT DevID, LTRIM(game) AS game
FROM
(
SELECT DevId, g_1 AS game FROM cte WHERE g_1 IS NOT NULL
UNION
SELECT DevId, g_2 AS game FROM cte WHERE g_2 IS NOT NUll
UNION
SELECT DevId, g_3 AS game FROM cte WHERE g_3 IS NOT NULL
) a1
) al
LEFT JOIN
Game g1
ON al.game = g1.GameId
) al1
GROUP BY DevId
输出:
DevId ReleaseDates OriginDates
"D-2" "{2015-08-31}" "{2010-02-09}"
"D-3" "{2017-11-20,1999-06-07,2015-08-31}" "{2015-11-09,1995-03-04,2010-02-09}"
"D-1" "{2017-11-20,1999-06-07}" "{2015-11-09,1995-03-04}"
答案 1 :(得分:0)
在使用“多值”字段时,您往往不得不诉诸以下内容:
Games = GameId
OR Games LIKE GameId & ',*'
OR Games LIKE '*, ' & GameId & ',*'
OR Games LIKE '*, ' & GameId
我的MSAccess语法有点生锈,因此可能并不完全正确。
SELECT g.[Origin Date] & ',' & g.[Release Date]
FROM Game AS g
INNER JOIN Developer AS d
ON d.Games = g.GameId
OR d.Games LIKE g.GameId & ',*'
OR d.Games LIKE '*, ' & g.GameId & ',*'
OR d.Games LIKE '*, ' & g.GameId
;
答案 2 :(得分:0)
不要在一个列中存储多个值!那不是数据库的工作方式。
有时候,我们真的非常,非常非常糟糕的设计被其他人所束缚。您可以这样做:
SELECT g.[Origin Date] & ',' & g.[Release Date]
FROM Game as g INNER JOIN
Developer as d
ON ',' & d.Games & ',' LIKE '*,' & g.GameId & ',*';
也许在MS Access中,您需要以CROSS JOIN
的身份执行此操作:
SELECT g.[Origin Date] & ',' & g.[Release Date]
FROM Game as g,
Developer as d
WHERE ',' & d.Games & ',' LIKE '*,' & g.GameId & ',*';
答案 3 :(得分:0)
我猜您应该执行的操作会覆盖执行以下操作的查找属性:
Developer
表的查询,将两个字段都添加到查询中。Games
重命名为Dates
(输入Dates: Games
作为第二个字段)SELECT Game.DeveloperID, Game.[Release Date] & ", " & Game.[Origin Date] AS Expr1 FROM Game;
尽管这并不能真正连接日期,但会像显示日期一样显示它们(多值字段显示多个值的方式)。
德语版本(用分号作为列表分隔符)的结果如下: