根据矩阵找到有效组合

Find valid combinations based on matrix

我在 CALC 中有一个以下矩阵:第一行 (1) 包含员工编号,第一列 (A) 包含产品代码。 处处有一个X表示productitem被上面对应的员工售出

     | 0302  |  0303 | 0304 | 0402 |
1625 |  X    |       |   X  |   X  |
1643 |       |    X  |   X  |      |
...

我们看到产品 1643 是由员工 0303 和 0304 销售的

我想看到一份清单,列出哪些员工销售了哪些产品,但格式如下:

1625 | 0302, 0304, 0402 |
1643 | 0303, 0304 |

这样做的原因是我们需要这个矩阵最终导入到SQL服务器table中。我们无法访问该矩阵的起源。它包含大约 50 名员工和 9000 多种产品。

感谢您与我们一起思考!

尝试这样的事情

;with data as
(
SELECT *
FROM   ( VALUES (1625,'X',NULL,'X','X'),
                (1643,NULL,'X','X',NULL))
         cs (col1, [0302], [0303], [0304], [0402]) 
),cte
     AS (SELECT col1,
                col
         FROM   data
                CROSS apply (VALUES ('0302',[0302]),
                                    ('0303',[0303]),
                                    ('0304',[0304]),
                                    ('0402',[0402])) cs (col, val)
         WHERE  val IS NOT NULL)
SELECT col1,
       LEFT(cs.col, Len(cs.col) - 1) AS col
FROM   cte a
       CROSS APPLY (SELECT col + ','
                    FROM   cte B
                    WHERE  a.col1 = b.col1
                    FOR XML PATH('')) cs (col)
GROUP  BY col1,
          LEFT(cs.col, Len(cs.col) - 1) 

我觉得有两个问题需要解决:

  1. 获取 X 标记的产品代码;
  2. 将它们连接成一个逗号分隔的字符串。

我无法一步解决这两个问题,但您可以分别处理这两个问题。

1.

要用相应的产品代码替换 X 标记,您可以使用数组函数创建第二个 table(矩阵)。为此,创建一个新的 sheet,复制第一列/第一行,然后在单元格 B2 中输入以下公式:

=IF($B2:$E3="X";$B:$E;"")

您必须调整公式,使其包含完整的输入数据(如果您的最后一个数据单元格是 Z9999,则它将是 =IF($B2:$Z9999="X";$B:$Z;""))。我的示例仅包含两行和四列。

修改后,用CTRL+SHIFT+ENTER确认为作为数组公式应用.

2.

现在,您必须连接产品代码。 LO Calc 缺少连接数组的功能,但您可以使用简单的用户定义函数。对于这样的字符串连接函数,请参阅 this answer。只需使用此处提供的 StarBasic 代码创建一个新宏并保存即可。现在,您手头有一个 STRJOIN() 函数,它接受一个数组并连接它的值,留下空值。

您可以在第二个 sheet 上使用辅助列添加该功能,然后通过将其向下拖动来应用它。最后,要删除带有单一产品 ID 的单元格,复制完整的第二个 sheet, 特殊粘贴 到第三个 sheet,仅粘贴值。现在,您可以删除除第一列(员工 ID)和最后一列(带有串联的产品 ID)之外的所有列。

我在 sql 中创建了一个 table 用于保存数据:

CREATE TABLE [dbo].[mydata](
    [prod_code] [nvarchar](8) NULL,
    [0100] [nvarchar](10) NULL,
    [0101] [nvarchar](10) NULL,
    [and so on...]

我通过复制和粘贴转置的方式在 Calc 中创建了列列表。之后,我使用连接函数为 create table statement

创建了 columnlist + 数据类型

我清理了工作表并使用 SQL 服务器的导入向导将其导入此 table。清洁意味着去除不必要的 rows/columns。由于列名相同,因此 99% 的映射正确完成。 现在我在 SQL 服务器中有了数据。

我修改了MM93建议的代码:

;with data as
(
SELECT *
FROM   dbo.mydata  <-- here i simply referenced the whole table
),cte

在下一部分中,我使用相同的 'worksheet' 技巧来列出所有列名并设置其格式并将它们粘贴到其中。

),cte
     AS (SELECT prod_code, <-- had to replace col1 with 'prod_code' 
                col
         FROM   data
                CROSS apply (VALUES ('0100',[0100]),
                            ('0101', [0101] ),
                            (and so on... ),

这个查询的结果被插入到一个新的 table 中,我和我的同事正在查询我们的数据:)

PS:删除 'FOR XML' 子句导致 table 包含两列:

prodcode | employee

其中包含 prodcode + employeenumber 的所有独特组合,查询速度更快,更实用。