表1中有NameId,年龄,性别......
表2有版本号,TimeStamp ...
现在我想从表1中选择NameId,从表2中多次选择版本号和时间戳,我需要查询table2中的所有版本和时间记录, 任何人都可以给我一些关于如何查询的想法吗?
NameId | Version/Time | Version/Time | Version/Time …
Angela | 1 / 01.01.2010 | 2 / 01.02.2010 | 3 / 01.03.2010
Betty | 1 / 01.01.2010 | 2 / 01.02.2010 | 3 / 01.03.2010
Cathy | 1 / 01.01.2010 | 2 / 01.02.2010 | 3 / 01.03.2010
... | .... | |
答案 0 :(得分:0)
如果正如你所说的那样,任何固定值集都不起作用,那么你需要动态的sql来完成你的工作。
这些内容:
CREATE PROCEDURE [dbo].[usp_pivot_]
AS
DECLARE @columns VARCHAR(1000)
SELECT @columns = COALESCE(@columns + ',[' + cast(versionTime as varchar) + ']',
'[' + cast(versionTime as varchar)+ ']')
FROM table1 inner join table2 on table1.NameId = table2.NameId
GROUP BY versionTime
DECLARE @query VARCHAR(8000)
SET @query = '
SELECT *
FROM table1 inner join table2 on table1.NameId = table2.NameId
PIVOT
(
first(versionTime)
FOR [versionTime]
IN (' + @columns + ')
)
AS p'
EXECUTE(@query)
答案 1 :(得分:0)
通常的方法是在两个表之间执行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语句中静态定义的。