Sql 查询未按预期工作

Sql 查询未按预期工作,sql,mysql,Sql,Mysql,目标 从blog_news中选择不同的ID,其中 活动=1 标题不是空的 至少有一张图片,除非图片是徽标或至少有一个视频 目前为止的声明 select distinct n.id from blog_news n left join blog_pics p ON n.id = p.blogid and active = '1' and trim(n.title) != '' left join blog_vdos v ON n.id = v.blogid where (p.islogo

目标

从blog_news中选择不同的ID,其中

  • 活动=1

  • 标题不是空的

  • 至少有一张图片,除非图片是徽标或至少有一个视频

目前为止的声明

select distinct n.id from blog_news n 
left join blog_pics p ON n.id = p.blogid and active = '1' and trim(n.title) != '' 
left join blog_vdos v ON n.id = v.blogid 
where (p.islogo = '0' and p.id is not null) OR (v.id is not null)
order by `newsdate` desc, `createdate` desc
问题

  • 选择包含图片的博客新闻ID,除非它们是徽标[正确]

  • 选择同时包含视频和图片的博客新闻ID[正确]

  • 不选择只有视频的博客新闻ID[错误]

    • 这个怎么样:

      SELECT DISTINCT n.id
        FROM blog_news n
       WHERE n.active = '1'
             AND trim(n.title) != ''
             AND (EXISTS (SELECT 1
                            FROM blog_pics p
                           WHERE p.blogid = n.id
                             AND p.islogo = 0)
                  OR EXISTS (SELECT 1
                               FROM blog_vdos v
                              WHERE v.blogid = n.id)
                 )
      ORDER BY n.newsdate desc, n.createdate desc
      
      如果您只对子行的存在感兴趣(或不感兴趣),那么子行的存在通常更清晰、更易于使用。

      这是怎么回事:

      SELECT DISTINCT n.id
        FROM blog_news n
       WHERE n.active = '1'
             AND trim(n.title) != ''
             AND (EXISTS (SELECT 1
                            FROM blog_pics p
                           WHERE p.blogid = n.id
                             AND p.islogo = 0)
                  OR EXISTS (SELECT 1
                               FROM blog_vdos v
                              WHERE v.blogid = n.id)
                 )
      ORDER BY n.newsdate desc, n.createdate desc
      

      如果您只是对子行的存在(或不存在)感兴趣,那么它通常更清晰、更易于使用。

      我看不出您的查询有任何问题

      我希望
      active
      列在
      blog\u news
      表中,您应该称之为
      n.active
      。如果此列位于
      blog_pics
      表中,则这就是问题所在

      我会将条件(n.active,n.title)添加到WHERE,因为它与left join(blog_pics)无关,但这只是为了更好的可读性,结果是一样的

      您也可以使用子选择写入查询:

      SELECT n.id FROM blog_news n
      WHERE n.active = 1 AND TRIM(n.title) != '' AND n.id IN (
        SELECT DISTINCT p.blogid FROM blog_pics p WHERE p.islogo = 0 UNION
        SELECT DISTINCT v.blogid FROM blog_vdos
      );
      

      我看不出你的问题

      我希望
      active
      列在
      blog\u news
      表中,您应该称之为
      n.active
      。如果此列位于
      blog_pics
      表中,则这就是问题所在

      我会将条件(n.active,n.title)添加到WHERE,因为它与left join(blog_pics)无关,但这只是为了更好的可读性,结果是一样的

      您也可以使用子选择写入查询:

      SELECT n.id FROM blog_news n
      WHERE n.active = 1 AND TRIM(n.title) != '' AND n.id IN (
        SELECT DISTINCT p.blogid FROM blog_pics p WHERE p.islogo = 0 UNION
        SELECT DISTINCT v.blogid FROM blog_vdos
      );
      

      @为什么
      IS[NOT]NULL
      IS standard ANSI SQLU满足多少%的博客新闻行(active=1,title为非空)?有多少博客新闻行至少有一个视频?有多少博客新闻行至少有一张图片?最后,blog_pics中有多少行是is_logo=1?@Bugai13为什么
      IS[NOT]NULL
      IS standard ANSI SQLU满足多少%的博客新闻行(active=1,title为非空)?有多少博客新闻行至少有一个视频?有多少博客新闻行至少有一张图片?最后,blog图片中有多少行是logo=1?这有效吗?我认为子查询需要在blog\u news中的每一行执行!!!(仅适用于分别满足active和trim(n.title)条件的行)@gAMBOOKa为什么要避免子查询,它们是清晰且性能良好的。@Vojta这比使用语句中的IN操作(查询一大堆不必要的行以填充IN子句)要有效得多。对于EXISTS,乐观主义者认识到需要进行简单的存在性检查。@Tom:您的查询似乎比Vojta更有效。他的完成时间是.8秒,而你的完成时间是.4秒。但是我们可能在博客新闻中有超过50000行,现在我们只有2000行的测试数据。子查询真的会减慢速度,对吗?+1@Tom:你能再给我解释一下,Optimizer是如何做到的吗?因为对我来说,看起来你需要对blog_新闻中的任何一行执行子查询。我知道使用IN远不是完美的,但我的子查询只需要执行一次,它们只能访问索引(如果您将索引放在islogo上)。非常感谢……这有效吗?我认为子查询需要在blog\u news中的每一行执行!!!(仅适用于分别满足active和trim(n.title)条件的行)@gAMBOOKa为什么要避免子查询,它们是清晰且性能良好的。@Vojta这比使用语句中的IN操作(查询一大堆不必要的行以填充IN子句)要有效得多。对于EXISTS,乐观主义者认识到需要进行简单的存在性检查。@Tom:您的查询似乎比Vojta更有效。他的完成时间是.8秒,而你的完成时间是.4秒。但是我们可能在博客新闻中有超过50000行,现在我们只有2000行的测试数据。子查询真的会减慢速度,对吗?+1@Tom:你能再给我解释一下,Optimizer是如何做到的吗?因为对我来说,看起来你需要对blog_新闻中的任何一行执行子查询。我知道使用IN远不是完美的,但我的子查询只需要执行一次,它们只能访问索引(如果您将索引放在islogo上)。非常感谢…像这样使用IN是非常低效的。像这样使用IN是非常低效的。