显示多列中的行

时间:2010-03-18 13:08:27

标签: sql sql-server

不确定是否可以单独使用sql,但这是问题所在。我有一个奇怪的要求,即数据需要在列中显示,以便用户可以快速比较数据!

以下是结果集现在的样子

CustomerID  Company     Active
001         ATT        Y
002         ATT        N
003         ATT        Y
001         VZ         Y
002         VZ         N
003         VZ         Y
001         TM         Y
002         TM         Y
003         TM         Y

现在这就是他们想要看到它的方式

CustomerID  Company     Active      Company     Active      Company     Active
001        ATT         Y           VZ          Y            TM         Y
002        ATT         N           VZ          N            TM         Y
003        ATT         Y           VZ          Y            TM         Y

假设:

  • 这可能是一张很长的桌子, 这就是为什么他们想要看到所有 公司在一排,而不是 需要向下滚动以查看是否 是否活跃。
    • 数十家公司 在大多数情况下是1-3之间

感谢任何帮助。

谢谢!

3 个答案:

答案 0 :(得分:3)

查询的版本可能如下所示:

SELECT
   CustList.CustomerId
  ,t1.Company
  ,t1.Active
  ,t2.Company
  ,t2.Active
  ,t3.Company
  ,t3.Active
 from (select distinct CustomerId from MyTable) CustList
  left outer join MyTable t1  --  outer join, in case a customer might not "have" a given company
   on t1.CustomerId = CustList.CustomerId
  left outer join MyTable t2
   on t2.CustomerId = CustList.CustomerId
  left outer join MyTable t3
   on t3.CustomerId = CustList.CustomerId
 where t1.Company = 'Att'
  and t2.Company = 'VZ'
  and t3.Company = 'TM'

但是,除非您提前知道公司名称是什么以及公司名称有多少,否则您将拥有 构建查询并每次动态运行它,通过:

  • 首先确定要包含的公司列表
  • 遍历该列表并为每个公司(t1,t2等)添加语句(列,连接,位置和/)
  • 动态执行查询

挑剔,但可行。

- 编辑---------------------------------

螺母。我仍然遇到外连接问题。 (我想如果我在真实的桌子上写这个,我会把它弄好......)

我认为查询在第一个之后与每个外连接“链接”太多行。试试这个:

SELECT 
   CustList.CustomerId 
  ,t1.Company 
  ,t1.Active 
  ,t2.Company 
  ,t2.Active 
  ,t3.Company 
  ,t3.Active 
 from (select distinct CustomerId from MyTable) CustList 
  left outer join MyTable t1  --  outer join, in case a customer might not "have" a given company 
   on t1.CustomerId = CustList.CustomerId 
    and t1.Company = 'ATT'
  left outer join MyTable t2 
   on t2.CustomerId = CustList.CustomerId 
    and t2.Company = 'VZ'
  left outer join MyTable t3 
   on t3.CustomerId = CustList.CustomerId 
    and t3.Company = 'TM'

在测试或计算出错误时,请尝试为一家公司运行,然后逐个添加公司,看看会发生什么。

答案 1 :(得分:0)

如果公司列表总是限于完全相同的值集合(您在评论中建议的那样),则可以使用the PIVOT feature(SQL Server 2005及更高版本):

SELECT CustomerID, [ATT], [VZ], [TM]
FROM (/* whatever gave you that result set above */) AS NormalizedData
PIVOT (MAX(Active) FOR Company IN ([ATT],[VZ],[TM])) AS PivotedData

MAX()仅在那里,因为你必须使用PIVOT的聚合函数;如果公司只有一个价值,这应该不是问题。

这不会提供与您要求的结果集完全相同的结果集。如果指定的输出列列表是必需的,请将select子句更改为:

SELECT
    CustomerID,
    -- Use CASE so output is NULL if Active column is NULL
    -- If you don't care, use: 'ATT' AS Company
    CASE WHEN [ATT] IS NOT NULL THEN 'ATT' END AS Company,
    [ATT] AS Active,
    CASE WHEN [VZ] IS NOT NULL THEN 'VZ' END AS Company,
    [VZ] AS Active,
    CASE WHEN [TM] IS NOT NULL THEN 'TM' END AS Company,
    [TM] AS Active

但是,我认为他们会更喜欢浓缩输出,因为它可以更容易地比较所有值。

如果特定公司没有行,它将在该列中返回NULL。遗憾的是,我不知道如何使PIVOT列列表动态(从SQL Server 2005开始 - 没有看过2008)没有使用动态sql。因此,如果添加另一家公司(例如,'SPR'),您将不得不返回并更改查询。

您可能想要做的另一件事就是通过添加:

直接检查重复项
WHERE CustomerID IN
    (SELECT CustomerID FROM (/* original query */) Data
    GROUP BY CustomerID, Active HAVING COUNT(*) > 1)

这会将输出列表限制为仅包含多个Active标记的项目。这可以添加到原始查询或透视查询中,但使用透视查询可以直接与输出列进行比较,并避免使用其他子查询。当您可以让计算机为您完成时,手动扫描值列表是没有意义的。

答案 2 :(得分:-1)

最好的办法是通过动态SQL来实现这一目标。