简体   繁体   English

mysql | 方面搜索高级

[英]mysql | Facet search advanced

I have tables: 我有桌子:

CREATE TABLE IF NOT EXISTS `category` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `category` (`id`, `name`) VALUES
(1, 'Computers'),
(2, 'Bikes');

CREATE TABLE IF NOT EXISTS `fields` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `field_name` varchar(255) DEFAULT NULL,
  `cid` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=4 ;

INSERT INTO `fields` (`id`, `field_name`, `cid`) VALUES
(1, 'Processor', '1'),
(2, 'Display', '1'),
(3, 'Brand', '2');

CREATE TABLE IF NOT EXISTS `fields_values` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `field_id` int(11) DEFAULT NULL,
  `field_value` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;

INSERT INTO `fields_values` (`id`, `field_id`, `field_value`) VALUES
(1, 1, 'Intel Pentium 3'),
(2, 2, '27 inch'),
(3, 3, 'BMX'),
(4, 1, 'AMD Radeon'),
(5, 1, 'Intel Atom'),
(6, 2, '22 inch');

CREATE TABLE IF NOT EXISTS `products` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `cid` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

INSERT INTO `products` (`id`, `name`, `cid`) VALUES
(1, 'Computer1', 1),
(2, 'Bike1.BMX', 2),
(3, 'Bike3', 2),
(4, 'Intel Atom', 1),
(5, 'Computer Radeon', 1);

CREATE TABLE IF NOT EXISTS `products_to_fields_values` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) DEFAULT NULL,
  `field_value_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

INSERT INTO `products_to_fields_values` (`id`, `product_id`, `field_value_id`) VALUES
(1, 1, 1),
(2, 2, 3),
(3, 1, 2),
(4, 4, 5);

My request looks like: 我的要求如下:

SELECT ft.id field_id, ft.field_name, fvt.field_value, fvt.id field_value_id, COUNT( DISTINCT pid ) count
FROM FIELDS ft
JOIN fields_values fvt ON ( ft.id = fvt.field_id ) 
JOIN products_to_fields_values pfv ON ( pfv.field_value_id = fvt.id ) 
JOIN products pt ON ( pt.id = pfv.product_id ) 
LEFT JOIN (

SELECT ft.id field_id, ft.field_name, fvt.field_value, fvt.id field_value_id, pt.name, pt.id pid
FROM FIELDS ft
JOIN fields_values fvt ON ( ft.id = fvt.field_id ) 
JOIN products_to_fields_values pfv ON ( pfv.field_value_id = fvt.id ) 
JOIN products pt ON ( pt.id = pfv.product_id ) 
GROUP BY pt.id
)LJ ON pfv.product_id = LJ.pid
WHERE FIND_IN_SET( 1, pt.cid ) 
GROUP BY ft.field_name, fvt.field_value
LIMIT 0 , 30

This request will return (I'm trying to build faceted filter): 该请求将返回(我正在尝试构建多面过滤器):

field_id field_name field_value field_value_id count
2        Display    27 inch     2              1
1        Processor  Intel Atom  5              1
1        Processor  Intel Pentium 3            1

But I have other values in this table: fields_values like: AMD Radeon and 22 inch. 但是我在此表中还有其他值: fields_values,例如:AMD Radeon和22 inch。 Where is my mistake in the request? 请求中我的错误在哪里? Thanks! 谢谢!

EDIT: 编辑:

I'm expect to getting result: 我期望得到结果:

field_id   field_name   field_value   field_value_id   count
2          Display      22 inch       6                0
2          Display      27 inch       2                1
1          Processor    AMD Radeon    4                0
1          Processor    Intel Atom    5                1
1          Processor    IntelPentium3 1                1

Where count is a products count. 计数是产品计数。

Here is a work SQL, but im not sure you have build your structure correctly. 这是一个工作SQL,但是我不确定您是否正确构建了结构。

SELECT
  ft.id field_id, ft.field_name, fvt.field_value, fvt.id as field_value_id, COUNT( DISTINCT pid ) count
FROM products AS pt
JOIN products_to_fields_values AS pfv ON pfv.product_id = pt.id
JOIN fields_values AS fvt ON fvt.field_id = pfv.field_value_id
JOIN fields AS ft on ft.id = fvt.field_id
LEFT JOIN (

SELECT ft.id field_id, ft.field_name, fvt.field_value, fvt.id field_value_id, pt.name, pt.id pid
FROM fields ft
JOIN fields_values fvt ON ( ft.id = fvt.field_id ) 
JOIN products_to_fields_values pfv ON ( pfv.field_value_id = fvt.id ) 
JOIN products pt ON ( pt.id = pfv.product_id ) 
GROUP BY pt.id
)LJ ON pfv.product_id = LJ.pid

WHERE FIND_IN_SET( 1, pt.cid ) 
GROUP BY ft.field_name, fvt.field_value
LIMIT 0 , 30

In short - u have error in this line: 简而言之-您在此行中有错误:

JOIN products_to_fields_values pfv ON ( pfv.field_value_id = fvt.id )

right one: 正确对象,真爱:

JOIN products_to_fields_values pfv ON ( pfv.field_value_id = fvt.field_id )

I tried for your question, check this query 我尝试了您的问题,请检查此查询

select fValue.field_id, f.field_name as field_name, fValue.field_value, fValue.id as field_value_id
from products_to_fields_values as productValue
left join fields_values as fValue on(fValue.field_id=productValue.field_value_id)
left join fields as f on (fValue.field_id=f.id)
left join products as p on (productValue.product_id=p.id)
where p.cid=1

I am quite sure the problem, ie the 'missing' records, is being caused by the 'group by' commands. 我非常确定问题是“丢失”记录是由“ group by”命令引起的。 It's a bit difficult to come up with a solution for you as I am not too sure what you are trying to achieve. 为您想出一个解决方案有点困难,因为我不太确定您要实现什么目标。 The expected result you posted hasn't helped me much in this regard. 您发布的预期结果在这方面对我没有太大帮助。 The query you are trying to run is rather complex, and on a populated database is going to start running very, very slowly. 您尝试运行的查询相当复杂,并且在填充的数据库上,运行将非常非常缓慢地开始。 As such it would suggest a better database design is required. 因此,这表明需要更好的数据库设计。 If you can explain what you are trying to achieve I will gladly look at a solution for you. 如果您能解释您要达到的目标,我们将很乐意为您提供解决方案。

Ignoring the limit and where clauses this is the query you need to use: 忽略限制和where子句,这是您需要使用的查询:

SELECT
  fields.id AS field_id
, fields.field_name
, fields_values.field_value
, fields_values.id AS field_value_id
, COUNT(products.id) AS `count`
FROM fields_values
JOIN fields ON fields.id = fields_values.field_id
JOIN category AS field_category ON field_category.id = fields.cid
LEFT JOIN products_to_fields_values AS product_fields ON fields_values.id = product_fields.field_value_id
LEFT JOIN products ON products.id = product_fields.product_id
GROUP  BY 1, 2, 3, 4;

This produces the following result: 这将产生以下结果:

| field_id | field_name | field_value     | field_value_id | count |  
+----------+------------+-----------------+----------------+-------+  
|        1 | Processor  | AMD Radeon      |              4 |     0 |  
|        1 | Processor  | Intel Atom      |              5 |     1 |  
|        1 | Processor  | Intel Pentium 3 |              1 |     1 |  
|        2 | Display    | 22 inch         |              6 |     0 |  
|        2 | Display    | 27 inch         |              2 |     1 |  
|        3 | Brand      | BMX             |              3 |     1 |

In your where clause you can specify 您可以在where clause中指定

WHERE category.id IN (1)

to get the result you want. 得到想要的结果。

The mistake you were making (and a previous answer as well) was that you were joining the category through the product giving you the product_category instead of the field_category . 您犯的错误(以及先前的答案)是您通过产品加入类别,从而获得了product_category而不是field_category

When you applied a where condition on the product_category , it removed all products not part of the set, so you would never get the count = 0 product_category上应用where条件时,它将删除不属于集合的所有产品,因此您永远都不会得到count = 0

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM