2013-08-26 120 views
0

有人可以告訴我有關如何解決以下問題的想法:複雜的SQL查詢(需要建議)

我的照片,視頻和標籤在我的數據庫中。標籤可以與圖片和視頻相關聯。我必須查詢數據庫中的標籤ID和計數,在7天或更早之前修改它們,並按它們對圖片和視頻資產的關聯計數進行排序。

所以我的想法是,最後我可以輸出最近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的樣本都會很棒。如果我讓自己清楚,請告訴我。

回答

1

說是在過去7天內更新的標籤可以寫爲:

select id from tags where updatedate >= sysdate - 7 

從你所說的屬性表只中有兩個值;所以你可以忽略它。即使它有更多的表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修改最多;所以你需要按計數:

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之間的交匯表。 標籤表應該存儲一個唯一的標籤列表,但這似乎並不是它所做的。然後,UPDATEATE應在PICTURE_ARRTMAPPINGS中,因爲您可以知道每個標記最後更新的時間或PICTURE的值,以便知道所有標記最後更新的時間(或兩者)。

我懷疑你缺少一些模式,但我沒有看到使用PICTURE或VIDEO提供的方法。

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 
;