如何将多个值组合到SQL中的单个列中

时间:2014-06-18 00:41:24

标签: sql sql-server oracle

给出以下SQL

SELECT 
    T1."PN" as "Part Number",
    T2."QTY" as "Quantity",
    T2."BRANCH" AS "Location", T3."STOCK" as "Bin"
FROM 
    "XYZ"."PARTS" T1,
    "XYZ"."BALANCES" T2,
    "XYZ"."DETAILS" T3
WHERE (T2."PART_ID" = T1."PART_ID") AND (T3."PART_ID" = T1."PART_ID")
ORDER BY "Part Number" ASC, "Location" ASC

我们得到的结果如

YZ-7-CA-080                 88  01  STOCK7
YZ-7-CA-080                 88  01  03482 
YZ-7-CA-080                 88  01  A8K2D

对于位置01,有88个部件号YZ-7-CA-080,它们可以在3个箱子STOCK7,03482或A8K2D中的任何一个中找到。 位置值是指像仓库这样的公共分支,数量是整个仓库的数量,而不是仓库。

我需要更改输出,这样我们就可以写出一个带有bin作为列表的条目

YZ-7-CA-080                 88  01  STOCK7,03482,A8K2D

所以我正在寻找一种在SQL中重构结果的好方法。我觉得应该有一种方法来使用函数或子查询或类似的东西,并希望有一个单一的多数据库解决方案,但假设可能需要在不同的dbs上使用不同的解决方案。 (Oracle是我们尝试解决的主要解决方案,但我们需要的第二优先级数据库是SQL Server)。

注意:每个部件号有多个位置,因此不足以在第一列上设置不同以减少多个部件号条目。在位置02处将存在多个相同的部件号也具有相同的问题。

想法?

3 个答案:

答案 0 :(得分:0)

您可以使用子字符串和子查询,在第一列中应用distinct

此问题中描述了类似的技术:Concatenate many rows into a single text string?

答案 1 :(得分:0)

您可以使用listagg()

在Oracle中执行此操作
SELECT T1."PN" as "Part Number", max(T2."QTY") as "Quantity", T2."BRANCH" AS "Location",
       listagg(T3."STOCK") within group (order by  t3.stock) as Bins
FROM "XYZ"."PARTS" T1 JOIN
     "XYZ"."BALANCES" T2
     ON T2."PART_ID" = T1."PART_ID" JOIN
     "XYZ"."DETAILS" T3
     ON T3."PART_ID" = T1."PART_ID"
GROUP BY t1.PN, t2.Branch
ORDER BY "Part Number", "Location";

我还修复了查询以使用正确的显式连接语法。

答案 2 :(得分:0)

对于旧版本,我猜 WM_CONCAT 会起作用。修改Gordon Linoff的查询:

SELECT T1."PN" as "Part Number", max(T2."QTY") as "Quantity", T2."BRANCH" AS "Location",
       WM_CONCAT(T3."STOCK") as Bins
FROM "XYZ"."PARTS" T1 JOIN
     "XYZ"."BALANCES" T2
     ON T2."PART_ID" = T1."PART_ID" JOIN
     "XYZ"."DETAILS" T3
     ON T3."PART_ID" = T1."PART_ID"
GROUP BY t1.PN, t2.Branch
ORDER BY "Part Number", "Location";

另请参阅this链接以获取替代方法:在链接中包含答案以供参考:

create table countries ( country_name varchar2 (100));
insert into countries values ('Albania');
insert into countries values ('Andorra');
insert into countries values ('Antigua');


SELECT SUBSTR (SYS_CONNECT_BY_PATH (country_name , ','), 2) csv
      FROM (SELECT country_name , ROW_NUMBER () OVER (ORDER BY country_name ) rn,
                   COUNT (*) OVER () cnt
              FROM countries)
     WHERE rn = cnt
START WITH rn = 1
CONNECT BY rn = PRIOR rn + 1;

CSV                                                                             
--------------------------
Albania,Andorra,Antigua