如何与多值列结合?

时间:2018-09-04 16:41:27

标签: sql ms-access

我有两个表:

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;

任何帮助将不胜感激

4 个答案:

答案 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作为第二个字段)
  • 按如下所示更改该字段的查找属性:
    • 显示:组合框
    • RowsourceType:表/查询
    • 行来源:SELECT Game.DeveloperID, Game.[Release Date] & ", " & Game.[Origin Date] AS Expr1 FROM Game;
    • 绑定列:1
    • 列数:2
    • 列宽:0(=隐藏第一列)
    • 列表宽度:0(=自动)

尽管这并不能真正连接日期,但会像显示日期一样显示它们(多值字段显示多个值的方式)。

德语版本(用分号作为列表分隔符)的结果如下:

enter image description here