Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/sql-server-2008/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 2008 从表中创建分层格式的输出_Sql Server 2008_Tsql_Hierarchical - Fatal编程技术网

Sql server 2008 从表中创建分层格式的输出

Sql server 2008 从表中创建分层格式的输出,sql-server-2008,tsql,hierarchical,Sql Server 2008,Tsql,Hierarchical,我有这样一个SQL表: CC Descr C_NO Vol Wt 2050 Des1 123 20 40 2060 Des2 123 30 50 2050 Des1 125 20 40 2060 Des2 125 30 50 2050 Des1 126 20 40 2050 Des1 123 20 40 125 2

我有这样一个SQL表:

CC     Descr  C_NO     Vol   Wt

2050   Des1   123      20    40
2060   Des2   123      30    50
2050   Des1   125      20    40
2060   Des2   125      30    50
2050   Des1   126      20    40
2050
    Des1

 123
    20
    40
 125
    20
    40   
 126
    20
    40

2060
    Des2

 123
    30
    50
 125
    30
    50
我想要这样的输出:

CC     Descr  C_NO     Vol   Wt

2050   Des1   123      20    40
2060   Des2   123      30    50
2050   Des1   125      20    40
2060   Des2   125      30    50
2050   Des1   126      20    40
2050
    Des1

 123
    20
    40
 125
    20
    40   
 126
    20
    40

2060
    Des2

 123
    30
    50
 125
    30
    50
如何使用TSQL代码实现这一点


对于每个始终具有相似Descr值的相似CC值,它会在输出部分中写入的序列中显示与该特定CC值相关的所有C_No、Vol和Wt值。

在tsql代码中不能这样做。您需要在应用程序代码中执行此类操作

我不会这么做。TSQL用于获取数据,然后使用应用程序代码格式化数据。
但是,如果您在Query analyzer中工作,并且只希望输出在那里,则可以尝试以下操作:

DECLARE mytable_cursor CURSOR FOR 
SELECT CC, Descr, C_NO, Vol, Wt
FROM myTable
ORDER BY CC, Descr, C_NO

OPEN mytable_cursor;

FETCH NEXT FROM mytable_cursor 
INTO @CC, @Descr, @C_NO, @Vol, @Wt

SET @oCC = @CC
SET @oDescr = @Descr
SET @oC_NO = @C_NO

WHILE @@FETCH_STATUS = 0
BEGIN
    PRINT @CC;
    WHILE @@FETCH_STATUS = 0 AND @oCC = @CC
    BEGIN    
        PRINT '    ' + @Descr;
        WHILE @@FETCH_STATUS = 0 AND @oDescr = @Descr
        BEGIN
            PRINT ' ' + @C_NO;
            WHILE @@FETCH_STATUS = 0 AND @oC_NO = @C_NO
            BEGIN
                PRINT '    ' + @Vol;
                PRINT '    ' + @WT;

                FETCH NEXT FROM mytable_cursor 
                INTO @CC, @Descr, @C_NO, @Vol, @Wt

            END
            SET @oC_NO = @C_NO
        END             
        SET @oDescr = @Descr
    END             
    SET @oCC = @CC
END     
CLOSE mytable_cursor;
DEALLOCATE mytable_cursor;
或者你可以使用一组。。。使用ROLLUP和CASE,可以在单个查询中获得结果

下面是一个使用破折号而不是空格来确保格式可见的示例:

SELECT (CASE
        WHEN Descr IS NULL THEN CC
        WHEN C_NO IS NULL THEN '----' + Descr
        WHEN Vol IS NULL THEN '--' + C_NO
        WHEN Wt IS NULL THEN '------' + Vol
        ELSE '------' + Wt
        END)
FROM
    (SELECT CC, Descr, C_NO, Vol, Wt
    FROM my
    GROUP BY CC, Descr, C_NO, Vol, Wt
    WITH ROLLUP) AS x
WHERE CC IS NOT NULL
ORDER BY CC, Descr, C_NO, Vol, Wt

按层次顺序表示数据的最佳方法之一是使用XML。更重要的是,XML的使用往往与出色的性能有关

使用您的示例信息和这段代码:

;WITH DistinctValues (CC,Descr ) AS
(
    SELECT DISTINCT CC,Descr 
    FROM @TableOne
)
SELECT  (
            SELECT  CC AS "CC/@CC"
                   ,Descr AS "CC/Descr"
                   ,(
                        SELECT C_NO AS "C_NO/@C_NO",
                               Vol AS "C_NO/Vol",
                               Wt AS "C_NO/Wt"
                        FROM @TableOne AS Data
                        WHERE Data.CC=DV.CC AND Data.Descr=DV.Descr
                        FOR XML PATH(''),TYPE
                   ) AS  "CC"
            FROM DistinctValues AS DV
            FOR XML PATH(''),TYPE
        )
FOR XML PATH('Source'),TYPE
我得到以下结果(以上述语句返回的一行形式):

这就像一个魔咒,在Microsoft SQL Server Management Studio 2012上进行了测试。

试试这个

 DECLARE @t TABLE
(
    CC BIGINT,
    Descr NVARCHAR(10),
    C_NO INT,
    Vol SMALLINT,
    WT SMALLINT
)

INSERT INTO @t(CC,Descr,C_NO,Vol,WT)
VALUES  (2050,'Des1',123,20,40)
       ,(2060,'Des2',123,30,50)
       ,(2050,'Des1',125,20,40)
       ,(2060,'Des2',125,30,50)
       ,(2050,'Des1',126,20,40)



;WITH CTE1 AS(
    SELECT 
        t1.CC
        ,t1.Descr
        ,MergedColumn = STUFF(
            (SELECT 
                    ',' 
                    + CAST(C_NO AS VARCHAR(10)) + '/' + CAST(Vol AS VARCHAR(10)) + '/' + CAST(Wt AS VARCHAR(10)) 
            FROM @t AS t2
            WHERE t2.CC=t1.CC AND t2.Descr=t2.Descr
            FOR XML PATH('')),1,1,'')
FROM  @t t1
GROUP BY t1.CC,t1.Descr) 
,CTE2 AS
(
    SELECT
            X.CC
            ,X.Descr
            ,Y.SplitDataByComma         
    FROM
        (
            SELECT 
                    *,
                    CAST('<X>'+REPLACE(F.MergedColumn,',','</X><X>')+'</X>' AS XML) AS xmlfilter 
            FROM CTE1 F
        )X
    CROSS APPLY
    ( 
        SELECT fdata.D.value('.','varchar(50)') AS SplitDataByComma 
        FROM X.xmlfilter.nodes('X') AS fdata(D)
    )Y
)
,CTE3 AS
(
    SELECT
            X.CC
            ,X.Descr
            ,Y.SplitDataBySlash         
            , X.SplitDataByComma AS GrpID
            ,ROW_NUMBER() OVER( PARTITION  BY X.SplitDataByComma ORDER BY X.CC,X.Descr ) AS Rn
            ,X.SplitDataByComma + CAST(CC AS Varchar(200)) + CAST(Descr AS Varchar(200))   CC_Descr 
    FROM
        (
            SELECT 
                    *,
                    CAST('<X>'+REPLACE(F.SplitDataByComma,'/','</X><X>')+'</X>' AS XML) AS xmlfilter 
            FROM CTE2 F
        )X
    CROSS APPLY
    ( 
        SELECT fdata.D.value('.','varchar(50)') AS SplitDataBySlash 
        FROM X.xmlfilter.nodes('X') AS fdata(D)
    )Y
)
,CTE4 AS
(
    SELECT  
        Rn = ROW_NUMBER() OVER(PARTITION BY CC ORDER BY CC)     
        ,CC
        ,Descr      
        ,CASE WHEN  Rn = 1 THEN CAST (SplitDataBySlash AS VARCHAR(10)) ELSE ' '  END C_NO
        ,CASE WHEN  Rn = 1 THEN ' ' ELSE CAST (SplitDataBySlash AS VARCHAR(10)) END Vol_Wt
        ,GrpID  
    FROM Cte3
)
,CTE5 AS(
SELECT 
        CC =  CASE WHEN Rn > 1 THEN ' ' ELSE CAST(CC AS Varchar(200)) END 
        ,Descr =  CASE WHEN Rn > 1 THEN ' ' ELSE CAST(Descr AS Varchar(200)) END 
        ,C_NO
        ,Vol_Wt
        ,GrpID  
FROM Cte4)

SELECT  
          CHAR(10)      
        + REPLICATE(SPACE(1),10) 
        + CAST(CC as VARCHAR(100)) 
        + CHAR(10) 
        + REPLICATE(SPACE(1),15) 
        + Descr
        + CHAR(10)
        + REPLICATE(SPACE(1),10)
        + C_NO
        + CHAR(10) 
        + REPLICATE(SPACE(1),15)
        + Vol_Wt
FROM CTE5
在网格模式下(CTRL+D),结果是

(No column name)
      2050
           Des1
      123 
           20           
           40
      125           
           20           
           40
      126
           20
           40

      2060
           Des2
      123
           30
           50
      125
           30
           50

但是,SQL Server(或任何数据库)不是其他人所谈论的格式化的地方。请查看这个问题。

你的问题措辞很好,但我建议你考虑用不同的语言来做。TSQL不以其格式著称。同意这一点,你最好在你的C#代码中这样做,所以没有其他方法可以使用光标?也许你可以回答为什么要在TSQL中这样做的问题?你不应该这样做是TSQL,但这是可能的。
(No column name)
      2050
           Des1
      123 
           20           
           40
      125           
           20           
           40
      126
           20
           40

      2060
           Des2
      123
           30
           50
      125
           30
           50