0

次の問題を解決する方法について誰かが私にアイデアを投げてくれませんか:

データベースに写真、ビデオ、タグがあります。タグは写真やビデオに関連付けることができます。データベースにクエリを実行して、7 日以内に変更されたタグ ID とカウントを取得し、それらを画像およびビデオ アセットとの関連付けの数で並べ替える必要があります。

つまり、最後に、過去 7 日間で最も多くの写真またはビデオに関連付けられたタグを出力できるということです。私が持っているフィールドでDB構造を書き留めました

VIDEO
    ID

PICTURE
    ID

PICTURE_ATTRMAPPING
    CS_OWNERID  (ID of picture)
    CS_ATTRID  ( will store ID of the tag attribute (picture_tag or video_tag))
    ASSETVALUE ( will store ID OF THE associated tag)

VIDEO_ATTRMAPPING
    CS_OWNERID  (ID of video)
    CS_ATTRID  ( will store ID of the tag attribute (picture_tag or video_tag))
    ASSETVALUE ( will store ID OF THE associated tag)

TAG
    ID
    UPDATEDATE

ATTRIBUTES (picture_tag attribute ID is stored here)
    ID
    NAME

タグ、動画、画像、属性が別々のテーブルに保存されていることがわかります。VIDEO/PICTURE_ATTRMAPPING テーブルに CS_ATTRID 列のビデオまたは画像タグ属性 ID と ASSETVALUE 列のタグの ID を持つレコードがある場合、タグがビデオまたは画像によって参照されている (つまり、ビデオ/画像にタグの関連付けがある) ことがわかります。

サブクエリを使用したクエリになると想定しているため、このタスクをサブタスクに分割し、必要なすべての情報を取得する方法を見つけ始めました。

ビデオ オブジェクトと画像オブジェクトのタグ属性の ID を必ず取得する必要があります。

SELECT id FROM ATTRIBUTES WHERE NAME = 'picture_tag' OR NAME = 'video_tag'

また、n 日経過したタグをクエリする方法の例:

SELECT id FROM TAG WHERE updateddate BETWEEN TO_DATE('2013-08-20 00:00:00', 'yyyy-mm-dd hh24:mi:ss') AND CURRENT_DATE

これはおそらく見た目ほど複雑ではありませんが、クエリ全体がどのように見えるべきか、何から始めるべきかについてはわかりません。誰かがアイデアやサンプルを投げてくれませんか?

私は oracle を使用していますが、mysql にも精通しているため、どの DBMS からのサンプルも素晴らしいでしょう。私が自分自身を十分に明確にしたかどうか教えてください。

4

2 に答える 2

1

過去 7 日間に更新されたタグは、次のように記述できます。

select id from tags where updatedate >= sysdate - 7

あなたが言っていることから、ATTRIBUTES テーブルには 2 つの値しかありません。無視できるようにします。PICTURE_ATTRMAPPING と VIDEO_ATTRMAPPING のテーブルがさらにある場合でも、それらに参加するときに属性が強制されるようにするため、これも問題ではありません。

タグを写真やビデオに関連付けたい場合は、 *_ARRTMAPPING テーブルのいずれかに存在するようにする必要があります。

select *
  from tags t
  left outer join picture_attrmappings pa
    on t.id = pa.assetvalue
  left outer join video_attrmappings va
    on t.id = va.assetvalue
 where t.updatedate >= sysdate - 7
   and ( pa.assetvalue is not null
         or va.assetvalue is not null
         )

次に、最も変更されたタグ ID が必要です。そのため、カウントで ORDER BY する必要があります。

select t.id
  from tags t
  left outer join picture_attrmappings pa
    on t.id = pa.assetvalue
  left outer join video_attrmappings va
    on t.id = va.assetvalue
 where t.updatedate >= sysdate - 7
   and ( pa.assetvalue is not null
         or va.assetvalue is not null
         )
 group by t.id
 order by count(*) desc

少し異なる点として、これは非常に奇妙なスキーマです (何も省略していないと仮定します)。PICTURE_ATTRMAPPINGS は、TAGS と PICTURE の間のジャンクション テーブルになると思います。TAGS テーブルはタグの一意のリストを格納する必要がありますが、これは機能していないようです。UPDATEDATE は、各タグが最後に更新された時期を知ることができるように PICTURE_ARRTMAPPINGS にするか、すべてのタグが最後に更新された時期を知ることができるように PICTURE にする必要があります (またはその両方)。

スキーマの一部が欠落していると思われますが、提供されたものでは、PICTURE または VIDEO を使用する方法がわかりません。

于 2013-08-26T11:36:55.983 に答える
0

写真に割り当てられたすべてのタグ ID:

SELECT ASSETVALUE  
            FROM PICTURE_ATTRMAPPING 
                 JOIN ATTRIBUTES 
                 ON (      ATTRIBUTES.ID = PICTURE_ATTRMAPPING.CS_ATTRID 
                      AND  ATTRIBUTES.NAME = 'picture_tag'
                    ) 

動画に割り当てられたすべてのタグ ID:

    SELECT ASSETVALUE  
    FROM   VIDEO_ATTRMAPPING 
           JOIN ATTRIBUTES 
           ON (      ATTRIBUTES.ID = PICTURE_ATTRMAPPING.CS_ATTRID 
                AND  ATTRIBUTES.NAME = 'video_tag'
              )

OUTER JOIN を使用して、タグ付けされた写真とビデオをカウントします

SELECT 
  TAG.ID
, SUM(CASE WHEN PT.ASSETVALUE is not NULL THEN 1 ELSE 0 END) as tagged_picture_number
, SUM(CASE WHEN VT.ASSETVALUE is not NULL THEN 1 ELSE 0 END) as tagged_vieos_number
  FROM 
    TAG
    LEFT OUTER JOIN 
      (
        SELECT ASSETVALUE  
        FROM PICTURE_ATTRMAPPING 
             JOIN ATTRIBUTES 
             ON ( ATTRIBUTES.ID = PICTURE_ATTRMAPPING.CS_ATTRID AND  ATTRIBUTES.NAME = 'picture_tag') 
      ) PT
      ON ( PT.ASSETVALUE = TAG.ID)
    LEFT OUTER JOIN 
      (
        SELECT ASSETVALUE  
        FROM   VIDEO_ATTRMAPPING 
               JOIN ATTRIBUTES 
               ON ( ATTRIBUTES.ID = PICTURE_ATTRMAPPING.CS_ATTRID AND  ATTRIBUTES.NAME = 'video_tag') 
      ) VT
      ON ( PT.ASSETVALUE = TAG.ID)
WHERE
    TAG.UPDATEDATE <= TRUNC(SYSDATE, 'DD') - 7
group by TAG.ID
order by tagged_picture_number + tagged_vieos_number DESC
;
于 2013-08-26T11:44:19.200 に答える