修改这个复杂的mySql查询

时间:2014-02-26 14:55:16

标签: mysql sql

我有2个表,添加和adds_filters

以下是我的表格:

CREATE TABLE IF NOT EXISTS `adds` (
    `addid` int(11) NOT NULL AUTO_INCREMENT,
    `memberid` int(11) NOT NULL,
    `isnew` int(11) NOT NULL,
    `catid` int(11) NOT NULL,
    `manufacturerid` int(11) NOT NULL,
    `modelid` varchar(255) DEFAULT NULL,
    `colorid` int(11) DEFAULT NULL,
    `geographicareaid` int(45) NOT NULL,
    `addtypeid` varchar(45) NOT NULL,
    `addcreatedon` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    `addvalidfrom` date NOT NULL,
    `addvaliduntil` date NOT NULL,
    `addcreatedfromip` varchar(255) NOT NULL,
    `yearofmanufacturing` varchar(255) DEFAULT NULL,
    `monthofmanufacturing` int(11) DEFAULT NULL,
    `hoursused` int(11) DEFAULT NULL,
    `cc2` int(11) DEFAULT NULL,
    `horsepowers` int(11) DEFAULT NULL,
    `metalic` tinyint(4) DEFAULT NULL,
    `isdamaged` tinyint(4) DEFAULT NULL,
    `price` float DEFAULT NULL,
    `hasvat` tinyint(4) NOT NULL,
    `canbenegotiated` tinyint(4) DEFAULT NULL,
    `addtitle` varchar(255) DEFAULT NULL,
    `addtext` text NOT NULL,
    `youtubevideo` varchar(255) DEFAULT NULL,
    `visible` tinyint(4) DEFAULT NULL,
    `ff1` varchar(255) DEFAULT NULL,
    `ff2` varchar(255) DEFAULT NULL,
    `ff3` varchar(255) DEFAULT NULL,
    `ff4` varchar(255) DEFAULT NULL,
    PRIMARY KEY (`addid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=43 ;


CREATE TABLE IF NOT EXISTS `adds_filters` (
    `addfilterid` int(11) NOT NULL AUTO_INCREMENT,
    `addid` int(11) NOT NULL,
    `filterid` int(11) NOT NULL,
    PRIMARY KEY (`addfilterid`)
 ) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=45 ;

我有以下sql查询,就像一个魅力,但我需要修改它:

SELECT DISTINCT a.addid
              , a.memberid
              , a.isnew
              , a.catid
              , a.manufacturerid
              , a.modelid
              , a.colorid
              , a.geographicareaid
              , a.addtypeid
              , a.addcreatedon
              , a.addvalidfrom
              , a.addvaliduntil
              , a.addcreatedfromip
              , a.yearofmanufacturing
              , a.monthofmanufacturing
              , a.hoursused
              , a.cc2
              , a.horsepowers
              , a.metalic
              , a.isdamaged
              , a.price
              , a.hasvat
              , a.canbenegotiated
              , a.addtitle
              , a.addtext
              , a.youtubevideo
              , a.visible
              , a.ff1
              , a.ff2
              , a.ff3
              , a.ff4
           FROM adds a
           JOIN adds_filters f
             ON f.addid = a.addid 
          WHERE a.catid = 1
            AND a.manufacturerid = 1
            AND f.filterid IN (67,158)

我的问题如下:如果我再添加一个过滤器,(例162),查询应该不返回任何结果,因为没有包含所有3个过滤器的添加。当前查询返回3行,所有行都有67和158.任何人都可以告诉我如何获得所需的结果?

问候,约翰

3 个答案:

答案 0 :(得分:2)

Here is SQLfiddle
您应该了解,您需要动态地将子查询添加到每个已检查的filterid

以下是查询(您还可以在主filterid中使用SELECT

SELECT t1.*, t2.filterid as filterid2
FROM
(
SELECT DISTINCT a.*,
       f.`filterid`
          FROM adds a
               JOIN adds_filters f
                    ON a.`addid` = f.`addid`
         WHERE      a.`catid` = 1
               AND  a.`manufacturerid` = 1
               AND  f.`filterid` = 67
) t1

JOIN 

(
SELECT DISTINCT a.`addid`,
       f.`filterid`
          FROM adds a
               JOIN adds_filters f
                    ON a.`addid` = f.`addid`
         WHERE      a.`catid` = 1
               AND  a.`manufacturerid` = 1
               AND  f.`filterid` = 158

  ) t2
ON t1.addid = t2.addid

JOIN 

(
SELECT DISTINCT a.`addid`,
       f.`filterid`
          FROM adds a
               JOIN adds_filters f
                    ON a.`addid` = f.`addid`
         WHERE      a.`catid` = 1
               AND  a.`manufacturerid` = 1
               AND  f.`filterid` = 162

  ) t3

ON t1.addid = t3.addid;

答案 1 :(得分:1)

您应该只需将连接更改为adds_filters组件

即可
   FROM adds a
      JOIN ( select addid
                from adds_filters
               where filterid in ( 67, 158, 162 )
               group by addid
               having count(*) = 3 ) f
             ON f.addid = a.addid 
   WHERE a.catid = 1
     AND a.manufacturerid = 1

通过更改为只包含具有所有3个组件的AddID的预先查询(通过分组依据和拥有),它将仅返回那些有效的AddID

答案 2 :(得分:0)

我倾向于接受DRapp的建议,但是如果在构建SQL时提前知道有多少过滤器存在问题,那么另一种可能性就是每个过滤器有一个内连接。

SELECT DISTINCT a.addid
              , a.memberid
              , a.isnew
              , a.catid
              , a.manufacturerid
              , a.modelid
              , a.colorid
              , a.geographicareaid
              , a.addtypeid
              , a.addcreatedon
              , a.addvalidfrom
              , a.addvaliduntil
              , a.addcreatedfromip
              , a.yearofmanufacturing
              , a.monthofmanufacturing
              , a.hoursused
              , a.cc2
              , a.horsepowers
              , a.metalic
              , a.isdamaged
              , a.price
              , a.hasvat
              , a.canbenegotiated
              , a.addtitle
              , a.addtext
              , a.youtubevideo
              , a.visible
              , a.ff1
              , a.ff2
              , a.ff3
              , a.ff4
           FROM adds a
           INNER JOIN adds_filters f1
             ON f1.addid = a.addid AND f1.filterid = 67
           INNER JOIN adds_filters f2
             ON f2.addid = a.addid AND f2.filterid = 158
           INNER JOIN adds_filters f3
             ON f3.addid = a.addid AND f3.filterid = 162
          WHERE a.catid = 1
            AND a.manufacturerid = 1