选择满足其他表中自定义过滤条件的MySQL中的记录作为1-n关系

时间:2018-09-19 18:48:58

标签: mysql

给出具有以下结构的表subscriptions

----------------------------------------
| id | userId | name | recipient   | … |
----------------------------------------
| 1  | 500    | Foo  | foo@abc.com | … |
| 2  | 3244   | Bar  | bar@abc.com | … |
| 3  | 543654 | Blah | blah@abc.de | … |
----------------------------------------

subscription_filters具有以下结构

----------------------------------------------
| id | subscriptionId | type     | value     |
----------------------------------------------
| 1  | 1              | category | it        |
| 2  | 1              | category | design    |
| 3  | 1              | type     | full-time |
| 4  | 1              | type     | part-time |
| 5  | 2              | type     | full-time |
| 6  | 3              | type     | full-time |
----------------------------------------------

我想做的是获取所有subscription记录集,这些记录集未设置给定类型的过滤器或具有我需要的值。例如:

使用category: ittype: full-time进行查询应该给我所有3个订阅。

使用category: constructiontype: full-time进行查询应该给我订阅23,因为1有一个category过滤器,其中不包含{ {1}}。

使用construction进行查询应该只给我订阅type: part-time,因为其他所有人都拥有1

是否可以通过一个查询有效地做到这一点?

2 个答案:

答案 0 :(得分:1)

此查询将执行您想要的操作。它检查“类别”(sf1.value = @category)是否匹配,或者没有类型为categorysf1.id IS NULL)的条目,或者未指定“类别”({{1} }),同样也适用于“类型”。为了演示查询,我使用MySQL变量作为占位符,在构建查询时将替换为适当的值。

@category = ''

输出:

SET @category = 'it';
SET @type = 'full-time';
SELECT s.*, sf1.value AS category, sf2.value AS type
FROM subscriptions s
LEFT JOIN subscription_filters sf1 ON sf1.subscriptionID = s.id AND sf1.type = 'category'
LEFT JOIN subscription_filters sf2 ON sf2.subscriptionID = s.id AND sf2.type = 'type'
WHERE (sf1.id IS NULL OR sf1.value = @category OR @category = '') AND
      (sf2.id IS NULL OR sf2.value = @type OR @type = '');

您可以通过适当设置@category和@type的值来运行其他查询。如果您不想使用过滤器类型,请将其设置为id userId name recipient category type 1 500 Foo foo@abc.com it full-time 2 3244 Bar bar@abc.com NULL full-time 3 543654 Blah blah@abc.de NULL full-time ,例如

''

输出:

SET @category = '';
SET @type = 'part-time';
SELECT s.*, sf1.value AS category, sf2.value AS type
FROM subscriptions s
LEFT JOIN subscription_filters sf1 ON sf1.subscriptionID = s.id AND sf1.type = 'category'
LEFT JOIN subscription_filters sf2 ON sf2.subscriptionID = s.id AND sf2.type = 'type'
WHERE (sf1.id IS NULL OR sf1.value = @category OR @category = '') AND
      (sf2.id IS NULL OR sf2.value = @type OR @type = '');

Demo on Rextester

答案 1 :(得分:0)

尝试一下。希望能帮助到你。以下查询给出了

的结果
  

查询类别:它并输入:全职应给我全部3个   订阅

SELECT * FROM subscriptions 
WHERE id IN (SELECT DISTINCT subscriptionId FROM subscription_filters
WHERE ((type = 'category' AND value = 'it') 
OR (type = 'type' AND value = 'full-time'))
);

您只需要更改条件AND / ORtype and value的值即可。