我有两张桌子。第一个“用户”表由记录用户登录事件的行组成。该表看起来像这样:
LoginTable
LoginID Name Time
100 Joe 12:00pm
101 Bob 3:30pm
102 Joe 4:00pm
103 Sue 6:15pm
第二个表记录了有关每次登录的其他指标,但并不常见,记录的其他项目数可能会发生变化。该表看起来像这样:
MetricsTable
MetricID LoginID Label Data
500 100 IPAddress 1.2.3.4
501 100 Attempts 25
502 100 Status Good
503 101 IPAddress 1.2.3.5
504 101 Attempts 19
505 101 Status Bad
506 102 IPAddress 1.2.3.6
507 102 Attempts 35
508 102 Status Hold
509 103 IPAddress 1.2.3.7
510 103 Attempts 4
511 103 Status Trial
我正在尝试为每一行构建一个LoginTable查询,显示代表与每个登录事件相关的额外指标数据的其他列。
一种解决方案是做这样的事情:
SELECT LoginTable.LoginID, LoginTable.Name, LoginTable.Time,
(SELECT MetricsTable.Data FROM MetricsTable WHERE
MetricsTable.LoginID=LoginTable.LoginID and
MetricsTable.Label="IPAddress") as IPAddressEx
FROM LoginTable
该查询将显示一个额外的列,显示为该事件记录的“IPAddress”值。然后我可以再添加2个子查询来显示“尝试”和“状态”的其他列(注意这些只是假的例子)。我并不担心能够自动识别有更多可能的列,如果它们出现,我可以手动添加它们。但是,为每个额外列添加子查询的这种技术似乎非常缓慢。
有什么更好的方法来实现这一目标?
请假设我无法重组表格。
谢谢!
答案 0 :(得分:0)
听起来你想要一个像这样的结果集:
LoginID Name Time IP Attempts Status FutureColumn1 FutureColumn2 ...
您可以PIVOT或Dynamic PIVOT您的数据。
答案 1 :(得分:0)
Select LoginID,
Name,
Time,
[IPAddress],
[Attempts],
[Status]
From (Select LoginTable.LoginID,
LoginTable.Name,
LoginTable.Time,
MetricsTable.Data,
MetricsTable.Label
From LoginTable
Inner Join MetricsTable
ON MetricsTable.LoginID=LoginTable.LoginID) As nested
Pivot (Min(Data) For Label In ([IPAddress],[Attempts],[Status])) As PivotTable
我没有时间对此进行测试,而且我不是最好的即时临时支点,但我认为这是对的。
答案 2 :(得分:0)
与Andrew的答案类似,我会改为使用MetricsTable。
SELECT LoginTable.LoginID
,LoginTable.Name
,LoginTable.Time
,IPAddress= IPAddress.Data
,Attempts = Attempts.Data
FROM LoginTable
Left Join MetricsTable As IPAddress
On IPAddress.LoginID=LoginTable.LoginID
And IPAddress.Label="IPAddress"
Left Join MetricsTable As Attempts
On Attempts.LoginID=LoginTable.LoginID
And Attempts.Label="Attempts"
-- Other joins for additional stats
如果您知道某些信息(如IPAddress)始终可用,请使用Inner Join
代替Left Join
。
你可以按照Love2Learn的建议pivot数据,但我更喜欢直接加入。
此外,如果LoginID不是LoginTable上的PK,则其上的索引将提高读取速度。
同样,如果您没有MetricsTable.LoginID的索引,我强烈建议您这样做。 Foreign keys benefit from indexes
通过上述查询,MetricsTable上的有用索引将位于LoginID和Label上(按此顺序),并且可能包含Data,以便数据库引擎可以读取索引中的所有数据。您应该进行性能测试,看看索引的开销是否值得。