根据矩阵找到有效组合
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)
我觉得有两个问题需要解决:
- 获取
X
标记的产品代码;
- 将它们连接成一个逗号分隔的字符串。
我无法一步解决这两个问题,但您可以分别处理这两个问题。
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
的所有独特组合,查询速度更快,更实用。
我在 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)
我觉得有两个问题需要解决:
- 获取
X
标记的产品代码; - 将它们连接成一个逗号分隔的字符串。
我无法一步解决这两个问题,但您可以分别处理这两个问题。
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
的所有独特组合,查询速度更快,更实用。