根据矩阵查找有效组合

时间:2015-12-07 10:02:02

标签: sql-server tsql ssis libreoffice calc

我在CALC中有以下矩阵:第一行(1)包含员工编号,第一列(A)包含产品代码。 在任何地方都有一个X,产品项目由上面相应的员工出售

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

我们看到产品1643由员工0303和0304出售

我希望看到的是哪些产品由哪些员工销售,但格式如下:

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

这样做的原因是我们需要最终导入SQL SERVER表的矩阵。我们无法访问此矩阵的来源。它包含约50名员工和9000多种产品。

Thanx和我们一起思考!

3 个答案:

答案 0 :(得分:2)

尝试这样的事情

;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 :(得分:1)

我认为有两个问题需要解决:

  1. 获取X标记的产品代码;
  2. 将它们连接成一个逗号分隔的字符串。
  3. 我无法在一个步骤中为这两个问题提供解决方案,但您可以单独处理这两个问题。

    1

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

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

    您必须调整公式,因此它涵盖了您的完整输入数据(如果您的最后一个数据单元格是Z9999,那么它将是=IF($B2:$Z9999="X";$B$1:$Z$1;""))。我的例子只包括两行四列。

    修改后,使用 CTRL + SHIFT + ENTER 确认将其应用为数组公式。< / p>

    2

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

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

答案 2 :(得分:0)

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

Actor

我通过复制和粘贴它们来创建Calc列中的列。之后,我使用concatenate函数为create table语句

创建columnlist +数据类型

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

我修改了代码MM93的建议:

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

在下一部分中,我使用相同的“工作表”技巧列出并格式化所有列名并将其粘贴。

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

此查询的结果已插入新表中,我和我的同事正在查询我们的仇恨:)

PS:删除'FOR XML'子句会产生一个包含两列的表:

),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... ),

包含prodcode | employee 的独特组合,这种组合更快,更实用。