3

次のように 2 つの MySql テーブルがあります。

resource
-----------------------------------------------
id   name           group   owner_id
-----------------------------------------------
1    MyResource1    hs      11
2    MyResource2    ms      24
3    MyResource3    ps      11
...

resource_access
-----------------------------------------------
id   resource_id    user_id
-----------------------------------------------
1    1              12
2    2              24
3    2              11
4    3              15
...

ここで、最初のテーブルはもちろんリソースのリストで、列にはそれぞれの所有者が表示されowner_idます。2 番目の表は、このリソースを別のユーザーと「共有」した結果です。テーブルには、所有者交換からの乱雑なクリーンアップの結果として、の行に相当する を持つレコードresource_access が含まれる場合があります。user_idowner_idresource_access

ユーザーが所有者であるか共有されているかに関係なく、ユーザーがアクセスできるリソースの ID、名前、およびグループを取得したいだけです。サンプルユーザー (24) の MySQL クエリは次のとおりです。

SELECT resource.id, resource.name, resource.group 
FROM `resource` 
INNER JOIN resource_access ON (
    resource.owner_id='24' 
    OR (
        resource_access.user_id='24' AND 
        resource_access.resource_id=resource.id
    )
)

現在、リソース番号 2 のidname、およびgroupを複数回 (12 のように) 返します。これには考えられる原因がありますか?私は試しLEFTRIGHT参加しましたが、同じ結果が得られています。resourceテーブルには多くのレコードがありますが、 2 のレコードはありません。同じユーザーとリソースを 2 回共有してidも、重複する行はありません。resource_access

前もって感謝します。

4

3 に答える 3

7

使用する:

SELECT DISTINCT resource.id, resource.name, resource.group

重複を削除します。

内部結合が概念的に機能する方法は、2 つのテーブル間で完全なクロス積を生成することです。このクロス積には、入力テーブルの行の各ペアの行が含まれます。ON次に、すべてのand条件に一致する行を保持し、WHEREこれを結果セットとして返します。2 つのテーブル間に一致する行が複数ある場合は、結果セットに複数の行が含まれます。

両方のテーブルから列を選択すると、実際には同じ行ではないことがわかります。テーブルからのデータは同じですが、resourceテーブルからのデータは異なりresource_accessます。しかし、結果に後者の列が表示されていません。を使用DISTINCTすると、これらすべての行が結果にマージされます。

于 2014-06-29T22:45:01.190 に答える
1

テーブルから選択しているだけなので、明示的に使用するのではなくresource、条件を句に入れることをお勧めします。wherejoin

SELECT r.id, r.name, r.group 
FROM `resource` r
WHERE r.owner_id='24' or
      EXISTS (select 1
              from resource_access ra
              where ra.resource_id = r.id and
                    ra.user_id = '24' 
             );

このロジックでは、「結合」は重複を生成できません。

于 2014-06-29T22:48:49.153 に答える
0

リソースの所有権を選択し、それをアクセス権のあるリソースに結合します。user_idあなたとは異なる結果の列WHERE RA.user_id valueは、リソースを所有するのではなく、リソースが共有されたことを意味します。お役に立てれば。

SELECT resource.name,resource.group,resource.owner_id AS user_id
  FROM resource
  WHERE resource.owner_id = '11'

UNION

SELECT R.name,R.group,R.owner_id AS user_id
  FROM resource_access RA 
  LEFT JOIN resource R 
     ON (R.id=RA.resource_id)
  WHERE RA.user_id = '11';
于 2014-06-29T23:19:26.700 に答える