通常的方法是在两个表之间执行 JOIN,例如
SELECT t1.NameId
, t2.VersionNo
, t2.Timestamp
FROM table_one t1
LEFT
JOIN table_two t2
ON t2.NameId = t1.NameId
ORDER
BY t1.NameId
, t2.VersionNo
这将为您提供如下结果集:
NameId VersionNo TimeStamp
-------- --------- ----------
Angela 1 01.01.2010
Angela 2 01.02.2010
Angela 3 01.03.2010
Betty 1 01.01.2010
Betty 2 01.02.2010
Betty 3 01.03.2010
Cathy 1 01.01.2010
Cathy 2 01.02.2010
Cathy 3 01.03.2010
(这假设table_two
与table_one
NameId 值相关。原始问题中提供的示例数据留下了与(即笛卡尔积)table_two
中的每一行匹配的三行的可能性table_one
。在这种情况下,它将是CROSS JOIN 语句中:
SELECT t1.NameId
, t2.VersionNo
, t2.Timestamp
FROM table_one t1
CROSS
JOIN table_two t2
ORDER
BY t1.NameId
, t2.VersionNo
要将来自该查询的结果集转换为“交叉表”(或数据透视表),每个单独的行都table_two
显示在同一行输出中,这通常在客户端而不是 SQL 语句中更好地处理。
但是,MySQL 可以返回一个类似的结果集,每个 VersionNo 和 Timestamp 值在一个单独的列中;但要做到这一点的查询并非易事。
(一个简单的替代方法是使用 GROUP_CONCAT 聚合函数,但它返回单个列,而不是单独的列,并且受max_allowd_packet_size
.)
SELECT t1.NameID
, GROUP_CONCAT(CONCAT(t2.VersionNo,'/',t2.Timestamp) ORDER BY t2.VersionNo)
FROM table_one t1
LEFT
JOIN table_two t2
ON t2.NameId = t1.NameId
GROUP
BY t1.NameId
ORDER
BY t1.NameId
再次假设table_two
与 相关table_one
,一种相当笨拙但易于理解的方法是在查询的 SELECT 列表中使用相关子查询,例如
SELECT t1.NameId
, ( SELECT CONCAT(t2a.VersionNo,' / ',t2a.Timestamp)
FROM table_two t2a WHERE t2a.NameId = t1.NameID
ORDER BY t2a.VersionNo LIMIT 0,1
) AS `Version/Time`
, ( SELECT CONCAT(t2b.VersionNo,' / ',t2b.Timestamp)
FROM table_two t2b WHERE t2b.NameId = t1.NameID
ORDER BY t2b.VersionNo LIMIT 1,1
) AS `Version/Time`
, ( SELECT CONCAT(t2c.VersionNo,' / ',t2c.Timestamp)
FROM table_two t2c WHERE t2c.NameId = t1.NameID
ORDER BY t2c.VersionNo LIMIT 2,1
) AS `Version/Time`
FROM table_one t1
ORDER BY t1.NameId
该查询将返回一个类似于原始问题中显示的结果集,尽管返回的列数是在 SELECT 语句中静态定义的。