1

Item-Id、Name、
PurchaseLog-Id、ItemId、CustomerId、PurchaseDate User-Id、UserName

与えられた2つの顧客のユーザー名について、昨年購入した一般的なアイテムの名前を見つけます。

これはナイーブ(または正しい)ですか?:

select distinct item.id, item.name
from item i, PurchaseLog log_username1, PurchaseLog log_username2,  user user1, user user2
where lower(user1.username) = lower('UserName1') AND
      lower(user2.username) = lower('UserName2') AND
      log_username1.itemid = log_username2.itemid AND
      log_username2.itemid = i.itemid AND
      log_username1 >-- satisfy date contraint AND
      log_username2 >-- satisfy date contraint
4

2 に答える 2

8

交差点クエリの基本的な要件について説明します。

select item.id, item.name
from item, PurchaseLog p, user u
where lower(u.username) = lower('Username1')
AND p.user_id = u.user_id
and item.id = p.itemid
and p.purchasedate between SYSDATE and SYSDATE-365
INTERSECT
select item.id, item.name
from item, PurchaseLog p, user u
where lower(u.username) = lower('Username2')
AND p.user_id = u.user_id
and item.id = p.itemid
and p.purchasedate between SYSDATE and SYSDATE-365

これにより、両方のユーザーに表示されるitem.idとitem.nameのリストが返されます。

于 2012-04-28T01:59:46.427 に答える
0

セミジョインウィッチを使用するこのソリューションソリューションは、結果を明確にする必要がないため、ケースに最適です。/ + inline /ヒントは、user_itemsサブクエリで一時テーブルを使用しないようにオプティマイザに指示します。パフォーマンスを向上させるには、user.useridが小文字に制限された列(仮想列が最適である必要があります)を使用し、その上にインデックスを使用する必要があります。そのため、後でクエリでlowerを呼び出す必要はありません。

また、クエリでPurchaseLogとユーザーテーブル間の結合条件を指定し忘れたと思います。

with user_items as (
        select /*+inline*/ lower(username),itemid
        from PurchaseLog
            join user using (userid) /*you were missing this join in your query*/
        where  log_username >-- satisfy date contraint
    )
select item.id, item.name
from item i
where itemid in (
        select itemid
        from user_items
        where username = lower('UserName1')
    ) and itemid in (
        select itemid
        from user_items
        where username = lower('UserName2')
    )
/
于 2012-04-29T13:45:48.403 に答える