2016-01-24 4 views
1

У меня есть таблица с данными в нем, как следующее:SQL Query для плохо разработанной базы данных

TableID \t Vendor ID \t DETAILS 
 
1 \t  SYS \t   *Hamburger Rolls <*Hamburger Rolls> 
 
2 \t  SYS \t   *WHEAT <WHEAT> 
 
3 \t  SYS \t   *2.99 <2.99> 
 
4 \t  SYS \t   *1364 <1364> 
 
5 \t  SYS \t   *WHITE <WHITE> 
 
6 \t  SYS \t   *1.99 <1.99> 
 
7 \t  SYS \t   *1363<1363> 
 
8 \t  SYS \t   *Hotdog Rolls <*HotDog Rolls> 
 
9 \t  SYS \t   *WHEAT <WHEAT> 
 
10 \t  SYS \t   *WHITE <WHITE> 
 
11 \t  SYS \t   *1.49 <1.49>

мне нужно найти способ слишком запросить эти данные в более форматированном список результатов или, возможно, XML-файл. Обратите внимание, что данные в столбце Details идут в порядке, где все под именем элемента связано с элементом. Идентификатор как результат установлен вдоль линий:

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

или

<SYS> 
 
    <Hamburger Rolls> 
 
      <Wheat> 
 
\t   <Price>2.99</Price> 
 
       <ItemID>1364</ItemID> 
 
      </Wheat> 
 
      <White> 
 
       <Price>1.99</Price> 
 
       <ItemID>1363</ItemID> 
 
      <White> 
 
    </Hamburger Rolls>

Но я с трудом генерации запроса либо способом который будет форматировать данные так, как мне это нужно. Пожалуйста помоги!

+0

Есть ли шанс получить качество строки? Сначала это выглядит как Product, а затем три слота, состоящий из «made», price и itemid. Но у вас есть Hotdog Rolls, где эта информация неполна ... – Shnugo

+1

Но откуда вы знаете, какая из строк действительно является именем элемента? И как вы можете сказать, глядя на строку, является ли она новой строкой или атрибутом в старой строке? –

+0

@GordonLinoff, я взял ведущий «*» в расширении XML-типа как знак нового продукта, качество которого является числовым с «.». как цена, будучи числовой без "." кажется ItemID, и то, что остается, является ItemType ... Как говорится в заголовке: ** очень ** плохо отформатирован :-) – Shnugo

ответ

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 
+0

Спасибо, я еще не пробовал, но я верю, что это выполнит то, что мне нужно. Огромное спасибо. – user2417949

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> 
Смежные вопросы