【问题标题】:Dynamic pivot in SQL Server 2000 without using stored procedure or functionSQL Server 2000 中的动态数据透视,不使用存储过程或函数
【发布时间】:2018-12-27 00:54:55
【问题描述】:

我有这两张表:

表 A

    pj    item     desc        pj_id
------------------------------------
    pjA   iphone   cell phone   1
    pjA   macbook  laptop       2
    pjB   windows  os           3

表 B

     pj   item     pj_id  version   date
-----------------------------------------
     pjA  iphone     1      2       2010
     pjA  iphone     1      3       2011
     pjA  macbook    2      0       2000
     pjB  windows    3      5       2008
     pjB  windows    3      6       2014
     pjB  windows    3      7       2017

我想要

   pj    item       desc       detail1   detail2  detail3
---------------------------------------------------------
   pjA   iphone   cell phone   2010(2)   2011(3)
   pjA   macbook   laptop      2000(0)
   pjB   windows     os        2008(5)   2014(6)  2017(7)

您可以看到“详细信息”列是动态的,因为表 B 中没有固定的项目版本号

我们知道,PIVOTFOR XML PATH 在 SQL Server 2000 上不受支持。

所以我搜索了一些解决方案,但他们通常使用存储过程或函数,但我没有此数据库的权限。

对我来说最接近的答案可能是this,但我不知道如何在我的桌子上使用。

任何帮助将不胜感激。

【问题讨论】:

  • 如果您从 Java 或 PHP 等应用程序语言调用 SQL Server,那么最好在表示层中处理此要求。我认为如果不使用动态 SQL,我们就无法做到这一点。
  • @TimBiegeleisen 是的,这也是一个解决方案,但我不知道如何在网格中绑定两个表(我使用 ASP.net)
  • 从 SQL Server 2000 升级的时间是 之前。它不受支持,并且多年来一直不受支持。
  • 我希望至少你的前端不是 Pascal 或其他一些古老的语言......
  • @GordonLinoff 好吧,有时你别无选择

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


【解决方案1】:

我有一个解决方案。您可以使用临时表创建带有 RowNum 列的“详细信息”,然后将 Pj_id 分组。通过使用左连接,您可以将“详细信息”带回。我只做了 3 个“详细信息”。您可以随意扩展。

 declare @tableA table(pj varchar(20), item varchar(50), descb varchar(100), pj_id int)
insert into @tableA
select 'pjA', 'iphone', 'cell phone', 1 union all
select 'pjA', 'macbook', 'laptop', 2 union all
select 'pjB', 'windows', 'os', 3 

declare @tableB table(pj varchar(20), item varchar(50), pj_id int, version int,   vdate int)
insert into @tableB
select 'pjA', 'iphone', 1, 2, 2010 union all
select 'pjA', 'iphone', 1, 3, 2011 union all
select 'pjA', 'macbook', 2, 0, 2000 union all
select 'pjB', 'windows ', 3, 5, 2008 union all
select 'pjB', 'windows', 3, 6, 2014 union all
select 'pjB', 'windows',3,  7, 2017

declare @Details table(pj_id int, Detail varchar(100), RowNum int)----IDENTITY(1,1)
insert into @Details
SELECT pj_id,
        Detail=cast(vdate as varchar(20))+'('+cast(SUM(version) as varchar(20))+')',
        RowNum = (SELECT COUNT(*) ---Simulating Row_num here
                 FROM @tableB i 
                WHERE i.pj_id  = o.pj_id 
                  AND cast(i.vdate as varchar(20))<=cast(o.vdate as varchar(20))  )
   FROM @tableB  o
group  by
pj_id, cast(o.vdate as varchar(20))
  ORDER BY pj_id, Detail




select 
    A.*, 
    detail1=D1.Detail,
    detail2=D2.Detail,
    detail3=D3.Detail
from
    @tableA A

left join @Details D1 ON
    D1.pj_id=A.pj_id
    AND 
    D1.RowNum=1

left join @Details D2 ON
    D2.pj_id=A.pj_id
    AND 
    D2.RowNum=2

left join @Details D3 ON
    D3.pj_id=A.pj_id
    AND 
    D3.RowNum=3

我已经模拟了 ROW_NUMBER。

【讨论】:

  • 它说'ROW_NUMBER'不是一个公认的函数名。如何让它在 SQL 2000 上运行?
  • 嗨 Hecxer,请查看修改后的版本。我已经模拟了 ROW_NUMBER。
  • 第 17 行列 'o.vdate' 在选择列表中无效,因为它既不包含在聚合函数或 GROUP BY 子句中。
  • 这里对我有用,但我已经修改了。请再试一次。我将 pj_id, cast(vdate as varchar(20)) 更改为 -> pj_id, cast(o.vdate as varchar(20))
  • 很奇怪。尝试 SQL Server 2016 并且它可以工作,但 SQL 2000 没有
猜你喜欢
  • 1970-01-01
  • 2015-11-12
  • 1970-01-01
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 2014-10-16
  • 2014-07-26
相关资源
最近更新 更多