0

私は助けが必要です!たとえば、cars、users、departments、join_user_departmentの4つのテーブルがあります。一部のユーザーはアクセスが制限されているため、テーブルユーザーと部門の間のM:N関係に使用される最後のテーブル。ユーザーがアクセスできる部門の車の数を取得する必要があります。テーブル「cars」には、department_id列があります。テーブルjoin_user_departmentにuser_idによるレコードがない場合、これは、彼がすべての部門にアクセスできることを意味し、selectクエリには条件がない必要があります。私はこのようなことをする必要があります:

declare
DEP_NUM  number;--count of departments where user have access
 CARS_COUNT number;--count of cars
BEGIN
SELECT COUNT (*) into DEP_NUM from join_user_departments where user_id=?;
SELECT COUNT(*) into CARS_COUNT FROM cars where 
  IF(num!=0)—it meant that user access is limited
  THEN department_id IN (select dep_id from join_user_departments where user_id=?);
4

2 に答える 2

2

ユーザーはすべての車にアクセスできるか(すべての車が部門に関連付けられており、ユーザーはすべての部門にアクセスできると想定しています)、またはユーザーのアクセスが制限されています。UNION ALLを使用して、これら2つのグループをまとめ、ユーザーごとにグループ化して最終的なカウントを行うことができます。車のテーブルに無制限にアクセスできるユーザーをクロス参加させて、すべての車に関連付けました。

(部門もカウントするように更新されました)

select user_id, 
    count(distinct department_id) as dept_count, 
    count(distinct car_id) as car_count,
from (
    select ud.user_id, ud.department_id, c.car_id
    from user_departments ud
    join cars c on c.department_id = ud.department_id
    UNION ALL
    select u.user_id, v.department_id, v.car_id
    from user u
    cross join (
        select d.department_id, c.car_id
        from department d
        join cars c on c.department_id = d.department_id
    ) v
    where not exists (
        select 1 from user_departments ud 
        where ud.user_id = u.user_id
    )
)
group by user_id

UNION ALLは、UNIONよりも効率的です。UNIONは、両方のグループに分類されるレコードを探し、重複をスローします。各ユーザーはいずれかのバケットに分類されるため、UNION ALLがそのトリックを実行する必要があります(外部クエリで個別のカウントを実行すると、重複も除外されます)。

于 2012-04-09T22:45:36.863 に答える
1

「テーブルjoin_user_departmentにuser_idによるレコードがない場合、これは彼がすべての部門にアクセスできることを意味します。」

これは非常に悪い習慣のようです。基本的に、レコードの不在を使用して、レコードの存在をシミュレートしています。非常に厄介。どの部門からも車にアクセスできないユーザーがいる場合はどうなりますか?おそらく、現在のビジネスロジックではこれが許可されていませんが、アプリケーションのロジックを変更せずにそのようなシナリオを実装することを許可しない「データモデル」があります。

于 2012-04-09T23:03:15.573 に答える