Sql 构造一个二进制值表,指示另一个表中是否存在条目

Sql 构造一个二进制值表,指示另一个表中是否存在条目,sql,sql-server,pivot,associations,case,Sql,Sql Server,Pivot,Associations,Case,我有几个表包含不同项目的订单信息。客户的信息可能会在不同的表中多次出现。这些项目对于表是唯一的。我想创建一个新表,显示客户在给定年份购买的所有商品。每个项目应有一列和一个二进制值,指示客户当年是否购买了该项目 换句话说,我想将列出单项订单的所有表格(例如,客户1在2007年11月购买了a项,2007年5月购买了c项)转换为年度交易(例如,客户1在2007年的交易为{a,c}或[1,0,1,0])。我想将单个订单分为年度交易,以便挖掘关联规则 最小工作示例: 表1包含项目a和b的订单。表2包含项目

我有几个表包含不同项目的订单信息。客户的信息可能会在不同的表中多次出现。这些项目对于表是唯一的。我想创建一个新表,显示客户在给定年份购买的所有商品。每个项目应有一列和一个二进制值,指示客户当年是否购买了该项目

换句话说,我想将列出单项订单的所有表格(例如,客户1在2007年11月购买了a项,2007年5月购买了c项)转换为年度交易(例如,客户1在2007年的交易为{a,c}或[1,0,1,0])。我想将单个订单分为年度交易,以便挖掘关联规则

最小工作示例:

表1包含项目a和b的订单。表2包含项目c和d的订单

CREATE TABLE table1
(
orderId INT,
customerId INT,
orderDate DATE,
item VARCHAR(1)
);

CREATE TABLE table2
(
orderId INT,
customerId INT,
orderDate DATE,
item VARCHAR(1)
);

INSERT INTO table1 (orderId, customerId, orderDate, item)
VALUES 
('1', '1', '2007-11-11', 'a'),
('2', '2', '2008-3-20', 'b'),
('3', '3','2009-7-11', 'a');

INSERT INTO table2 (orderId, customerId, orderDate, item)
VALUES 
('4', '2', '2008-1-1', 'c'), 
('5', '1', '2007-5-15', 'c'), 
('6', '1', '2009-2-2', 'd');
我使用一个并集来组合表,因为一些订单ID可能会重叠,即使订单是不同的

SELECT * 
INTO #table3
FROM
(
SELECT *
FROM table1 
UNION ALL 
SELECT * 
FROM table2
) a;
这里是一个解决方案的尝试,但它不是很优雅。更重要的是,它没有按照预期将案例陈述应用于每年

SELECT customerId, 
DATEPART(YEAR, orderDate) as orderYear,
    CASE
        WHEN customerId IN (
            SELECT DISTINCT customerId
            FROM #table3
            WHERE item = 'a')
            THEN 1
        ELSE 0 
    END AS itemA,
    CASE
        WHEN customerId IN (
            SELECT DISTINCT customerId
            FROM #table3
            WHERE item = 'b')
            THEN 1
        ELSE 0 
    END AS itemB,
    CASE
        WHEN customerId IN (
            SELECT DISTINCT customerId
            FROM #table3
            WHERE item = 'c')
            THEN 1
        ELSE 0 
    END AS itemC,
    CASE
        WHEN customerId IN (
            SELECT DISTINCT customerId
            FROM #table3
            WHERE item = 'd')
            THEN 1
        ELSE 0 
    END AS itemD
FROM #table3
ORDER BY customerId, orderDate;
预期结果如下所示:

CREATE TABLE desiredResult
(
customerId INT,
orderYear INT,
itemA INT,
itemB INT,
itemC INT,
itemD INT
);

INSERT INTO desiredResult (customerId, orderYear, itemA, itemB, itemC, itemD)
VALUES 
('1', '2007', '1', '0', '1', '0'), 
('1', '2009', '0', '0', '0', '1'), 
('2', '2008', '0', '1', '1', '0'),
('3', '2009', '1', '0', '0', '0');

有没有更简单的方法来获得我想要的结果?这是PIVOT可能有用的功能吗?

我会使用条件聚合:

SELECT customerId, OrderYear,
       MAX(CASE WHEN item = 'a' THEN 1 ELSE 0 END) as itemA,
       MAX(CASE WHEN item = 'b' THEN 1 ELSE 0 END) as itemB,
       MAX(CASE WHEN item = 'c' THEN 1 ELSE 0 END) as itemC,
       MAX(CASE WHEN item = 'd' THEN 1 ELSE 0 END) as itemD
FROM ((SELECT customerId, year(OrderDate) as OrderYear, item FROM table1
      ) union all
      (SELECT customerId, year(OrderDate) as OrderYear, item FROM table2
      )
     ) t
GROUP BY customerId, orderYear;
这也消除了对临时表的需要