我有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,但我不熟悉如何写它们。
对你的任何帮助都非常感谢!
答案 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 |
-----------------------------