SQL查询设计不佳的数据库

时间:2016-01-24 20:09:31

标签: sql-server xml tsql

我有一个包含数据的表格,如下所示:

input = paste0(path, "/T", i, ".tif")

我需要找到一种方法,将这些数据查询到更好的格式化结果列表或可能是XML文件。请注意,TableID Vendor ID DETAILS 1 SYS *Hamburger Rolls <*Hamburger Rolls> 2 SYS *WHEAT <WHEAT> 3 SYS *2.99 <2.99> 4 SYS *1364 <1364> 5 SYS *WHITE <WHITE> 6 SYS *1.99 <1.99> 7 SYS *1363<1363> 8 SYS *Hotdog Rolls <*HotDog Rolls> 9 SYS *WHEAT <WHEAT> 10 SYS *WHITE <WHITE> 11 SYS *1.49 <1.49>列中的数据按顺序排列,项目名称下方的所有内容都与项目相关联。我喜欢结果集:

Details

VendorID	Item	            ItemType	Price	ItemID
SYS	        Hambergurer Rolls	Wheat	    2.99	1364
SYS	        Hambergurer Rolls	White	    1.99	1363
SYS	        HotDog Rolls	    Wheat		
SYS	        HotDog Rolls	    White	    1.49

但是我很难生成查询,无论是以我需要的方式格式化数据。请帮忙!

2 个答案:

答案 0 :(得分:0)

这个怎么样?

DECLARE @tbl TABLE(TableID INT,Vendor_ID VARCHAR(10),DETAILS VARCHAR(100));
INSERT INTO @tbl VALUES
 (1,'SYS','*Hamburger Rolls <*Hamburger Rolls>')
,(2,'SYS','*WHEAT <WHEAT>')
,(3,'SYS','*2.99 <2.99>')
,(4,'SYS','*1364 <1364>')
,(5,'SYS','*WHITE <WHITE>')
,(6,'SYS','*1.99 <1.99>')
,(7,'SYS','*1363<1363>')
,(8,'SYS','*Hotdog Rolls <*HotDog Rolls>')
,(9,'SYS','*WHEAT <WHEAT>')
,(10,'SYS','*WHITE <WHITE>')
,(11,'SYS','*1.49 <1.49>');

WITH CleanedData AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY tbl.TableID) RowInx
          ,tbl.TableID
          ,tbl.Vendor_ID
          ,RTRIM(SUBSTRING(tbl.DETAILS,2,CHARINDEX('<',tbl.DETAILS)-2)) AS DetailsClean
          ,CASE WHEN SUBSTRING(InnerInfo.Data,1,1)='*' THEN 'Product'
                WHEN ISNUMERIC(InnerInfo.Data)=1 AND CHARINDEX('.',InnerInfo.Data)>0 THEN 'Price'
                WHEN ISNUMERIC(InnerInfo.Data)=1 THEN 'ItemID'
                ELSE 'MadeOf' END AS LineType  
    FROM @tbl AS tbl
    CROSS APPLY
    (
        SELECT REPLACE(REPLACE(SUBSTRING(tbl.DETAILS,CHARINDEX('<',tbl.DETAILS),1000),'<',''),'>','')
    ) AS InnerInfo(Data)
)
,DistinctVendors AS
(
    SELECT DISTINCT Vendor_ID 
    FROM CleanedData 
)
SELECT dv.Vendor_ID AS [@Vendor_ID]
      ,(
         SELECT cd1.DetailsClean AS [@Product]
               ,(
                  SELECT cd2.DetailsClean AS [@MadeOf]
                               ,(
                                  SELECT cd3.DetailsClean AS [@Price]
                                  FROM CleanedData AS cd3
                                  WHERE cd3.Vendor_ID=dv.Vendor_ID
                                    AND cd3.RowInx BETWEEN cd2.RowInx+1 AND cd2.RowInx+3
                                    AND cd3.LineType='Price'
                                  FOR XML PATH('Price'),TYPE
                                )
                               ,(
                                  SELECT cd3.DetailsClean AS [@ItemID]
                                  FROM CleanedData AS cd3
                                  WHERE cd3.Vendor_ID=dv.Vendor_ID
                                    AND cd3.RowInx BETWEEN cd2.RowInx+1 AND cd2.RowInx+3
                                    AND cd3.LineType='ItemID'
                                  FOR XML PATH('ItemID'),TYPE
                                )
                  FROM CleanedData AS cd2
                  WHERE cd2.Vendor_ID=dv.Vendor_ID
                    AND cd2.RowInx BETWEEN cd1.RowInx+1 AND ISNULL(
                                                            (SELECT TOP 1 x.RowInx 
                                                             FROM CleanedData AS x 
                                                             WHERE x.LineType='Product' 
                                                              AND  x.RowInx>cd1.RowInx 
                                                             ORDER BY x.RowInx DESC)-1,100000)
                    AND cd2.LineType='MadeOf'
                  FOR XML PATH('MadeOf'),TYPE
                )
         FROM CleanedData AS cd1 
         WHERE cd1.Vendor_ID=dv.Vendor_ID
           AND cd1.LineType='Product'
         FOR XML PATH('Product'),TYPE
       )
FROM DistinctVendors AS dv
FOR XML PATH('Vendor'),ROOT('root')

结果:

<root>
  <Vendor Vendor_ID="SYS">
    <Product Product="Hamburger Rolls">
      <MadeOf MadeOf="WHEAT">
        <Price Price="2.99" />
        <ItemID ItemID="1364" />
      </MadeOf>
      <MadeOf MadeOf="WHITE">
        <Price Price="1.99" />
        <ItemID ItemID="1363" />
      </MadeOf>
    </Product>
    <Product Product="Hotdog Rolls">
      <MadeOf MadeOf="WHEAT">
        <Price Price="1.49" />
      </MadeOf>
      <MadeOf MadeOf="WHITE">
        <Price Price="1.49" />
      </MadeOf>
    </Product>
  </Vendor>
</root>

答案 1 :(得分:0)

我把它放在另一个答案中,以保持两种方法的清洁:

DECLARE @tbl TABLE(TableID INT,Vendor_ID VARCHAR(10),DETAILS VARCHAR(100));
INSERT INTO @tbl VALUES
 (1,'SYS','*Hamburger Rolls <*Hamburger Rolls>')
,(2,'SYS','*WHEAT <WHEAT>')
,(3,'SYS','*2.99 <2.99>')
,(4,'SYS','*1364 <1364>')
,(5,'SYS','*WHITE <WHITE>')
,(6,'SYS','*1.99 <1.99>')
,(7,'SYS','*1363<1363>')
,(8,'SYS','*Hotdog Rolls <*HotDog Rolls>')
,(9,'SYS','*WHEAT <WHEAT>')
,(10,'SYS','*WHITE <WHITE>')
,(11,'SYS','*1.49 <1.49>');

WITH CleanedData AS
(
    SELECT ROW_NUMBER() OVER(ORDER BY tbl.TableID) RowInx
          ,tbl.TableID
          ,tbl.Vendor_ID
          ,RTRIM(SUBSTRING(tbl.DETAILS,2,CHARINDEX('<',tbl.DETAILS)-2)) AS DetailsClean
          ,CASE WHEN SUBSTRING(InnerInfo.Data,1,1)='*' THEN 'Product'
                WHEN ISNUMERIC(InnerInfo.Data)=1 AND CHARINDEX('.',InnerInfo.Data)>0 THEN 'Price'
                WHEN ISNUMERIC(InnerInfo.Data)=1 THEN 'ItemID'
                ELSE 'MadeOf' END AS LineType  
    FROM @tbl AS tbl
    CROSS APPLY
    (
        SELECT REPLACE(REPLACE(SUBSTRING(tbl.DETAILS,CHARINDEX('<',tbl.DETAILS),1000),'<',''),'>','')
    ) AS InnerInfo(Data)
)
,DistinctVendors AS
(
    SELECT DISTINCT Vendor_ID 
    FROM CleanedData 
)
SELECT dv.Vendor_ID 
      ,Product.DetailsClean AS Item
      ,MadeOf.DetailsClean AS ItemType
      ,Price.DetailsClean AS Price
      ,ItemID.DetailsClean AS ItemID
FROM DistinctVendors AS dv
CROSS APPLY
(
    SELECT cd1.* 
    FROM CleanedData AS cd1 
    WHERE cd1.Vendor_ID=dv.Vendor_ID
    AND cd1.LineType='Product'
) AS Product
OUTER APPLY
(

    SELECT cd2.*

    FROM CleanedData AS cd2
    WHERE cd2.Vendor_ID=dv.Vendor_ID
    AND cd2.RowInx BETWEEN Product.RowInx+1 AND ISNULL(
                                            (SELECT TOP 1 x.RowInx 
                                                FROM CleanedData AS x 
                                                WHERE x.LineType='Product' 
                                                AND  x.RowInx>Product.RowInx 
                                                ORDER BY x.RowInx DESC)-1,100000)
    AND cd2.LineType='MadeOf'
) AS MadeOf
OUTER APPLY
(

    SELECT cd3.*
    FROM CleanedData AS cd3
    WHERE cd3.Vendor_ID=dv.Vendor_ID
    AND cd3.RowInx BETWEEN MadeOf.RowInx+1 AND MadeOf.RowInx+3
    AND cd3.LineType='Price'
) AS Price
OUTER APPLY
(
    SELECT cd3.*
    FROM CleanedData AS cd3
    WHERE cd3.Vendor_ID=dv.Vendor_ID
    AND cd3.RowInx BETWEEN MadeOf.RowInx+1 AND MadeOf.RowInx+3
    AND cd3.LineType='ItemID'
) AS ItemID

结果

Vendor_ID     Item              ItemType    Price   ItemID
SYS           Hamburger Rolls   WHEAT       2.99    1364
SYS           Hamburger Rolls   WHITE       1.99    1363
SYS           Hotdog Rolls      WHEAT       1.49    NULL
SYS           Hotdog Rolls      WHITE       1.49    NULL