【问题标题】:Checking whole array over a multiple JOIN通过多个 JOIN 检查整个数组
【发布时间】:2012-01-03 12:52:27
【问题描述】:


要从单个表中过滤选定条目的表输出,我需要通过多个表进行多个 JOIN 请求。
我想通过表格中的特殊列过滤人员表格。假设此列是“任务”。现在,tasks 也是另一个包含“people”列的表,并且这两个表之间的值与数据库中现有的“join”表连接,该表将一个表的多个 ID 与另一个表的每个 ID 匹配。
现在,如果这很简单,我可以使用 INNER JOIN 和特殊条件进行过滤。问题是,表“任务”的条目通过数据库中的“连接”表连接到另一个表。为了简化事情,可以说它是“设置”。因此,每个“任务”都由几个“设置”组成,这些“设置”通过其 ID 中的连接表连接。

那么输入是什么?
我有一个 ID 数组,它们代表我不想显示的设置 ID。

输出应该是什么?
如前所述,我想要过滤后的“人”输出,而过滤器是“设置”。 我希望 sql 请求返回表“人”的每个条目,其中仅加入未加入数组中任何“设置 ID”的任务。

我希望你能帮助我。

提前致谢!

示例

设置-表格:
1. 进行中
2. 很重要
3. 有未解决的问题

Tasks-Table:(settings.tasks 是许多任务与许多设置之间的连接表)
1. 2012 年 1 月 1 日开始的任务 - 1 和 3 中的 JOINS 设置(进行中 + 未解决的问题)
2. 2012 年 1 月 2 日的任务 - 2 中的 JOINS 设置(很重要)
3. 2012 年 1 月 3 日的任务 - JOINS 设置 1 和 2 (...)

People-Table:(people.tasks 是多人到多个任务的连接表)
1. Guy - 加入 1、2、3 中的任务(已分配给所有 3 个任务)
2. Dude - 将任务加入 1(已从 01.01.2012 分配给任务)
3. 女孩 - 加入 2、3 (...) 中的任务

现在有一个数组传递给 sql 查询
[2,3] 不应返回 noone,因为每个人都被分配了一项重要的任务或有未解决的问题!
[3] 只会返回“Girl”这个人,因为它是唯一分配给没有未解决问题的任务(2 和 3)的人。

我希望现在很清楚。 :)

【问题讨论】:

  • 你的问题很难理解。我们需要通过一些示例数据行查看您的表的结构,然后您需要向我们展示您希望您的结果是什么样的。此外,问题中的文字越少,阅读的人就越多。

标签: mysql sql ruby-on-rails database


【解决方案1】:
SELECT DISTINCT PEOPLE.* 
FROM PEOPLE INNER JOIN PEOPLE_TASKS ON PEOPLE.PERSON_ID = PEOPLE_TASKS.PERSON_ID
WHERE TASK_ID NOT IN (SELECT DISTINCT TASK_ID
                      FROM TASK_SETTINGS
                      WHERE SETTING_ID = <Id you don't want>)

编辑(用于提供您不想要的多个设置 ID)

SELECT DISTINCT PEOPLE.* 
FROM PEOPLE INNER JOIN PEOPLE_TASKS ON PEOPLE.PERSON_ID = PEOPLE_TASKS.PERSON_ID
WHERE TASK_ID NOT IN (SELECT DISTINCT TASK_ID
                      FROM TASK_SETTINGS
                      WHERE SETTING_ID IN (<Id you don't want>))

【讨论】:

  • 哇,非常感谢 :) 但是如果 是一个数组,它也可以工作吗?
  • @NikoM。你认为数组是什么?
【解决方案2】:

首先,您必须将join table peopletable tasksjoin table 联系起来,我们称之为people_tasks

select distinct p.* from people p
inner join people_tasks pt on p.people_id = pt.people_id
inner join tasks on t.tasks_id = pt.tasks_id

然后你必须join table taskstable settings 加上join table,我们称之为tasks_settings。您必须在当前的selectjoin 他们。

select distinct p.* from people p
inner join people_tasks pt on p.people_id = pt.people_id
inner join tasks on t.tasks_id = pt.tasks_id
inner join tasks_settings ts on t.tasks_id = ts.tasks_id
inner join settings s on s.settings_id = ts.settings_id

现在您已将所有people 与其taskssettings 连接起来。最后你需要restriction。在选择了设置的人之后,您可以像这样选择其他人:

select distinct p.people_id from people p
inner join people_tasks pt on p.people_id = pt.people_id
where p.people_id not in (
    select distinct p2.people_id from people p2
    inner join people_tasks pt2 on p2.people_id = pt2.people_id
    inner join tasks t2 on t2.tasks_id = pt2.tasks_id
    inner join tasks_settings ts2 on t2.tasks_id = ts2.tasks_id
    inner join settings s2 on s2.settings_id = ts2.settings_id
    where s2.settings_id in (list of ids)
)

【讨论】:

  • 那行不通。如果一个人有一个任务,并且该任务有 2 个设置,其中一个是 OP 不想要的设置,则此查询将返回该任务的另一行,因此返回该人的一行。
  • 如果有一个像这样的tasks_settings (task_id, setting_id) 表:(1, 1), (1, 2), (2, 3), (2, 4), (3, 5) 并且提供的设置数组是4, 5,那么您的查询将“允许”任务12。但是 OP 说:‘……只有加入的任务不加入任何来自数组的“设置 ID”。也就是说,2 应该被过滤掉,因为它与不需要的设置 4 相关联。所以,我认为,您应该在不同的阶段应用NOT IN(或等效构造),而不是设置列表,而是任务列表的某个位置。
  • @AndriyM 现在不会有这个问题了。
  • @aF:仍然认为它不太正确.. 它现在会返回所有人,无论他们是否有相关任务..
  • @StevieG 哈哈,你是对的:P 现在它拥有一切!!天哪,多么大的查询:$
猜你喜欢
  • 1970-01-01
  • 2020-10-27
  • 2013-09-14
  • 1970-01-01
  • 2011-12-30
  • 2012-03-04
  • 2013-11-03
相关资源
最近更新 更多