SQL:比较具有常见多对多关系的多个表

时间:2018-10-02 06:34:18

标签: sql sqlite many-to-many

两个材料表:

LocalDateTime fromDate = LocalDateTime.parse("2018-10-02T15:17:35");
LocalDateTime fromDate2 = LocalDateTime.parse("2018-10-02T14:17:35");

if (fromDate.isAfter(fromDate2)) {

}

MaterialA
ID  Name
------------
1   Steel
2   Wood
3   Concrete
4   Gold

和带有一些注释的表格:

MaterialB
ID  Name
------------
1   Oil
2   Glass
3   Copper
4   Water

因此,所有材料可以具有零个或所有音符(多对多关系)。 因此表归因:

Note
ID  Property
------------
1   hard
2   liquid
3   flammable
4   heavy
5   metal
6   lighter than water

为了获得更好的视图,材料表带有注释ID:

Attribution
ID  Table   Mat_ID  Note_ID
---------------------------
1   A       1       1
2   A       1       4
3   A       1       5
4   A       2       3
5   A       2       6
6   A       3       1
7   A       4       4
8   A       4       5
9   B       1       2
10  B       1       3
11  B       1       6
12  B       2       1
13  B       3       4
14  B       3       5
15  B       4       2

MaterialA
ID  Name        Notes
---------------------
1   Steel       1, 4, 5
2   Wood        3, 6
3   Concrete    1
4   Gold        4, 5

如何从MaterialA获取具有与MaterialB中任何材料相同注释的材料。 所以结果应该是:

MaterialB
ID  Name        Notes
---------------------
1   Oil         2, 3, 6
2   Glass       1
3   Copper      4, 5
4   Water       2

我正在使用SQLite

1 个答案:

答案 0 :(得分:0)

使用此

select MaterialA.ID, MaterialA.Name
from (
    select "Table", mat_ID, group_concat(Note_ID) notes from Attribution where "Table"='A' group by "Table", mat_ID ) ta
join (
    select "Table", mat_ID, group_concat(Note_ID) notes from Attribution where "Table"='B' group by "Table", mat_ID )tb on ta.notes=tb.notes 
join MaterialA on ta.mat_id=MaterialA.ID

如果您需要在归因表中进行排序,则必须先进行排序,然后再使用group_concat()。例如:

select MaterialA.ID, MaterialA.Name
from (
    select "Table", mat_ID, group_concat(Note_ID) notes from (
        select "Table", mat_ID, note_id from test where "Table"='A' order by ID desc  )t1
    group by "Table", mat_ID ) ta
join (
    select "Table", mat_ID, group_concat(Note_ID) notes from (
        select "Table", mat_ID, note_id from test where "Table"='B' order by ID desc  )t2
    group by "Table", mat_ID )tb on ta.notes=tb.notes 
join MaterialA on ta.mat_id=MaterialA.ID