1

次のデータがある場合、1 つのルールに複数の基準を設定できます。

-------------------
RuleId   CriteriaId
-------------------
1        1
1        2
1        3
2        1
2        2
2        3
3        1
3        2

ルールのすべての基準でグループ化するときに最小RuleIdを取得するにはどうすればよいですか。つまり、ルール 1 と 2 は基準がまったく同じであるため、1 つのグループに属しますが、ルール 3 は同じ基準を持たないため、別のグループに属します。

次の結果が返されることを期待しています。

-------------------
RuleId   CriteriaId
-------------------
1        1
1        2
1        3
3        1
3        2

RuleId で MIN を使用して単純な GROUP BY を実行しても、ここでは機能しません。代わりに次の結果が返されるためです。

-------------------
RuleId   CriteriaId
-------------------
1        1
1        2
1        3

ご協力いただきありがとうございます。

4

4 に答える 4

1

これが絶対に最善の方法かどうかはわかりませんが、うまくいきます。

CREATE TABLE GroupingTest (RuleId int, CriteriaId int)
INSERT INTO GroupingTest VALUES 
    (1, 1),
    (1, 2),
    (1, 3),
    (2, 1),
    (2, 2),
    (2, 3),
    (3, 1),
    (3, 2)

----------------------------------------------------
WITH MergedGroupingCriteria AS (
    SELECT DISTINCT RuleId, 
        STUFF((SELECT ', ' + CAST(CriteriaId AS varchar)
                FROM GroupingTest GT
                WHERE GT.RuleId = MergeGroup.RuleId
                FOR XML PATH(''),TYPE).value('.','VARCHAR(MAX)')
            , 1, 2, '') AS MergedGrouping
    FROM GroupingTest MergeGroup )
SELECT MIN(GroupingTest.RuleId), GroupingTest.CriteriaId
FROM GroupingTest
JOIN MergedGroupingCriteria
    ON GroupingTest.RuleId = MergedGroupingCriteria.RuleId
GROUP BY MergedGroupingCriteria.MergedGrouping, GroupingTest.CriteriaId
ORDER BY MIN(GroupingTest.RuleId), GroupingTest.CriteriaId
于 2013-05-15T22:11:26.717 に答える
0

ここに 1 つのアプローチがあります。これは、条件が完全に一致するルールのすべてのペアのリストを作成することから始まります。各ルールに同じ数がある場合、基準は一致します。そして、一致した数を数えると、一致した数は合計数と同じです。

次のクエリは、これらのペアを見つけます。

select driver.ruleid1, driver.ruleid2
from (select rc1.ruleid as ruleid1, rc2.ruleid as ruleid2,
             rc1.numCriteria as Num1, rc2.numCriteria as Num2
      from (select ruleid, COUNT(*) as numCriteria from rc group by ruleid) rc1 join
           (select ruleid, COUNT(*) as numCriteria from rc group by ruleid) rc2
           on rc1.ruleid <= rc2.ruleid and
              rc1.numCriteria = rc2.numCriteria
     ) driver left outer join
     rc rc1
     on driver.ruleid1 = rc1.ruleid left outer join
     rc rc2
     on rc2.ruleid = driver.ruleid2 and
        rc1.criteriaId = rc2.criteriaid
group by driver.ruleid1, driver.ruleid2
having max(driver.Num1) = COUNT(distinct rc1.ruleid) and
       MAX(driver.Num1) = COUNT(distinct rc2.ruleId)

サブクエリは最初のdriverパスを実行し、同じ数の基準を持つすべてのルール ペアを取得します。次に、基準が結合されます。これにより、小さなデカルト積が作成されることがわかりました。ただし、条件の数をカウントするために、クエリは を使用しますcount(distinct)

一意のグループ ID を割り当てるには、rule1 の最小値を取ります。このようなもの:

with pairs as (
      <above subquery>
     )
select ruleid2, min(ruleid1) as groupnum
from pairs
group by ruleid2
于 2013-05-15T22:00:25.807 に答える