使用true或false更新sql列

时间:2013-12-12 09:15:07

标签: sql sql-server-2008 if-statement sql-update

我想根据 customer_code列品牌列<更新“品牌A”,“品牌B”和“品牌C”列,其结果为“true”或“false” / b>。

例如,表市场显示以下内容:  我有一个顾客买了A和B品牌:

Customer_code   Brand   Brand A Brand B Brand C
1234567            A    NULL    NULL    NULL
1234567            B    NULL    NULL    NULL


Customer_code   Brand   Brand A Brand B Brand C
1234567           A     True    True    False
1234567           B     True    True    False

由于我有大量数据,所以有什么方法可以解决这个问题吗?

非常感谢你!

3 个答案:

答案 0 :(得分:2)

以这种方式存储数据有很多或冗余:

Customer_code   Brand   Brand A Brand B Brand C
1234567           A     True    True    False
1234567           B     True    True    False

存储它的正常方法就是:

Customer_code   Brand 
1234567           A    
1234567           B   

由于您的真/假列基于前两个数据,因此存储它们是一个坏主意,因为您有另外的任务来保持其准确性。

想象一下,我向你的表中插入了一个新行,即使我为每个品牌插入了正确的true / false值,它仍会使前两行错误:

Customer_code   Brand   Brand A Brand B Brand C
1234567           A     True    True    False
1234567           B     True    True    False
1234567           C     True    True    True

正如我所说,我建议只存储customer_code和品牌,其余的可以从这两列中计算出来。最后,我还建议使用BIT DataType来表示布尔值,而不是将true或false存储为文本(SQL Server中没有布尔类型)。所以你可以创建一个视图:

SELECT  pvt.Customer_Code,
        [Brand A] = CAST(CASE WHEN pvt.[A] > 0 THEN 1 ELSE 0 END AS BIT),
        [Brand B] = CAST(CASE WHEN pvt.[B] > 0 THEN 1 ELSE 0 END AS BIT),
        [Brand C] = CAST(CASE WHEN pvt.[C] > 0 THEN 1 ELSE 0 END AS BIT)
FROM    (   SELECT  Customer_Code, Brand, Value = 1
            FROM    T
        ) T
        PIVOT
        (   COUNT(Value)
            FOR Brand IN ([A], [B], [C])
        ) pvt;

这给出了以下结果:

Customer_code | Brand A | Brand B | Brand C
--------------+---------+---------+----------
1234567       |     1   |     1   |     0

<强> Example on SQL Fiddle

它没有品牌专栏,但这是多余的,因为品牌是每个品牌的位栏所暗示的,因此包括品牌只会导致重复的行。

最后,要真正回答您的问题,您可以使用以下内容实际进行更新:

WITH PVT AS
(   SELECT  Customer_Code, [A], [B], [C]
    FROM    (   SELECT  Customer_Code, Brand, Value = 1
                FROM    T
            ) T
            PIVOT
            (   COUNT(Value)
                FOR Brand IN ([A], [B], [C])
            ) pvt
)
MERGE T
USING PVT
    ON PVT.Customer_Code = T.Customer_Code
WHEN MATCHED THEN UPDATE
    SET [Brand A] = CASE WHEN pvt.A > 0 THEN 'True' ELSE 'False' END,
        [Brand B] = CASE WHEN pvt.B > 0 THEN 'True' ELSE 'False' END,
        [Brand C] = CASE WHEN pvt.C > 0 THEN 'True' ELSE 'False' END;

<强> Example on SQL Fiddle

或SQL Servier特定的UPDATE / FROM语法:

WITH PVT AS
(   SELECT  Customer_Code, [A], [B], [C]
    FROM    (   SELECT  Customer_Code, Brand, Value = 1
                FROM    T
            ) T
            PIVOT
            (   COUNT(Value)
                FOR Brand IN ([A], [B], [C])
            ) pvt
)
UPDATE  T
SET     [Brand A] = CASE WHEN pvt.A > 0 THEN 'True' ELSE 'False' END,
        [Brand B] = CASE WHEN pvt.B > 0 THEN 'True' ELSE 'False' END,
        [Brand C] = CASE WHEN pvt.C > 0 THEN 'True' ELSE 'False' END
FROM    T
        INNER JOIN PVT
            ON PVT.Customer_Code = T.Customer_Code;         

<强> Example on SQL Fiddle

答案 1 :(得分:0)

使用子查询:

UPDATE m
SET Brand_A = CASE WHEN EXISTS(SELECT 1 FROM dbo.Market m2
                               WHERE m.Customer_code = m2.Customer_code
                               AND   m2.Brand = 'A') THEN 1 ELSE 0 END,
    Brand_B = CASE WHEN EXISTS(SELECT 1 FROM dbo.Market m2
                               WHERE m.Customer_code = m2.Customer_code
                               AND   m2.Brand = 'B') THEN 1 ELSE 0 END,
    Brand_C = CASE WHEN EXISTS(SELECT 1 FROM dbo.Market m2
                               WHERE m.Customer_code = m2.Customer_code
                               AND   m2.Brand = 'C') THEN 1 ELSE 0 END
FROM dbo.Market m

Demo

答案 2 :(得分:0)

create table market
(customer_code varchar(200),
brand char(1),
brand_a int,
brand_b int,
brand_c int
);

insert into market values('1234567','A',0,0,0);
insert into market values('1234567','B',0,0,0);

UPDATE market
SET brand_a = a, brand_b = b, brand_c = c
FROM
(
 SELECT customer_code c_code,
 MAX(CASE WHEN brand = 'A' THEN 1 ELSE NULL END) over(PARTITION by customer_code) a,
 MAX(CASE WHEN brand = 'B' THEN 1 ELSE NULL END) over(PARTITION by customer_code) b,
 MAX(CASE WHEN brand = 'C' THEN 1 ELSE NULL END) over(PARTITION by customer_code) c
 FROM market
) aa

WHERE customer_code = c_code;

另外一件事就是删除不需要的列,只将客户和品牌存储在数据库中,稍后再使用查询:

    SELECT 
    customer_code,
    MAX(CASE WHEN brand='A' THEN 1 ELSE 0 END) AS brand_a,
    MAX(CASE WHEN brand='B' THEN 1 ELSE 0 END) AS brand_b,
    MAX(CASE WHEN brand='C' THEN 1 ELSE 0 END) AS brand_c
    FROM market
    GROUP BY customer_code;