如何“压扁”我的TSQL结果?

时间:2011-10-14 19:32:27

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

前言:我已经遍布stackoverflow.com并谷歌搜索了这个。我已经找到了数百个可能的答案,但要么它不是正确的SQL Server版本,要么根本不适用于SQL Server,而且我并不擅长能够使查询适应SQL Server 2000的TSQL。大多数示例都假设我想做某种聚合 - 我不需要这样做。此外,许多示例都假定行数是固定的(每年四分之一的行转换为4列或租约已知的数字。每行的列数会有不同的数量。

我在SQL Server 2000中有一个存储单词的表。它看起来像这样:

MAPENTRY_ID int NOT NULL
PARENT_ID int NOT NULL
ENCODED varchar(10) NOT NULL

MAPENTRY_ID是主键。 PARENT_ID存储“父”字的MAPENTRY_ID。它是一个单词列表,因为这些单词是CaSe敏感的,所以给定的“父”可能有不止一个“子”字。如果只存在一个单词/个案(下面的例子是“ABC”)那么MAPENTRY_ID将等于PARENT_ID。

一些示例数据如下所示:

MAPENTRY_ID PARENT_ID ENCODED
----------- --------- -------
8274302     8274302   abaco
8274306     8274302   Abaco
8274308     8274302   ABACO
5217985     5217985   abbynormal
5217987     5217985   Abbynormal
5217986     5217985   AbbyNormal
5217990     5217985   ABBYNORMAL
9285        9285      ABC
1144839     1144839   abc123
1144864     1144839   ABC123
5129019     5129019   abcapp
5129020     5129019   AbcApp
5129021     5129019   ABCAPP
8329759     8329759   abdominals
8329757     8329759   Abdominals
8329761     8329759   ABDOMINALS
8278875     8278875   abmill
8278878     8278875   abMill
8278879     8278875   abMILL
8278876     8278875   Abmill
8278877     8278875   AbMill
8278880     8278875   ABMILL
5217983     5217983   abnormal
5217993     5217983   Abnormal
5217994     5217983   ABNORMAL
8199838     8199838   aboutcopd
8199839     8199838   Aboutcopd
8199841     8199838   AboutCopd
8199840     8199838   AboutCOPD
8199845     8199838   ABOUTCOPD
8199733     8199733   aboutpad
8199756     8199733   Aboutpad
8199744     8199733   AboutPad
8199735     8199733   AboutPAD
8199765     8199733   ABOUTPAD
8199767     8199767   aboutrls
8199768     8199767   Aboutrls
8199770     8199767   AboutRls
8199772     8199767   AboutRLS
8199789     8199767   ABOUTRLS
8672422     8672422   abroad
8672423     8672422   Abroad
8672424     8672422   ABROAD
8478426     8478426   absecon
8478525     8478426   Absecon
8478582     8478426   ABSECON
8427765     8427765   absinthe
8427767     8427765   ABSINTHE
8690704     8690704   absolutely
8690705     8690704   Absolutely
8690706     8690704   ABSOLUTELY

在阅读了很多材料后,我尝试了以下SQL:

SELECT MAPENTRY_ID, PARENT_ID, ENCODED
FROM XCO_MASTER
ORDER BY ENCODED, MAPENTRY_ID, PARENT_ID 

它产生的内容在逻辑上是正确的,但看起来更像树结构。它看起来不仅仅是一个好的“排序”......一个小例子是:

MAPENTRY_ID PARENT_ID ENCODED
----------- --------- -------
8274302     8274302   abaco
8274306     8274302   Abaco
8274308     8274302   ABACO
5217985     5217985   abbynormal
5217987     5217985   Abbynormal
5217986     5217985   AbbyNormal
5217990     5217985   ABBYNORMAL
9285        9285      ABC
1144839     1144839   abc123
1144864     1144839   ABC123

我需要看到的结果如下:

MAPENTRY_ID ENCODED    ENCODED    ENCODED    ENCODED
----------- ---------- ---------- ---------- ----------
8274302     abaco      Abaco      ABACO      
5217985     abbynormal Abbynormal AbbyNormal ABBYNORMAL
9285        ABC
1144839     abc123     ABC123

我之所以喜欢它的原因是因为我希望将这些信息显示为网站上的HTML表格。我不会显示整个表格,只显示用户可以搜索的关键字查询的结果。

有没有办法在使用TSQL的SQL Server 2000中执行此操作?我宁愿不在客户端上解析上面的查询结果,以便在可以使用特定类型的查询完成时产生所需的结果。

1 个答案:

答案 0 :(得分:2)

就像一些评论指出的那样,我认为在外面做这件事会更好。

然而在TSQL中你可以这样做:

DECLARE @i int
SET @i = 1
DECLARE @sql_alter nvarchar(4000)
      , @sql_update nvarchar(4000)
      , @sql_select nvarchar(4000)

CREATE TABLE #FLAT_TABLE (FID_0 int, FENCODED_0 varchar(10))
SET @sql_select = N'SELECT FID_0, FENCODED_0'

INSERT INTO #FLAT_TABLE (FID_0, FENCODED_0)
SELECT MAPENTRY_ID
     , ENCODED
  FROM XCO_MASTER
 WHERE MAPENTRY_ID = PARENT_ID

while (@@ROWCOUNT > 0) begin

    SET @sql_select = @sql_select + ', FID_' + @i

    SET @sql_alter = N'
        ALTER TABLE #FLAT_TABLE ADD COLUMN FID_' + @i + N' int
        ALTER TABLE #FLAT_TABLE ADD COLUMN FENCODED_' + @i + N' varchar(10)
    '

    SET @sql_update = N'
        UPDATE #FLAT_TABLE
           SET FID_' + @i + N' = MAPENTRY_ID
             , FENCODED_' + @i + N' = ENCODED
          FROM XCO_MASTER
         WHERE MAPENTRY_ID <> PARENT_ID
           and MAPENTRY_ID = FID_' + (Cast (@i - 1) as nvarchar(8))
    '
    SET @i = @i + 1

    sp_executesql @sql_alter
    sp_executesql @sql_update
end

@sql_select = @sql_select + ' FROM #FLAT_TABLE'
SELECT @sql_select

这只是一个想法,你需要做一些修正(例如演员@i)。

警告

小心@@ROWCOUNT > 0条件,如果你犯了错误,可能会导致无限循环。 您可以使用@@ROWCOUNT > 0 and @i < @MAX_COLUMNS之类的内容来避免任何问题。