簡體   English   中英

MySQL內部聯接返回同一行的倍數

[英]MySQL Inner Join Returning Multiples of the Same Row

我有兩個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列中的各自所有者。 第二個表是與另一個用戶“共享”此資源的結果。 resource_access 可以包含與記錄user_id ,它等效於該owner_id在一排resource_access作為從所有者交換凌亂清理的結果。

我只想獲取用戶有權訪問的任何資源的ID,名稱和組,無論他們是所有者還是已經與他們共享。 這是我對示例用戶的MySQL查詢(24):

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的idnamegroup (如12)。 有可能的原因嗎? 我嘗試過LEFTRIGHT連接,並得到相同的結果。 resource表中有許多記錄,但沒有id為2的resource_access .resource_access中沒有重復的行與同一用戶共享資源兩次。

提前致謝。

使用:

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

刪除重復項。

內部聯接在概念上的工作方式是它在兩個表之間產生完整的交叉產品。 此交叉產品在輸入表中為每行包含一行。 然后它保留與所有ONWHERE條件匹配的行,並將其作為結果集返回。 如果兩個表之間有多個匹配的行,您將在結果集中獲得多行。

如果您從兩個表中選擇列,您會發現它們實際上並不是同一行。 它們只有resource表中的相同數據,但是來自resource_access表的數據不同。 但是你沒有在結果中顯示后面的那些列。 使用DISTINCT合並結果中的所有這些行。

因為您只是從resource表中進行選擇,所以我建議將條件放在where子句中,而不是使用顯式join

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' 
             );

有了這個邏輯,“連接”不能產生重復。

選擇資源的所有權,然后將其與具有訪問權限的資源聯合。 生成的與WHERE RA.user_id value不同的user_id列只表示資源已共享給他們而不是擁有資源的資源。 希望這可以幫助。

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';

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM