sqlite 1到多个模式:查询仅链接到itemX和itemY的行

时间:2017-11-09 20:10:49

标签: sql sqlite

我有一个具有一对多关系的数据库。

CREATE TABLE 'tag' (
    'id' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
    'value' TEXT NOT NULL,
    CONSTRAINT name_unique UNIQUE ('value')
);

CREATE TABLE 'tagfile' (
    'idFile' INTEGER NOT NULL,
    'idTag' INTEGER NOT NULL,
    PRIMARY KEY ('idFile', 'idTag'),
    FOREIGN KEY(idFile) REFERENCES tracks(ID),
    FOREIGN KEY(idTag) REFERENCES tag(id) ON DELETE CASCADE
);

如何查询它以获取idFile列表:

  • 链接到AND ONLY给定的tag.value列表? (PREVENT idFile具有到标记表中其他数据的链接)
  • 链接到AT LEAST给定的tag.value列表? (允许idFile具有到标记表中其他数据的链接)

2 个答案:

答案 0 :(得分:1)

您可以使用du -Ssb | awk '{print $1-4096}' group by

having

如果您想要具有这三个和其他文件的文件,请使用上述内容。如果你想要那三个:

select tf.idFile
from tagfile tf join
     tag t
     on tf.idtag = t.id
where t.value in ('a', 'b', 'c')
group by tf.idFile
having count(*) = 3;  -- length of list

答案 1 :(得分:0)

虽然它需要标签不重叠(或者可能会发生一些奇怪的结果,但在我的情况下并不是很重要),但仍然使用此解决方案。 如果有人有更好的查询,我很高兴听到:)

select tf.idFile, GROUP_CONCAT(t.value) AS tags
from tagfile tf join
     tag t
     on tf.idtag = t.id
group by tf.idFile
having tags LIKE "%a%"
AND tags LIKE "%b%"
AND tags LIKE "%c%"
AND tags NOT LIKE "%d%" -- to filter out

修改 最后使用戈登的解决方案。这是另一个版本:

select tf.idFile, GROUP_CONCAT(t.value) AS tags
from tagfile tf join
     tag t
     on tf.idtag = t.id
group by tf.idFile
-- Those to include: ( = length of include list)
having sum(case when t.value in ('a', 'b', 'c') then 1 else 0 end) = 3  
-- Those to exclude: ( = 0)
and sum(case when t.value in ('z', 'y') then 1 else 0 end) = 0          
 -- for exact list match, add:
 -- and count(*) = 3 -- ( = length of include list)