2016-04-28 16 views
1

カテゴリに商品が追加されているウェブサイトがあります。これらのカテゴリは階層的にランク付けされています。したがって、製品はカテゴリのメンバーであり、このカテゴリのすべての親です。SQL照会の共通分母(列)

product_id | category_level_1 | category_level_2 | category_level_3 | property_a | property_b 
--------------------------------------------------------------------------------  
1   | category1  | category2  | category3  | 1   | 2 
2   | category1  | category2  | category4  | 1   | 3 

私はいくつかの性質上、製品の検索インデックステーブルのフィルタリングにクエリを実行する場合(例えばpropery_aとproperty_b)私も知りたい最小公分母カテゴリ:私たちは、このようになります検索インデックステーブルを持っていますです。上記のカテゴリ2の例では、

私はcategory_level_1、category_level_2、category_level_3の列を含むアプリケーションに結果セットを返す動作するクエリを持っています。結果セットをループしている間、私は最も低い共通分母のカテゴリを決定することができます。

しかし、最初のクエリで最小公約数を判断できれば、多くのデータ転送が節約されます(カテゴリツリーは実際のレベルで最大9レベルです)。誰もが、プロパティ(WHERE property_a = 1)にフィルタをかけるクエリで共通カテゴリを判断する方法を提案していますか?

ARTMの回答に基づいて、これは私の解決策は最終的に何であったかです:

現実はもっと複雑ですが、あなたは正しい道に私を置きます!ありがとう!プロパティに関するクエリは非常に複雑です:WHERE(property_a = 1 AND(Property_2 = 2またはPeroperty_2)= 3 AND Property_3 = 4)など これを "property_query"と呼ぶことができます。

私は仕事にこれを得た:

SELECT product_id, category as common_category FROM (SELECT Product_id, COUNT(*) OVER (PARTITION BY 1) AS productCount FROM <tablename> WHERE <property_query>)) A INNER JOIN ( 
     select count(*) as categoryCount , category 
    from (select category_level_1 as cat, from <tablename> WHERE <property_query> 
     union all select category_level_2, from <tablename> WHERE <property_query> 
     union all select category_level_3, from <tablename> WHERE <property_query>)c 
      group by cat) B ON B.categoryCount = A.productCount 

は今、私はパフォーマンスのためにそれをテストする必要が....

+1

試行したクエリを表示してください。 –

+0

期待された結果を見せてください! – jarlh

+0

私は方法がわからないので、まだ何も試みていません。現在の(簡略化された)照会は、property_a = 1の商品からselect *です。 –

答えて

1

をウインドウで最初のクエリにこのロジックを組み込むことができる、とカウントをカテゴリ別にグループ化します。次に、検索基準を持つ行の数が各カテゴリでグループ化された数と同じである他の内部選択に参加できます。

SELECT product_id, cat AS CommonDeno 
FROM (
select COUNT(*) OVER (PARTITION BY property_a) AS ProductCountWithProperty_A 
, product_id 
, pr.property_a 
from yourTable 
) A 
INNER JOIN (select count(*) as catCount 
, cat 
    from (
     select category_level_1 as cat, property_a as p from yourTable 
     union all select category_level_2, property_a from yourTable 
     union all select category_level_3, property_a from yourTable 
    ) c 
    where c.p = 1 
    group by cat 
) i on i.catCount = A.ProductCountWithProperty_A 
AND A.property_a = 1 
+0

現実はもっと複雑ですが、私は正しい経路に置いてあります。ありがとう!プロパティに関するクエリは非常に複雑です(WHERE property_a = 1 AND(Property_2 = 2またはPeroperty_2)= 3 AND Property_3 = 4など)。 –

0

まずあなたが第二段階で結果セットをループする必要はありません。

with result(product_id, category_level_1 , category_level_2 , category_level_3, property_a , property_b) as 
(
--your first query here 
) 
select denominator= 
    case min(category_level_1) when max(category_level_1) then min(category_level_1) + 
     case min(category_level_2) when max(category_level_2) then min(category_level_2) + 
     case min(category_level_3) when max(category_level_3) then min(category_level_3) else '' end else '' end end 
from result 
having min(category_level_1) = max(category_level_1) 

次は、SQL 2014であるならば、あなたはあなたがproperty_aは、あなたが探しているもので、すべてのカテゴリの列の和集合を取得することができますmax() over(), min() over()

+0

私はこの解決策を試しましたが、category_level_1、2および3の列はGuidsですので、min/maxを使用することはできません... –

+0

最初にchar(36)クエリについては – Serg