2

表 1 有,NameId、年龄、性别...
表 2 有版本号、时间戳...

现在我想从表1中选择NameId,从表2中多次选择版本号和时间戳,我需要从表2中查询所有版本和时间记录,谁能给我一些关于如何查询的想法?

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
...     |   ....                |                   |   
4

2 回答 2

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)
于 2012-12-07T20:01:46.847 回答
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_twotable_oneNameId 值相关。原始问题中提供的示例数据留下了与(即笛卡尔积)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 语句中静态定义的。

于 2012-12-07T21:39:17.137 回答