2017-08-28 32 views
0

我有一個用戶表,它與Areas具有多對多的關係。這種關係存儲在Rel_User_area表中。我想顯示用戶名和區域列表中出現的第一個區域。例如,查詢sql以獲得多對多關係中的第一個匹配項

用戶

id | Name  
1 | Peter  
2 | Joe 

id | Name  
1 | Area A  
2 | Area B 
3 | Area C 

Rel_User_area

iduser | idarea  
1  | 1  
1  | 3  
2  | 3 

我想要的結果:

User Name | Area  
Peter  |Area A  
Joe  |Area C 
+1

當按區域「id」排序時,是「第一」嗎?就像你想爲每個用戶使用'min(area.id)',它是相應的名字。 – JNevill

+0

不一定,它必須是出現在關係表中的第一個。 – Dayana

+1

這就是問題所在。當記錄被插入/刪除時,首先進行更改。在桌子上有沒有可以告訴我們的「TimeStamp」列/字段?請記住,表格中的數據是UNORDERED。您必須提供訂單或訂購方式。 – xQbert

回答

1

使用最小面積ID來確定「第一」,你可以使用相關子查詢(引用字段(S)在主查詢子查詢過濾結果):

SELECT user.name, area.name 
FROM 
    user 
    INNER JOIN Rel_User_Area RUA ON user.id = RUA.iduser 
    INNER JOIN Area ON RUA.idarea = area.id 
WHERE area.id = (SELECT min(idarea) FROM Rel_User_Area WHERE iduser = RUA.iduser) 

有其他的做法可能是RDBMS特有的。就像在Teradata中一樣,我會使用MySQL,SQL Server,Oracle,Postgres等中不存在的QUALIFY子句。無論RDBMS如何,上面都應該可以工作。

SELECT user.name, area.name 
FROM 
    user 
    INNER JOIN Rel_User_Area RUA ON user.id = RUA.iduser 
    INNER JOIN Area ON RUA.idarea = area.id 
QUALIFY ROW_NUMBER() OVER (PARTITION BY user.id ORDER BY area.id ASC) = 1; 
+0

它工作完美。謝謝 – Dayana

1

利用Rel_user_Area您在評論中提到的ID ...

這應該是相當獨立的平臺。

SELECT U.name as Username, A.Name as Area 
FROM (SELECT min(ID) minID, IDUser, IDarea 
     FROM Rel_user_Area 
     GROUP BY IDUser, IDarea) UA 
INNER JOIN User U 
on U.ID = UA.IDuser 
INNER JOIN Area A 
on A.ID = UA.IDArea 

如果跨應用和頂部工作(可替代限1比頂部如果PostgreSQL的或MySQL)

這將運行跨應用SQL一次在用戶的每個記錄;因此您可以獲得每個用戶最近的rel_user_Area ID。

SELECT U.name as Username, A.Name as Area 
FROM User U 
on U.ID = UA.IDuser 
CROSS APPLY (SELECT TOP 1 IDUser, IDArea 
      FROM Rel_user_Area z 
      WHERE Z.IDUSER = U.ID 
      ORDER BY ID ASC) UA 
INNER JOIN Area A 
on A.ID = UA.IDArea 
+0

謝謝你的回答。有效 :) – Dayana