0

問題の説明

各推奨事項の平均成績のコンマ区切りリストを取得しようとしています。これは、推奨コンテンツIDの別のコンマ区切りリストで構成されています。レコメンデーションは、レコメンデーションを受け取るコンテンツ(ContentID)と、レコメンデーションされるその他のコンテンツのリスト()で構成されるオブジェクトRecommendedContentIDsです。

テーブル構造、サンプルデータ、その他の制限

私は2つのテーブルのデータベース構造を持っています。最初の表には、コンマ区切りのランク付けされたリストとして保存された推奨コンテンツIDが含まれています。2番目の表には、推奨される各コンテンツIDの成績が含まれています。ランク付けされたリストには、最大10個のコンマ区切りの値があり、グレードの範囲は0〜5です。

問題をよりよく説明するために、テーブル構造といくつかのサンプルデータを次に示します。

Table Recommendations

|ID    |ContentID    |RecommendedContentIDs |Type |
+------+-------------+----------------------+-----+
|1     |2051         |9706,14801,13354,...  |a    |
+------+-------------+----------------------+-----+
|67    |2051         |8103,16366,8795,...   |b    |
+------+-------------+----------------------+-----+
|133   |2051         |8795,8070,15341,...   |c    |
+------+-------------+----------------------+-----+
|22    |1234         |4782,283,33,...       |a    |
+------+-------------+----------------------+-----+
...

Table Grades

|ID    |RecommendationID |RecommendedDocumentID |Grade |EvaluatorHash|
+------+-----------------+----------------------+------+-------------+
|1     |1                |9706                  |4     |123456789    |
+------+-----------------+----------------------+------+-------------+
|2     |1                |14801                 |5     |123456789    |
+------+-----------------+----------------------+------+-------------+
|3     |1                |13354                 |3     |987654321    |
+------+-----------------+----------------------+------+-------------+
|3     |1                |9706                  |3     |987654321    |
+------+-----------------+----------------------+------+-------------+
|4     |67               |8103                  |5     |123456789    |
+------+-----------------+----------------------+------+-------------+
|1     |67               |16366                 |4     |987654321    |
+------+-----------------+----------------------+------+-------------+
|1     |133              |8795                  |2     |123456789    |
+------+-----------------+----------------------+------+-------------+
...

「Recommendations」テーブルのRecommendedContentIDs列を、次のような別のテーブルに変換しました。

Table RecommendedContent

|ID    |RecommendationID |RecommendedContentID |Rank |
+------+-----------------+---------------------+-----+
|1     |1                |9706                 |1    |
+------+-----------------+---------------------+-----+
|2     |1                |14801                |2    |
+------+-----------------+---------------------+-----+
|3     |1                |13354                |3    |
+------+-----------------+---------------------+-----+
|4     |1                |12787                |4    |
+------+-----------------+---------------------+-----+
...

+------+-----------------+---------------------+-----+
|11    |2                |19042                |1    |
+------+-----------------+---------------------+-----+
|12    |2                |13376                |2    |
+------+-----------------+---------------------+-----+
|13    |2                |9853                 |3    |
+------+-----------------+---------------------+-----+

期待される結果

次に、対応する2つのコンマ区切りリストを含む結果セットを返すクエリを作成して、推奨される各コンテンツIDの平均グレードを表示できるようにします。次のようになります。

|ContentID    |RecommendedContentIDs    |RecommendedContentAverageGrades   |Type  |
+-------------+-------------------------+----------------------------------+------+
|2051         |9706,14801,13354,...     |3.5,5.0,3.0,...                   |a     |
+-------------+-------------------------+----------------------------------+------+
|2051         |8103,16366,8795,...      |5.0,4.0,0.0,...                   |b     |
+-------------+-------------------------+----------------------------------+------+
|2051         |8795,8070,15341,...      |2.0,0.0,0.0,...                   |c     |
+-------------+-------------------------+----------------------------------+------+
...

ご覧のとおり、この列には、対応する各ContentIDの平均RecommendedContentAverageGrades評点が列に含まれています(ID 9706のコンテンツは2回評定され、1回は4、もう1回は3であるため、平均は3.5です)。コンテンツが採点されていない場合、平均評点は0になります。ここで非常に重要なのは、のリストがランク付けされたリストであるため、 2つのコンマ区切りリストが対応していることです。RecommendedContentIDsRecommendedContentIDs

私は通常、このようなものをC#で実装しますが、SQLで実行できるかどうか疑問に思っていました。使用することを考えてGROUP_CONCATいましたが、適切な結果セットを得ることができませんでした。誰かがMySQLやT-SQL用の実用的なSQLクエリを提供してくれれば非常にありがたいですが、提案だけでも問題ありません。

編集

#1-ローレンスは、コンマ区切りのリストの代わりに個別のテーブルを使用することに言及しました。古いデザインのため使用していますが、変更することはできません。ただし、コンマ区切りのリストのデータは別のテーブルに格納されていると想定している場合は、自由に回答できます。

#2-ローレンスが提案したように構造を変更しました(分離されたテーブルを使用-更新された構造を参照)。

4

4 に答える 4

3

これは、@Laurenceによって与えられた答えをフォローアップするだけです。

http://sqlfiddle.com/#!2/7d236/6

于 2012-11-16T13:15:23.000 に答える
2

Akriggの修正とsqlfiddleで更新され、推奨テーブルの値で並べ替える方法も更新されました。また、brozoの修正に従って、group_concat句でorderbyを使用して更新されました。

Table RecommendedContent

+-----------------+----------------------+
|RecommendationID | RecommendedContentID |
+-----------------+----------------------+
| 1               | 9706                 |
| 1               | 14801                |
| 1               | 13354                |
| 67              | 8103                 |
| ...             | ...                  |
+-----------------+----------------------+

Select
  a.RecommendationID,
  a.ContentID,
  Group_Concat(a.RecommendedContentId Order By a.Rank),
  Group_Concat(Trim(Trailing '.' From Trim(Trailing '0' From a.AverageGrade)) Order By a.Rank),
  a.Type
From (
  Select
    r.RecommendationID,
    r.ContentID,
    r.Type,
    rc.RecommendedContentID,
    rc.Rank,
    Coalesce(Avg(g.Grade), 0) As AverageGrade
  From
    Recommendations r
      Left Outer Join
    RecommendedContent rc
      On r.RecommendationID = rc.RecommendationID
      Left Outer Join
    Grades g
      On rc.RecommendedContentID = g.RecommendedDocumentID And
         rc.RecommendationID = g.RecommendationID
  Group By
    r.RecommendationID,
    r.ContentID,
    r.Type,
    rc.RecommendedContentID,
    rc.Rank
  ) as a
Group By
  a.RecommendationID,
  a.ContentID,
  a.Type
Order By
  a.ContentID, -- Or other way round if that's what you prefer
  a.RecommendationID

http://sqlfiddle.com/#!2/ca8b8/8

于 2012-11-16T12:08:52.183 に答える
1

SQL Serverでカスタム集計を作成して、コンマ区切りの文字列連結を実行し、次のように使用できます。

SELECT ContentID, RecommendedContentIDs, CustomToCsv(AvgGrade), Type FROM
(
    SELECT ContentID, RecommendedContentIDs, AVG(Grade) AvgGrade, Type 
    FROM Recommendations r INNER JOIN  Grades g ON r.ID = g.RecommendationID
    GROUP BY ContentID, RecommendedContentIDs, RecommendedDocumentID, Type
) as t
GROUP BY ContentID, RecommendedContentIDs, Type
于 2012-11-16T12:09:36.347 に答える
1

これはオラクルで行われます

WITH count_number AS
  (SELECT 
    ContentID,
    ','
    ||RecommendedContentIDs
    ||',' new_ContentIDs,
    RecommendedContentIDs,
    type ,
    LENGTH(RECOMMENDEDCONTENTIDS )-LENGTH(REPLACE(RECOMMENDEDCONTENTIDS ,','))+1 COUNT_ID
  FROM Recommendations
  ) ,
  RecommendedContentIDs_postion AS
  (SELECT A1.*,
    B1.CONTENTIDS_OCCURANCE_POSITION ,
    SUBSTR(new_ContentIDs,instr(new_ContentIDs,',',1,ContentIDs_OCCURANCE_POSITION)+1 , INSTR(new_ContentIDs,',',1,ContentIDs_OCCURANCE_POSITION+1)-instr(new_ContentIDs,',',1,ContentIDs_OCCURANCE_POSITION)-1) ContentIDs
  FROM count_number a1,
    (SELECT I ContentIDs_OCCURANCE_POSITION
    FROM DUAL model dimension BY (1 i) measures (0 X) (X[FOR I
    FROM 2 TO 1000 increment 1] = 0)
    ) b1
  WHERE b1.ContentIDs_OCCURANCE_POSITION<=a1.count_id
  )
SELECT 
  CONTENTID,
  WM_CONCAT(CONTENTIDS) RECOMMENDEDCONTENTIDS ,
  WM_CONCAT(GRADE) avg_grade_contentid ,
  type
FROM RECOMMENDEDCONTENTIDS_POSTION RCI,
  (SELECT RECOMMENDEDDOCUMENTID,
    AVG(GRADE) GRADE
  FROM Grades
  GROUP BY RECOMMENDEDDOCUMENTID
  ) GRD
WHERE TRIM(RCI.CONTENTIDS)=TRIM(GRD.RECOMMENDEDDOCUMENTID)
GROUP BY 
  ContentID,
  type;
于 2012-11-16T14:20:25.330 に答える