将结果集行显示为列

时间:2010-11-11 19:04:20

标签: sql-server tsql sql-server-2000

我有一个只返回一条记录的SQL存储过程。但是,在该proc中,是一个子查询,可以返回多行。我认为最好设计子查询以返回多行的一行,而不是多行。

如何写出子查询以便返回列 目前查询是:

SET @Pkg_Status = (Select lf.name, edi.Date from EdiPackage edi, Labelfeed lf
     Where edi.orderID = @OrderID
     AND edi.code = lf.code
     AND lf.labelID = 'EDIStage')  

上述查询的示例结果集将为:

Column 1             Column 2  
Field1.Value1     Field2.Value1  
Field1.Value2     Field2.Value2  
Field1.Value3     Field2.Value3  

相反,我希望结果是:

Column 1      | Column2       | Column3       | Column4      |  Column 5       | Column 6  
Field1.Value1 | Field2.Value1 | Field1.Value2 | Field2.Value2 | Field1.Value3 | Field2.Value3

如何做到这一点?

3 个答案:

答案 0 :(得分:4)

首先,在连接两个表时应使用ISO Join关键字,而不是通过逗号分隔表,然后在Where子句中“连接”它们。所以我们的查询是:

Select LF.name, EDI.Date 
From EdiPackage As EDI
    Join LabelFeed As LF
        On LF.Code = EDI.Code
Where EDI.orderID = @OrderID
    And LF.labelID = 'EDIStage'

其次,您的原始示例是将查询结果设置为变量。这不适用于多列或多行。最好的情况是,SQL可能只是占用子查询中的第一列。最后,你听起来像是一个交叉的东西。我们需要查看数据,但您可以通过这样做来实现您想要的目标:

Select Min( Case When LF.Name = 'Value1' Then LF.Name End ) As Col1
    , Min( Case When LF.Name = 'Value1' Then EDI.Date End ) As Col2
    , Min( Case When LF.Name = 'Value2' Then LF.Name End ) As Col3
    , Min( Case When LF.Name = 'Value2' Then EDI.Date End ) As Col4
    , Min( Case When LF.Name = 'Value3' Then LF.Name End ) As Col5
    , Min( Case When LF.Name = 'Value3' Then EDI.Date End ) As Col6
From EdiPackage As EDI
    Join LabelFeed As LF
        On LF.Code = EDI.Code
Where EDI.orderID = @OrderID
    And LF.labelID = 'EDIStage'

在这种情况下,您可以将'Value1','Value2'和'Value3'替换为应该用于区分一列与另一列的数据值。

答案 1 :(得分:0)

您应该编写一个存储过程,该存储过程将创建一个新的内存表,您可以动态地向其添加列,并且每列将具有不同的行。

答案 2 :(得分:0)

在SQL 2005及更高版本中,您将使用pivot。

如果列数已修复,请使用Thomas给出的答案。

否则,要将它们压成一个区域,你会做类似

的事情
Declare @Pkg_Status Character Varying(8000)
Select @Pkg_Status = 
  Coalesce(@Pkg_Status + ',' + LF.Name + ',' + Cast(EDI.Date As Character Varying),
           LF.Name + ',' + Cast(EDI.Date As Character Varying))
From
  dbo.EDIPackage As EDI
  Inner Join dbo.LabelFeed As LF
    On EDI.Code = LF.Code
Where
  (EDI.OrderID = @OrderID)
  And (LF.LabelID = 'EDIStage')