正确的方法来执行此查询

时间:2011-12-09 02:09:10

标签: mysql

我有一张桌子

  

表格(       int id)   webformsystemflags(int id,int formid int sysflagid)

     

sysflag(int id,name char(10))

表格表格是一张包含所有表格的表格

webform是一个表格,其中包含应用了标志的表格。它有一个外键formid,它是表格表的id和sysflagid,它是sys标志表的外键

sys标志是包含标志的表。假设我将标记定义为1,2,3 我可以有没有应用所有标志的表格,有些可能有1个,有些可能有2个或有些可能有3个或者有些可能没有。

如何找到所有已应用标志1或标志2或标志3的表格?

3 个答案:

答案 0 :(得分:1)

您可以使用子查询:

SELECT * FROM `form` WHERE `id` IN (SELECT `formid` FROM `webformsystemflags`)

尽管有大型数据库的子查询。你可以用连接做同样的事情,但这是一个简单的解决方案,可以帮助你。

或者对于没有特定标志的所有结果:

SELECT * FROM `form` WHERE `id` IN (SELECT `formid` FROM `webformsystemflags` WHERE `sysflagid` != 1 OR `sysflagid` != 2)

或加入方法:

SELECT f.*, r.`sysflagid` FROM `form` f LEFT JOIN `webformsystemflags` r ON r.`formid` = f.`id` WHERE r.`sysflagid` != null

将为您提供表格和相关标志。但是,如果表单上有多个标志,它将不会在一行中获取所有标志。那个你可能需要在旗帜上做一个连续,但这个答案已经变得越来越不必要了。

* 最后编辑*

Ok nutsandbolts - 你需要更新你的问题,因为我们两个人已经在一些不同的查询中超越了自己,并且它并没有真正帮助回来说它没有给出正确的结果。只需检查我们提供的查询并使用它们背后的一般逻辑来组合适合您的查询,就可以轻松获得正确的结果。

所以我的最后一个建议 - 你说你想要一个返回表单的查询 IF 它有一个适用于它的某个标志 AND 那是 NOT 已应用其他标志。

这里假设你想要所有形式的标志为1而不是2或3或没有:

SELECT f.*, r.`sysflagid` FROM `form` f LEFT JOIN `webformsystemflags` r ON r.`formid` = f.`id` WHERE r.`sysflagid` =1  AND r.`formid` NOT IN (SELECT `formid` FROM `webformsystemflags` WHERE `sysflagid` = 2 OR `sysflagid` = 3)

因为你的webformsystemflags是关系型的,所以这个查询不会返回webformsystemflags表中不存在的任何表单 - 所以你不需要考虑null。

如果这不是您正在寻找的内容,我强烈建议您在完成此问题之后,以绝对和完美的清晰度重写您的问题。祝你好运。玩得开心。

答案 1 :(得分:1)

这是寻找排除的常见技巧。我在“FlagYouAreExpectingTo_ NOT _Exist”下面的值明确地是您希望不存在的值。这是它的工作原理。

获取每个表单并将LEFT JOIN连接到Web System Flags表,找到匹配的表单,并标记您不想要的设置。如果它找到表单和标志的有效条目,则(wsf)表中的“formid”将存在。因此,我们希望所有不存在,因此关闭WHERE wsf.formid为空。

对于那些尚未标记的人,它将为NULL。

select
      f.ID
   from
      forms f
         left join webformsystemflags wsf
            on  f.id = wsf.formid
           AND wsf.sysflagid = FlagYouAreExpectingTo__NOT__Exist
   where
      wsf.formid is null

答案 2 :(得分:0)

您可以使用exists子句来提取这样的记录:

select a.*
from form a
where exists (select 1 
              from webformsystemflags 
              where formid = a.id 
              and sysflagid IN (1,2,3))

这不会给你相关的标志。如果你想要:

select a.*, b.sysflagid
from form a
join (select formid, sysflagid
           from webformsystemflags
           where sysflagid in (1,2,3)) b
on a.id = b.formid

有许多不同的方法可以解决这个问题。

编辑:通过阅读对其他答案的评论,似乎问题不明确。您想要只有一个标志的结果表单吗?即表格有标志1但不是2或3?

edit2:如果你真的只想要一个真/假查询只拉真(有一个标志):

select a.*, b.sysflagid
from form a
join webformsystemflags b on a.id = b.formid

如果你想要没有旗帜的表格:

select a.*
from form a
left join webformsystemflags b on a.id = b.formid
where b.formid is null

edit3:基于评论,表格带有一个标志而不是其他标志:

select a.*
from form a
where exists (select 1 from webformsystemflags where formid = a.id and sysflagid = 1)
and (
  not exists (select 1 from webformsystemflags where formid = a.id and sysflagid = 2)
  or
  not exists (select 1 from webformsystemflags where formid = a.id and sysflagid = 3)
)