我正在尝试让产品搜索在MySQL 5.0.88中正常运行。
基本设置:我有表A和产品
A.id
A.ean
A.styleNo
A.price
A.seller (ID e.g. 123, 456)
带有价格表的表B
B.name
B.ean
B.alt_price
B.seller
卖家可以定义可选的价格表,与进行搜索的用户匹配。我的搜索或多或少看起来像这样:
SELECT A.styleNo, A.price, B.price
FROM arts A
LEFT JOIN pricelists B ON
B.seller = A.seller
AND B.ean = A.ean
AND B.alt_price != 0
WHERE...
// pricelists
AND ( B.name = "some_name" AND B.seller = "123" ) OR ( next applicable seller ) ...
因此,在LEFT JOIN之后,我将按名称和卖家的价格包含所有物品。
这可以正常工作,因为它同时选择常规价格(A)和alt_price(B),并且我可以在显示结果时检查现有的alt_price以向用户显示正确的价格。
但是如果卖家没有给他的所有产品提供 alt-price ,我现在用A的价格显示产品,而实际上我不想显示这个卖家的产品根本没有价格表(区域分类)。
因此,如果用户X有一个价格表“abc”而卖家123有500个产品,其中200个在价格表“abc”上,我只想以正确的价格显示200个产品而不是500个200。 / p>
我尝试在LEFT JOIN中使用 B.alt_price!= 0 ,但这没有用,因为那里的所有项目都有价格。
问题
有没有办法在实际搜索中执行此操作,或者我必须在结果循环中执行此操作,我并不是真的很想做。
答案 0 :(得分:2)
SELECT
b.styleNo, b.price, a.alt_price
FROM
pricelists a
INNER JOIN
arts b ON a.seller = b.seller AND a.ean = b.ean
WHERE
a.alt_price <> 0 AND
a.name = 'name' AND
a.seller = 123
INNER JOIN
在此处执行的操作仅在seller
和ean
字段在两个表中都匹配时返回行,因此它只会检索已过滤的价目表中的产品通过WHERE
。
LEFT JOIN
将返回所有行,无论其他表中是否匹配。如果匹配,则显示第二个表中的相应值,但如果没有,则第二个表中的值为NULL
,同时仍保留第一个表中的行数据。
因此,如果我们改为FROM arts a LEFT JOIN pricelists b ON ...
,我们将从产品表中获取所有行,而不管价格表中是否存在匹配。如果价目表没有匹配,产品仍会显示,但价格表数据包含NULL
值。
请注意,LEFT JOIN
的左侧的表格保留了行数据,而不管{的右侧侧表格中的匹配项是什么{1}} ...因此“左”。
您可能需要查看Jeff Atwood的visual explanation of joins,了解不同LEFT JOIN
类型的工作原理。
还要了解在加入后{em}评估<{1}},因此您在JOIN
中指定的条件过滤将在加入发生后应用。因此,如果您希望仅在table2的行没有匹配{1}}中table1的行的所有行,则应指定WHERE
。
答案 1 :(得分:0)
听起来你想要一个内连接而不是外连接。内部联接仅返回连接条件成功的组合。左连接将始终为左表中的每一行返回至少一行。
要仅获得具有替代价格的产品,请执行以下操作:
SELECT A.styleNo, A.price, B.price
FROM arts A
INNER JOIN pricelists B ON
B.seller = A.seller
AND B.ean = A.ean
AND B.alt_price is not null
WHERE...
或者,您可以将AND B.alt_price is not null
添加到当前查询的where子句中,但除非您的db的查询优化器接管,否则效率可能会降低。
答案 2 :(得分:0)
确定。终于找到了解决方案。
问题是,搜索将包含多个卖家,一些人使用价格表,一些人不使用价格表。
我这样解决了: - 无论如何我不得不构建这条线:
LEFT JOIN pricelists B ON
// dynamic construct depending on number of sellers using pricelists matched to user
B.seller = A.seller
AND B.ean = A.ean
AND B.alt_price != 0
因此,我创建了另一个变量,其中包含使用价格表且适用于此用户的所有卖家ID。看起来像这样:
123456789 ...
我将此添加到WHERE子句:
AND(IF(A.seller IN(123,456,789 ...),B.alt_price IS NOT NULL,1))
这样,我正在检查
(a)如果记录来自适用于该用户的价格表卖方,并且
(b)如果是这种情况,那么记录在b.alt_price中不能有NULL值,该值不会出现在价格表中,因为当LEFT JOINING时,sql会向不在价格表B上的所有记录添加NULL。
那很难......