SQL加入Null的字段

时间:2017-04-03 18:53:42

标签: sql join string-matching

我试图匹配两个表,其中一个表将多个值存储为字符串。

在下面的示例中,我需要使用#NewProduct.NewProductId对从#Orders表中订购的每个产品进行分类。

我遇到的问题有时会推出像#34; Black Shirt"这样的新产品, 然后我们开始对该产品进行改编,例如" Black Shirt Vneck"。

我需要将两个更改正确匹配到#Orders表。因此,如果订单有黑色和衬衫,但不是Vneck,它被认为是"黑衬衫",但如果订单有黑色和衬衫和Vneck,它被认为是&# 34;黑色Vneck衬衫。"

下面的代码就是一个例子 - 我使用的当前逻辑使用Left Join返回重复项。 另外,假设我们可以修改#NewProducts的格式,但不能修改#Orders的格式。

IF              OBJECT_ID('tempdb.dbo.#NewProducts') IS NOT NULL DROP TABLE #NewProducts
CREATE TABLE    #NewProducts 
(
      ProductType VARCHAR(MAX)
    , Attribute_1 VARCHAR(MAX)
    , Attribute_2 VARCHAR(MAX)
    , NewProductId INT
)

INSERT      #NewProducts
VALUES
    ('shirt', 'black', 'NULL', 1),
    ('shirt', 'black', 'vneck', 2),
    ('shirt',  'white', 'NULL', 3)


IF              OBJECT_ID('tempdb.dbo.#Orders') IS NOT NULL DROP TABLE #Orders
CREATE TABLE    #Orders
(
      OrderId INT
    , ProductType VARCHAR(MAX)
    , Attributes    VARCHAR(MAX)
)

INSERT  #Orders
VALUES
    (1, 'shirt', 'black small circleneck'),
    (2, 'shirt', 'black large circleneck'),
    (3, 'shirt', 'black small vneck'),
    (4, 'shirt', 'black small vneck'),
    (5, 'shirt', 'white large circleneck'),
    (6, 'shirt', 'white small vneck')

SELECT      *
FROM        #Orders o
        LEFT JOIN #NewProducts np
            ON o.ProductType = np.ProductType
            AND CHARINDEX(np.Attribute_1, o.Attributes) > 0
            AND (
                    CHARINDEX(np.Attribute_2, o.Attributes) > 0
                OR np.Attribute_2 = 'NULL'
                )

2 个答案:

答案 0 :(得分:1)

您似乎想要最长的重叠:

SELECT *
FROM #Orders o OUTER APPLY
     (SELECT Top (1) np.*
      FROM #NewProducts np
      WHERE o.ProductType = np.ProductType AND
            CHARINDEX(np.Attribute_1, o.Attributes) > 0
      ORDER BY ((CASE WHEN CHARINDEX(np.Attribute_1, o.Attributes) > 0 THEN 1 ELSE 0 END) +
                (CASE WHEN CHARINDEX(np.Attribute_2, o.Attributes) > 0 THEN 1 ELSE 0 END)
               ) DESC
     ) np;

我不能说我很高兴有这样的需要。看起来Orders应该包含引用实际产品的数字 ID。但是,我可以看到这样的事情有时是必要的。

答案 1 :(得分:0)

我无法得到戈登对工作的回答,并且当他进来时,我的回答是他的一部分。他对最大重叠的想法有所帮助。我已经调整了你的Orders表,以便即使create table #NewProduct ( NewProductID int primary key, ProductType varchar(max), ProductName varchar(max) ) create table #Attribute ( AttributeID int primary key, AttributeName varchar(max) ) create table #ProductAttribute ( NewProductID int, AttributeID int ) insert into #NewProduct values (1, 'shirt', 'black shirt'), (2, 'shirt', 'black vneck shirt'), (3, 'shirt', 'white shirt') insert into #Attribute values (1, 'black'), (2, 'white'), (3, 'vneck') insert into #ProductAttribute values (1,1), (2,1), (2,3), (3,2) select top 1 with ties * from ( select o.OrderId, p.NewProductID, p.ProductType, p.ProductName, o.Attributes, sum(case when charindex(a.AttributeName,o.Attributes)>0 then 1 else 0 end) as Matches from #Orders o JOIN #Attribute a ON charindex(a.AttributeName,o.Attributes)>0 JOIN #ProductAttribute pa ON a.AttributeID = pa.AttributeID JOIN #NewProduct p ON pa.NewProductID = p.NewProductID AND o.ProductType = p.ProductType group by o.OrderId, p.NewProductID, p.ProductType, p.ProductName, o.Attributes ) o2 order by row_number() over (partition by o2.OrderID order by o2.Matches desc) 表不能,也会对这一部分进行“规范化”。代码低于或rextester.com/ERIF13021

{{1}}