简体   繁体   中英

many-to-many relationship,, querying one side depending on its elements

Here is the most relevant part of my database schema:

create table TEST (
    ID integer not null,
    NAME text not null,
    constraint PK_TEST primary key (ID),
    constraint UNQ_TEST_NAME unique (NAME)
);

create table SESSION (
    ID integer not null,
    constraint PK_SESSION primary key (ID)
);

create table SESSION_TEST (
    SESSION_ID integer not null,
    TEST_ID integer not null,
    ORDINAL integer not null,
    constraint PK_SESSION_TEST primary key (SESSION_ID, TEST_ID),
    constraint FK_SESSION_TEST_SESSION_ID foreign key (SESSION_ID) references SESSION (ID) on delete cascade,
    constraint FK_SESSION_TEST_TEST_ID foreign key (TEST_ID) references TEST (ID) on delete cascade,
    constraint UNQ_SESSION_TEST_SESSION_ID_ORDINAL unique (SESSION_ID, ORDINAL)
);

There are SESSIONS that consist of multiple TESTS. TESTs in SESSIONS have ORDINALs (are ordered). SESSION_TEST is a link table for a many-to-many relationship: one test can be a part of multiple sessions, and one session consists of multiple tests (but one test can be in a session only once, which is the PK).

I am having problems writing an SQL statement that would return true (or 1 actually, as I am using SQLite) for a test with a given ID, if there is a session that has that test and only that test (in other words, the session consists of only one test, the one I am looking for). For example:

TEST:
ID|NAME
1|aaa
2|bbb
3|ccc

SESSION:
ID
1
2
3
4

SESSION_TEST:
SESSION_ID|TEST_ID|ORDINAL
1|1|1
1|2|2
2|1|1
3|3|1

SESSION with ID = 1 has two TESTs, and SESSIONs 2 and 3 have one test each. I would need to have a select that would return 1/true for inputs 1 and 3, but 0 for 2 (as this TEST is only in SESSION 1, but it's not the only one).

(Sorry about the title, I really didn't know how to put it in a few sentences and make it clear!).

RETURN EXISTS SELECT SESSION_ID FROM 
SESSION_TEST
WHERE TEST_ID = @id
AND ORDINAL = 1
AND SESSION_ID NOT IN (SELECT SESSION_ID FROM SESSION_TEST WHERE ORDINAL > 1);

The RETURN EXISTS syntax might be TSQL only, but you get the picture. If the query returns rows, return true, if not return false.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM