如何通过将多个过滤器应用于sql server 2008中的单个列来获取行?

时间:2013-07-24 14:40:16

标签: sql sql-server

我的sql server 2008数据库中有以下表格:

MsgID    TrackerId    MsgContent

  1        123           red    //MsgContent corresponding to colour
  2        123          E2120   //MsgContent corresponding to model
  5        123           sam    //MsgContent corresponding to password
  1        111          orange  //MsgContent corresponding to colour
  2        111          M3420   //MsgContent corresponding to model
  5        111           pam    //MsgContent corresponding to password

我想要一个查询,其结果如下:

TrackerId     Colour    Model    Password   

  123          red      E2120       sam
  111          orange   M3420       pam 

那么,我该如何解决这个问题呢?提前致谢。

4 个答案:

答案 0 :(得分:2)

您可以根据TrackerID将表格连接到自身并按MsgID过滤来完成此操作。

示例:

SELECT 
     Colour.TrackerId, 
     Colour.MsgContent AS Colour,
     Model.MsgContent AS Model,
     Password.MsgContent AS Password 
FROM MyTable Colour
JOIN MyTable Model ON Colour.TrackerId = Model.TrackerId AND Model.MsgID = 2
JOIN MyTable Password ON Colour.TrackerId = Password.TrackerId AND Password.MsgID = 5
WHERE Colour.MsgID = 1

答案 1 :(得分:2)

这是使用PIVOT的版本。我唯一的问题是不必要的聚合函数。我不知道你的表定义,但是如果你只有列MsgID,TrackerID,MsgContent,那么选择分组,传播和聚合列到枢轴的CTE是多余的。如果您有更多列,则保留CTE,否则您将在结果中获得空值。

SELECT TrackerID, [1] [Colour], [2] [Model], [5] [Password]
FROM 
(
  SELECT 
    MsgID, -- spreading column
    TrackerID, -- grouping column
    MsgContent -- aggregation column
  FROM Trackers
) p
PIVOT
(
  MAX(MsgContent)
  FOR MsgID IN( [1], [2], [5] )
) AS pvt

SQLFiddle

您还可以为每种类型的值使用选择。

SELECT DISTINCT TrackerID,
  (SELECT MsgContent FROM trackers t2 
   WHERE t2.MsgID = 1 AND t2.TrackerID = t1.TrackerID) [Colour],
  (SELECT MsgContent FROM trackers t2 
   WHERE t2.MsgID = 2 AND t2.TrackerID = t1.TrackerID) [Model],
  (SELECT MsgContent FROM trackers t2 
   WHERE t2.MsgID = 5 AND t2.TrackerID = t1.TrackerID) [Password]
FROM Trackers t1

SQLFiddle

答案 2 :(得分:0)

以下是支点方法:

select TrackerId, [1] as Colour, [2] as Model, [5] as Password
from Trackers
pivot (max(MsgContent) for MsgId in ([1], [2], [5])) pvt

唯一的技巧是你需要重命名列。这是在select子句中完成的。

编辑:

丹尼尔的评论是正确的。使用子查询例行修复问题:

with trackers(MsgId, TrackerId, MsgContent, extra) as (
      select 1, 123, 'red', 0 union all
      select 2, 123, 'E2120', 2 union all
      select 5, 111, 'orange', 8 union all
      select 2, 111, 'M3420', 9 union all
      select 5, 111, 'pam', 10
     ) 
select TrackerId, [1] as Colour, [2] as Model, [5] as Password
from (select MsgId, TrackerId, MsgContent
      from Trackers t
     ) t
pivot (max(MsgContent) for MsgId in ([1], [2], [5])) pvt;

答案 3 :(得分:0)

Select [TrackerId],[1] AS Color,[2] as Model,[5] AS [Password]
FROM 
    (SELECT [TrackerId], [MsgID], MAX([MsgContent]) as [MsgContent]
    FROM Table1
    GROUP BY [TrackerId], [MsgID]
    )x
    PIVOT
    (
        MAX([MsgContent])
        FOR [MsgID] IN ([1],[2],[5])
    )p

<强> Sql Fiddle