使用FOR XML困境的SQL Server Concatenate

时间:2016-04-13 16:06:22

标签: sql sql-server

我来自oracle背景所以在这个网站上进行搜索时,我发现了无数关于如何使用FOR XML PATH来尝试复制LISTAGG()将在oracle中做什么的例子。但是我不知道我想要做的是在那个范围之外还是我不知道我错过了什么。我发现的每个例子都只使用一个密钥id,在我的例子中,我必须使用多个表中的连接。

以下是表格外观的布局。

CREATE TABLE driven_product
([PRODUCT_ID] int, [DRIVER_ID] int, [DRIVER_PRODUCT_INPUT_NUM] int);

INSERT INTO driven_product
([PRODUCT_ID], [DRIVER_ID], [DRIVER_PRODUCT_INPUT_NUM])
VALUES (1, 2, 3);

CREATE TABLE product_input
([PRODUCT_ID] int, [PRODUCT_INPUT_NUM] int, [PRODUCT_VALUE_NUM] int, [COLOR] VARCHAR (50));

INSERT INTO product_input
([PRODUCT_ID], [PRODUCT_INPUT_NUM], [PRODUCT_VALUE_NUM], [COLOR])
 VALUES
   (1, 3, 1, 'White'),
   (1, 3, 2, 'Blue'),
   (1, 3, 3, 'Green'),
   (1, 3, 4, 'Yellow'),
   (1, 3, 5, 'Orange');

CREATE TABLE driven_price
[PRODUCT_ID] int, [DRIVER_ID] int, [PRODUCT_VALUE_NUM] int, [PRICE] int);

INSERT INTO driven_price
([PRODUCT_ID], [DRIVER_ID], [PRODUCT_VALUE_NUM], [PRICE])
VALUES
   (1, 2, 1, 10),
   (1, 2, 2, 10),
   (1, 2, 3, 10),
   (1, 2, 4, 20),
   (1, 2, 5, 20);

driven_product表使用driven_product.product_id = product_input.product_id AND driven_product.driver_product_input_num = product_input.product_input_num连接到product_input表。 driven_price表连接使用 driven_product.product_id = driven_price.product_id,driven_product.driver_id = driven_price.driver_id,product_input.product_value_num = driven_product.product_value_num。

我最接近的是:

SELECT STUFF((SELECT '/' + color
              FROM product_input pi
              WHERE pi.product_id = dp.product_id
              AND pi.product_input_num = dp.product_input_num
              FOR XML PATH( '')), 1, 1, ''), dpr.price
FROM driven_product dp
INNER JOIN driven_price dpr ON dp.product_id = dpr.product_id
AND dp.driven_id = dpr.driven_id

这将所有颜色组合成每个价格。

现在显而易见的是,我没有将product_input.product_value_num加入至driven_price.product_value_num。当我这样做时,它会将每种颜色分解成自己的行。

所以这就是我在努力的地方,我需要按价格来做。所以我需要将“白色,蓝色,绿色”和“黄色,橙色”分开。

我试图在SQLFiddle上设置它,但我一直在收到错误。我们将非常感谢您提供的任何指导。

2 个答案:

答案 0 :(得分:1)

你可以使用group by或distinct ..但你的主要问题是你没有按PRICE过滤你的FOR XML查询,所以你得到了所有的颜色。

SELECT  DISTINCT
        Products = STUFF((
                SELECT '/' + color
                FROM    driven_price dp2
                        JOIN product_input pi ON dp2.Product_Value_Num = PI.Product_Value_Num
                WHERE   dp2.driver_id = dpr.driver_id AND dp2.Price = dp.Price
                FOR XML PATH('')), 1, 1, ''),
        dp.[Price]
FROM    driven_product dpr
        JOIN product_input pri ON dpr.Driver_product_input_num = pri.PRODUCT_INPUT_NUM
        JOIN driven_price dp ON pri.product_id = dp.product_id 
            AND pri.product_value_num = dp.product_value_num

答案 1 :(得分:0)

您需要在外部查询中使用聚合。我认为这会做你想要的:

SELECT dpr.price,
       (SELECT '/' + pi.color
        FROM product_input pi join
             driven_product dp INNER JOIN
             ON pi.product_id = dp.product_id AND
                pi.product_input_num = dp.product_input_num
        WHERE dp.product_id = dpr.product_id
        FOR XML PATH(''))
       )
FROM driven_price dpr
GROUP BY dpr.price;

注意:您只需要stuff()来处理中缀分隔符。如果您对“/ blue / green / red”感到满意,那么您不需要它。 stuff()的目的是删除一个前导的分隔符,因此“蓝色,绿色,红色”变为“蓝色,绿色,红色”。