2017-06-26 5 views
1

これは初めての投稿です。類似の受注をSQLで検索

私は製造会社で働き、私たちが作っている製品のほとんどはカスタムメードです。 私たちは、販売している製品に共通点があると考えています。

これを行うには、受注を分析し、システム内のすべての受注と比較して、同一のものを見つける必要があります。

+------------------------------+ 
| OrderId ProductCode Qty | 
+------------------------------+ 
| SS1234 Widget1  1 | 
| SS1234 Widget2  3 | 
| SS1234 Widget3  1 | 
+------------------------------+ 

私は同じ製品とSS1234に似て注文、すなわち注文を見つけたいと思います...

enter image description here

など:ここ

は、SQL結果の形で例です(widget1、widget2、widget3)と同じ数量です。

SQL Server 2008 R2でこれを行うにはどうすればよいですか? ご協力いただきありがとうございます! Raf

+1

あなたの編集は、難しい問題を読むようにしました。サンプル入力と期待する出力を、その出力のロジックと一緒に示してください。 –

+0

それでは、productcode = productcodeとqty = qtyとorderid!= orderidの自己結合が好きですか?どれだけ多くの「ウィジェット」が一致する必要がありますか? – ZLK

+0

正確な数量と部品番号に一致するように探していることがわかります。しかし、将来的には、これを拡張して部品番号(色、重量など)の類似性を調べることもできます。より柔軟なアプローチが必要な場合は、コサインの類似性を調べてみてください –

答えて

0

私が夕方に寝る前に、これをテストすることはできません。これはあまり冗長なアプローチですが、私はできるだけ早くこの問題を解決したいので、私はドキュメントに頼る必要がある、より簡潔で効率的なコードを書くのではなく、よく知っている構造/構文を使用しようとしました。基本的には、各オーダーのアイテム数を数え、一致する2つの広告申込情報が見つかるたびに1対のオーダーIDを選択し、正確なオーダーIDのペアが何回表示されるかをカウントします。内部結合を使用して、順序が合っている製品よりも少ない回数で一致したペアを除外します。

WITH 
ProductCounts AS (
SELECT COUNT(OrderID) AS ProductCodesInOrder, OrderID 
FROM Table 
GROUP BY OrderID 
), MatchingLineItems AS (
SELECT A.OrderID AS FirstOrderID, B.OrderID AS SecondOrderID 
FROM Table AS A 
INNER JOIN Table AS B 
ON A.ProductCode = B.ProductCode AND A.Qty = B.Qty 
ORDER BY FirstOrderID, SecondOrderID 
), MatchTotals AS (
SELECT 
COUNT(FirstOrderID) AS Matches, FirstOrderID, SecondOrderID 
FROM MatchingLineItems 
GROUP BY FirstOrderID, SecondOrderID 
), FirstMatches AS (
SELECT MatchTotals.FirstOrderID, MatchTotals.SecondOrderID, MatchTotals.Matches 
FROM MatchTotals 
INNER JOIN ProductCounts 
ON MatchTotals.FirstOrderID = ProductCounts.OrderID 
WHERE MatchTotals.Matches = ProductCounts.ProductCodesInOrder 
) 
SELECT FirstMatches.FirstOrderID, FirstMatches.SecondOrderID 
FROM FirstMatches 
INNER JOIN ProductCounts 
ON FirstMatches.SecondOrderID = ProductCounts.OrderID 
WHERE FirstMatches.Matches = ProductCounts.ProductCodesInOrder 
0

セットアップ:

CREATE TABLE #ord (
    OrderId VARCHAR(20), 
    ProductCode VARCHAR(40), 
    qty int 
) 
INSERT INTO #ord (OrderId, ProductCode, Qty) 
VALUES 
    ('SS1234','Widget1',1) 
,('SS1234','Widget2',3) 
,('SS1234','Widget3',1) 

,('SS1234a','Widget1',1) 
,('SS1234a','Widget2',3) 
,('SS1234a','Widget3',1) 

,('xSS1234','Widget1',1) 
,('xSS1234','Widget2',3) 
,('xSS1234','Widget3',1) 
,('xSS1234','Widget4',1) 

,('ySS1234','Widget1',10) 
,('ySS1234','Widget2',3) 
,('ySS1234','Widget3',1) 

,('zSS1234','Widget2',3) 
,('zSS1234','Widget3',1) 
; 

問合せ:

with CTE as (
    select distinct 
     o.OrderID, ca.ProductString, ca.QtyString 
    from #ord o 
    cross apply (
     SELECT 
      STUFF((
        SELECT 
         ', ' + o2.ProductCode 
        FROM #ord o2 
        WHERE o.OrderID = o2.OrderID 
        ORDER BY o2.ProductCode 
        FOR XML PATH ('') 
       ) 
       , 1, 1, '') 
      , STUFF((
        SELECT 
         ', ' + cast(o2.Qty as varchar) 
        FROM #ord o2 
        WHERE o.OrderID = o2.OrderID 
        ORDER BY o2.ProductCode 
        FOR XML PATH ('') 
       ) 
       , 1, 1, '') 
     ) ca (ProductString, QtyString) 
    ) 
select 
    ProductString, QtyString, count(*) Num_Orders 
from CTE 
group by 
    ProductString, QtyString 
having 
    count(*) > 1 
order by 
    Num_Orders DESC 
    , ProductString 

結果:

ProductString    QtyString Num_Orders 
Widget1, Widget2, Widget3 1, 3, 1  2 

参照:http://rextester.com/DJEN59714

関連する問題