SQL - денормализованный экспорт данных в смешанный разделитель плоских файлов - PullRequest
1 голос
/ 31 января 2012

У меня плоский денормализованный стол:

PRODUCT_ID     LOCATION        PARTNUMBER      PRICE   STATUS
1234567890     9999            5555            10.99   A
1234567890     8888            5555            11.99   A
1234567890     7777            5555             9.99   B
9876543210     9999            3333            15.99   A
9876543210     4444            3333            14.99   A
...

Мне нужно запросить это, чтобы получить выходной файл, который выглядит примерно так:

1234567890|9999|5555|10.99|A,8888|5555|11.99|A,7777|5555|9.99|B
9876543210|9999|3333|15.99|A,4444|3333|14.99|A
...

Таким образом, в основном формат данных:

PRODUCT_ID | LOCATION1 | PARTNUMBER1 | price1 | STATUS1, LOCATIONN | PARTNUMBERN | PRICEN, STATUSN ...

Я не уверен, с чего начать ... нужно ли использовать вложенный запрос?

Ответы [ 3 ]

0 голосов
/ 31 января 2012

Есть также способы сделать это без зацикливания, но sql сложнее.

Список мест ограничен и мал?

Если это так, вы можете сделать что-то вродеэто:

select a.product_id || 
     coalesce((select '|' || b.location || '|' || b.partnumber  || '|' || 
                             b.price || '|' || trim(b.status)  || ','
               from session.products b 
               where b.location = '9999' and b.product_id = a.product_id), '') || 

     coalesce((select '|' || c.location || '|' || c.partnumber  || '|' || 
                                 c.price || '|' || trim(c.status)  || ','
               from session.products c 
               where c.location = '8888' and c.product_id = a.product_id), '') 
from (select distinct product_id as product_id from session.products) as a

, где вы расширяете оператор для каждого местоположения.

Есть способы сделать это для неограниченного набора местоположений в SQL, но это не так просто читать / писать /Отладка и решение курсора от + Diego могут быть более желательными.

0 голосов
/ 01 февраля 2012

Интересно, что вы можете сделать это рекурсивно:

WITH Ordered_Data (product_id, orderIndex, dataString) as (
     SELECT product_id, location, partnumber, price, status, 
         ROW_NUMBER() OVER(PARTITION_BY product_id ORDER BY product_id, location ASC),
            product_id || '|' || location || '|' || partnumber || '|' ||     
            price || '|' || status   
     FROM Product_Location),

     Combined_Data(product_id, orderIndex, dataString) as (
     SELECT a.product_id, a.orderIndex, a.dataString
     FROM Ordered_Data as a
     JOIN (SELECT product_id, MAX(orderIndex) as orderIndex
           FROM Ordered_Data 
           GROUP BY product_id) as b
     ON b.product_id = a.product_id
     AND b.orderIndex = a.orderIndex
     UNION ALL
     SELECT b.product_id, a.orderIndex, b.dataString || ',' || a.dataString
     FROM Ordered_Data as a
     JOIN Combined_Data as b
     ON b.product_id = a.product_id
     AND b.orderIndex - 1 = a.orderIndex)

SELECT dataString
FROM Combined_Data
WHERE orderIndex = 1

Что дает ожидаемое:

9876543210|9999|3333|15.99|A,9876543210|4444|3333|14.99|A                            
1234567890|9999|5555|10.99|A,1234567890|8888|5555|11.99|A,1234567890|7777|5555|9.99|B 

Я не даю никаких гарантий того, как быстро это будет выполняться -в частности, вы захотите, чтобы индекс превысил (product_id, location) (или аналогичный, и измените оператор).Я считаю, что DB2 достаточно умна, чтобы читать индикаторы в обратном направлении, поэтому направление не должно иметь большого значения.

В качестве примечания я действительно надеюсь price - это numeric или decimal (точные десятичные дроби), а не float или real.

0 голосов
/ 31 января 2012

вам нужно создать курсор для просмотра таблицы.Используйте переменную, чтобы контролировать, относится ли каждая строка таблицы к одному и тому же продукту или новому продукту.

Примерно так:

DECLARE @OLD_PRODUCT_ID int
set @OLD_PRODUCT_ID = -1

DECLARE MyCursor CURSOR FOR 
select PRODUCT_ID, LOCATION, PARTNUMBER, PRICE, STATUS
FROM YourTable

OPEN MyCursor;

FETCH NEXT FROM MyCursor 
INTO @PRODUCT_ID, @LOCATION, @PARTNUMBER, @PRICE, @STATUS --declare these variables

WHILE @@FETCH_STATUS = 0 BEGIN
    if (@PRODUCT_ID = @OLD_PRODUCT_ID) begin
        -- use the same line
    end ele begin
        -- new product = new line
    end

    @OLD_PRODUCT_ID = @PRODUCT_ID
    FETCH NEXT FROM MyCursor 
    INTO @PRODUCT_ID, @LOCATION, @PARTNUMBER, @PRICE, @STATUS

END
CLOSE MyCursor;
DEALLOCATE MyCursor;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...