PHP SQL Server-动态表行和列?

PHP SQL Server-动态表行和列?,php,sql-server-2008,pivot,Php,Sql Server 2008,Pivot,我有一个和我之前的问题相似的问题- 在该查询中,我知道将调用行标题,并且只需要动态创建列标题。但是现在,我也不知道行标题 所以我有一个疑问 select eng, count, weekof from dbo.RPT_ENG_WEEK ('2013-03-03', '2013-03-16', '2013-03-03', '2013-03-16') order by eng, weekof asc 返回以下数据: eng count weekof James 11 20

我有一个和我之前的问题相似的问题-

在该查询中,我知道将调用行标题,并且只需要动态创建列标题。但是现在,我也不知道行标题

所以我有一个疑问

select eng, count, weekof from dbo.RPT_ENG_WEEK ('2013-03-03', '2013-03-16', '2013-03-03', '2013-03-16') order by eng, weekof asc
返回以下数据:

eng     count   weekof
James   11      2013-03-03  
James   12      2013-03-10  
Bill    2       2013-03-03  
Gary    15      2013-03-03  
Gary    5       2013-03-10  
Fred    3       2013-03-03  
Fred    2       2013-03-10
所以我想把它变成一行一行,一周一列,如下所示

week:  2013-03-03    2013-03-10
James:     11              12       
Bill:      2               0         
Gary:      15              5            
Fred:      3               2
我在上一个问题中得到的答案很有吸引力,如果我把eng的名称作为静态行输入,但是它可能会返回大约100个eng,并且真的不想手动更新列表


我可能可以通过SQL函数中的游标来解决这个问题,但是有没有更好的方法呢?

将数据从行转换为列被称为。由于您使用的是SQL Server,因此可以使用pivot函数来获得结果

有几种方法可以做到这一点。如果已知数量的
weekof
值,则可以对查询进行硬编码:

select eng, 
  coalesce([2013-03-03], 0) [2013-03-03],  
  coalesce([2013-03-10], 0) [2013-03-10]
from
(
  select eng, [count], weekof
  from RPT_ENG_WEEK
) d
pivot
(
  sum([count])
  for weekof in ([2013-03-03], [2013-03-10])
) piv;

但如果值的数目未知,则需要实现动态SQL以获得结果:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(weekof as date)) 
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT distinct ', coalesce(' + QUOTENAME(cast(weekof as date))+', 0) as '+ QUOTENAME(cast(weekof as date))
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT eng, ' + @colsNull + ' 
            from 
            (
                select eng, [count], cast(weekof as date) weekof
                from RPT_ENG_WEEK
            ) x
            pivot 
            (
                sum([count])
                for weekof in (' + @cols + ')
            ) p '

execute(@query);
|   ENG | 2013-03-03 | 2013-03-10 |
-----------------------------------
|  Bill |          2 |          0 |
|  Fred |          3 |          2 |
|  Gary |         15 |          5 |
| James |         11 |         12 |
看。两者都给出了结果:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(weekof as date)) 
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT distinct ', coalesce(' + QUOTENAME(cast(weekof as date))+', 0) as '+ QUOTENAME(cast(weekof as date))
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT eng, ' + @colsNull + ' 
            from 
            (
                select eng, [count], cast(weekof as date) weekof
                from RPT_ENG_WEEK
            ) x
            pivot 
            (
                sum([count])
                for weekof in (' + @cols + ')
            ) p '

execute(@query);
|   ENG | 2013-03-03 | 2013-03-10 |
-----------------------------------
|  Bill |          2 |          0 |
|  Fred |          3 |          2 |
|  Gary |         15 |          5 |
| James |         11 |         12 |

将数据从行转换为列称为。由于您使用的是SQL Server,因此可以使用pivot函数来获得结果

有几种方法可以做到这一点。如果已知数量的
weekof
值,则可以对查询进行硬编码:

select eng, 
  coalesce([2013-03-03], 0) [2013-03-03],  
  coalesce([2013-03-10], 0) [2013-03-10]
from
(
  select eng, [count], weekof
  from RPT_ENG_WEEK
) d
pivot
(
  sum([count])
  for weekof in ([2013-03-03], [2013-03-10])
) piv;

但如果值的数目未知,则需要实现动态SQL以获得结果:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(weekof as date)) 
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT distinct ', coalesce(' + QUOTENAME(cast(weekof as date))+', 0) as '+ QUOTENAME(cast(weekof as date))
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT eng, ' + @colsNull + ' 
            from 
            (
                select eng, [count], cast(weekof as date) weekof
                from RPT_ENG_WEEK
            ) x
            pivot 
            (
                sum([count])
                for weekof in (' + @cols + ')
            ) p '

execute(@query);
|   ENG | 2013-03-03 | 2013-03-10 |
-----------------------------------
|  Bill |          2 |          0 |
|  Fred |          3 |          2 |
|  Gary |         15 |          5 |
| James |         11 |         12 |
看。两者都给出了结果:

DECLARE @cols AS NVARCHAR(MAX),
    @colsNull AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(cast(weekof as date)) 
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colsNull = STUFF((SELECT distinct ', coalesce(' + QUOTENAME(cast(weekof as date))+', 0) as '+ QUOTENAME(cast(weekof as date))
                    from RPT_ENG_WEEK
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT eng, ' + @colsNull + ' 
            from 
            (
                select eng, [count], cast(weekof as date) weekof
                from RPT_ENG_WEEK
            ) x
            pivot 
            (
                sum([count])
                for weekof in (' + @cols + ')
            ) p '

execute(@query);
|   ENG | 2013-03-03 | 2013-03-10 |
-----------------------------------
|  Bill |          2 |          0 |
|  Fred |          3 |          2 |
|  Gary |         15 |          5 |
| James |         11 |         12 |

您的另一个问题是将MySQL标记为数据库,这是SQL Server,您使用的是什么数据库?两个版本的代码都会非常不同。@bluefeet是的,我知道-这一个来自SQL Server,而不是MySQL(另一个查询是MySQL)。您的另一个问题是将MySQL标记为数据库,这一个是SQL Server,您使用的是什么数据库?这两个版本的代码都会非常不同。@bluefeet是的,我知道-这一个来自SQL Server,而不是MySQL(另一个查询是MySQL),我相当肯定这是voodoo:D绝对精彩@sam.clements LOL,这就是我想确认SQL Server或MySQL的原因,代码非常不同,但您将得到相同的结果。很抱歉出现错误,但我如何在PHP中显示此结果?通常我会按照while($obj=sqlsrv\u fetch\u object($stmt))的思路做一些事情{$eng=$obj->eng;$count=$obj->count;然后显示它,但由于我不知道列标题或行标题,我不确定如何显示它?@sam.clements我不熟悉PHP,我的建议是发布一个新问题。感谢您的帮助-很快就会发布一个新问题!我相当确定这是voodoo:D绝对精彩!@sam.clements LOL,这就是我想确认SQL Server或MySQL的原因,代码非常不同,但您会得到相同的结果。很抱歉出现错误,但我如何在PHP中显示它?通常我会按照while($obj=sqlsrv\fetch\u object($stmt))的思路做一些事情{$eng=$obj->eng;$count=$obj->count;然后显示它,但由于我不知道列标题或行标题,我不确定如何显示它?@sam.clements我不熟悉PHP,我的建议是发布一个新问题。感谢您的帮助-一个新问题很快就会发布!