根据另一个MYSQL查询结果命令MYSQL查询

时间:2013-10-09 17:14:50

标签: php mysql sql

我有2个sql查询,第一个根据AREA和CATEGORY从数据库中选择产品

它是一家家具店,此查询适用于餐桌。

SELECT p.id,
   p.product_name,
   p.range_name,
   p.pic_url,
   p.hits,
   p.manufacturer,
   p.standard_price,
   p.sale_price,
   p.offer_price,
   p.discount,
   p.display_manufacturer,
   p.display_price,
   p.visible,
   p.display_model_results,
   p.model,
   p.subcat,
   p.disable_options,
   p.request_price,
   p.corner_flag,
   cf.flag_name,
   cf.flag_url,
   cf.flag_description,
   p.display_model,
   p.offer_status,
   p.disable_options_results,
   p.added_timestamp,
   p.about,
   p.keywords
FROM   products p,
   corner_flags cf
WHERE  ( p.area = 'Dining Room Furniture'
      OR p.additionarea = 'Dining Room Furniture' )
   AND ( p.subcat = 'Dining Tables'
          OR p.additionsubcat = 'Dining Tables' )
   AND p.sale_price = ''
   AND p.visible = '1'
   AND p.corner_flag = cf.flag_id
   AND ( p.sale_price = ''
          OR p.offer_price = '0' )
   AND p.visible = '1'
 ORDER  BY ( p.hits ) DESC  

每次查看产品时,产品表中的字段“点击”它都会增加1.这一开始就没问题但是如果客户决定按人气来订购结果,那么现在新产品总是在列表的底部

我们有另一张表跟踪我们网站上的每一次点击,因此我写了一个查询,以计算特定产品在过去2周内查看的次数。

SELECT Count(*) AS total,
   vtp.product_id
FROM   visitor_tracking_pages vtp,
   products p
WHERE  vtp.product_id = p.id
   AND p.subcat = 'Dining Tables'
   AND p.visible = '1'
   AND vtp.last_click >= '1380153600'
GROUP  BY vtp.product_id
ORDER  BY total DESC 

此查询提供过去两周内收到的产品ID和总点击次数。

我只需要一种方法将这两个查询合并为一个。显然,并不是每个产品都会在过去2周内被查看过,所以如果有任何不同,id需要返回0吗?

我看了各种JOINS,但我不熟悉如何写它们。

对你的任何帮助都非常感谢!

4 个答案:

答案 0 :(得分:1)

我认为这解决了你的问题,正确的加入:

SELECT COUNT(*) AS total, p.id as product_id
FROM visitor_tracking_pages vtp RIGHT JOIN products p ON p.id=vtp.product_id
WHERE p.SUBCAT = 'Dining Tables' AND p.visible = '1' AND (vtp.last_click >= '1380153600' or vtp.last_click IS NULL)
GROUP BY p.id
ORDER BY total DESC

RIGHT(或LEFT)JOIN执行标准JOIN,就像在您编写的查询中一样,然后在右侧(或左侧)表中添加与连接不匹配的所有行。

要合并您发布的两个查询,您可以执行此查询

SELECT p.id, p.product_name, p.range_name, p.pic_url, p.hits, p.manufacturer, p.standard_price, p.sale_price, p.offer_price, p.discount, p.display_manufacturer, p.display_price, p.visible, p.display_model_results, p.model, p.SUBCAT, p.disable_options, p.request_price, p.corner_flag, cf.flag_name, cf.flag_url, cf.flag_description, p.display_model, p.offer_status, p.disable_options_results, p.added_timestamp, p.about, p.keywords
FROM products p, corner_flags cf LEFT JOIN visitor_tracking_pages vtp ON vtp.product_id=p.id
WHERE (p.AREA='Dining Room Furniture' OR p.AdditionAREA='Dining Room Furniture') AND (p.SUBCAT='Dining Tables' OR p.AdditionSUBCAT='Dining Tables') AND p.sale_price='' AND p.visible='1' AND p.corner_flag = cf.flag_id AND (p.sale_price= '' OR p.offer_price = '0') AND p.visible='1'
AND (vtp.last_click >= '1380153600' or vtp.last_click IS NULL)
GROUP BY p.id
ORDER BY COUNT(*), p.hits DESC

我知道这不是完美的方式,因为规范地,字段列表中允许的唯一字段是GROUP BY子句中提到的字段,但它可以工作,您可以在ORDER BY子句中使用COUNT(*)。

另一种做你需要的方法是使用我编写的第一个查询创建一个视图,例如* view_order *然后使用它作为数字来避免使用GROUP BY的每种问题,使用此查询:

SELECT p.id, p.product_name, p.range_name, p.pic_url, p.hits, p.manufacturer, p.standard_price, p.sale_price, p.offer_price, p.discount, p.display_manufacturer, p.display_price, p.visible, p.display_model_results, p.model, p.SUBCAT, p.disable_options, p.request_price, p.corner_flag, cf.flag_name, cf.flag_url, cf.flag_description, p.display_model, p.offer_status, p.disable_options_results, p.added_timestamp, p.about, p.keywords
FROM products p, corner_flags cf JOIN view_order vtp ON vtp.product_id=p.id
WHERE (p.AREA='Dining Room Furniture' OR p.AdditionAREA='Dining Room Furniture') AND (p.SUBCAT='Dining Tables' OR p.AdditionSUBCAT='Dining Tables') AND p.sale_price='' AND p.visible='1' AND p.corner_flag = cf.flag_id AND (p.sale_price= '' OR p.offer_price = '0') AND p.visible='1'
ORDER BY vtp.totale, p.hits DESC

答案 1 :(得分:0)

试试这个

SELECT p.id,
   p.product_name,
   p.range_name,
   p.pic_url,
   p.hits,
   p.manufacturer,
   p.standard_price,
   p.sale_price,
   p.offer_price,
   p.discount,
   p.display_manufacturer,
   p.display_price,
   p.visible,
   p.display_model_results,
   p.model,
   p.subcat,
   p.disable_options,
   p.request_price,
   p.corner_flag,
   cf.flag_name,
   cf.flag_url,
   cf.flag_description,
   p.display_model,
   p.offer_status,
   p.disable_options_results,
   p.added_timestamp,
   p.about,
   p.keywords,
   IFNULL(vtp.last_two_week_hits, 0) as last_two_week_total_hits
FROM corner_flags cf INNER JOIN  products p
     ON cf.flag_id = p.corner_flag
    LEFT JOIN
       (SELECT v.product_id as product_id,Count(*) as last_two_week_hits
            FROM   visitor_tracking_pages v
           WHERE v.last_click >= '1380153600' group by v.product_id 
        ) as vtp ON vtp.product_id = p.id
WHERE  p.visible = '1' AND ( p.area = 'Dining Room Furniture'
      OR p.additionarea = 'Dining Room Furniture' )
   AND ( p.subcat = 'Dining Tables'
          OR p.additionsubcat = 'Dining Tables' )
   AND ( p.sale_price = ''
          OR p.offer_price = '0' )
 ORDER BY last_two_week_total_hits DESC  

答案 2 :(得分:0)

感谢您的帮助!

Ravi - 您的优化有效但由于某种原因它停止了返回过去14天内未查看过的产品。

最后,我终于找到了一个有效的解决方案。

如果你看到任何进一步的改进,请告诉我:)。

我创建了一个名为popular_products的新表,并编写了一个脚本,每天(通过cron作业)填充此表,并使用查询visitor_tracking_pages表的新命中计数。

TRUNCATE TABLE在添加新结果之前删除前几天的结果。

$timestamp = strtotime("-2 week");

mysql_query("TRUNCATE TABLE  `popular_products`");

$result = mysql_query("SELECT COUNT(*) AS total, product_id 
FROM visitor_tracking_pages vtp 
WHERE  vtp.product_id != '' AND vtp.last_click >= '$timestamp' 
GROUP BY product_id");

while($row = mysql_fetch_array($result)){

mysql_query("INSERT INTO popular_products (product_id, total_views) 
VALUES ('$row[1]','$row[0]')");

}

这使我可以在结果中添加它而无需即时运行查询。

过去两周内未查看的产品返回NULL,这很好。

SELECT p.id, 
   p.product_name, 
   p.range_name, 
   p.pic_url, 
   p.hits, 
   p.manufacturer, 
   p.standard_price, 
   p.sale_price, 
   p.offer_price, 
   p.discount, 
   p.display_manufacturer, 
   p.display_price, 
   p.visible, 
   p.display_model_results, 
   p.model, 
   p.subcat, 
   p.disable_options, 
   p.request_price, 
   p.corner_flag, 
   cf.flag_name, 
   cf.flag_url, 
   cf.flag_description, 
   p.display_model, 
   p.offer_status, 
   p.disable_options_results, 
   p.added_timestamp, 
   p.about, 
   p.keywords, 
   (SELECT pp.total_views 
       FROM popular_products pp 
       WHERE pp.product_id = p.id 
   ) AS total_views 
FROM products p, corner_flags cf 
WHERE p.visible='1' 
   AND (p.AREA='Dining Room Furniture' OR p.AdditionAREA='Dining Room Furniture') 
   AND (p.SUBCAT='Dining Tables' OR p.AdditionSUBCAT='Dining Tables') 
   AND p.corner_flag = cf.flag_id 
   AND p.sale_price= '' 
ORDER BY ABS(total_views) DESC

答案 3 :(得分:0)

有什么方法可以进一步过滤命中数? ...基本上有些访问者会多次在产品之间来回切换,这些产品会显示为产品可以获得更多真实的视图。

产品的visitor_tracking_pages表中的查询显示共查看了7次,但实际上只有5位唯一身份访问者查看过。

SELECT ip_address, product_id
FROM  `visitor_tracking_pages` 
WHERE  `product_id` =  '1562805'
AND  `last_click` >=  '1380153600'

| ip_address   | product_id |
-----------------------------
| 192.168.0.1  | 1562805    |
| 192.168.0.1  | 1562805    |
| 192.168.0.2  | 1562805    |
| 192.168.0.3  | 1562805    |
| 192.168.0.4  | 1562805    |
| 192.168.0.1  | 1562805    |
| 192.168.0.5  | 1562805    |
-----------------------------