3

我正在尝试让产品搜索在 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 以向用户显示正确的价格。

但是,如果卖家没有为他的所有产品提供替代价格,我现在正在展示具有 A 价格的产品,而实际上我不想展示来自该卖家且没有价目表的产品完全进入(想想区域分类)。

因此,如果用户 X 有一个价目表“abc”而卖家 123 有 500 个产品,其中 200 个在价目表“abc”上,我只想显示 200 个产品,而不是 500 个和 200 个的正确价格。

我尝试在 LEFT JOIN 中使用B.alt_price != 0,但这无济于事,因为那里的所有物品都有价格。

问题
有没有办法在实际搜索中做到这一点,或者我是否必须在结果循环中做到这一点,我并不热衷于这样做。

4

3 回答 3

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

此处所做的是仅在两个表中的and字段匹配INNER JOIN时才返回该行,因此它只会检索在.sellereanWHERE

LEFT JOIN另一方面,无论另一个表中是否存在匹配项,A都会返回所有行。如果匹配,则显示第二个表中的相应值,但如果没有,则这些值将NULL来自第二个表,同时仍保留第一个表中的行数据。

因此,如果我们改为这样做FROM arts a LEFT JOIN pricelists b ON ...,我们将从 products 表中获取所有行,而不管 pricelist 表中是否存在匹配项。如果价格表不匹配,产品仍会显示,但价格表数据包含NULL值。

请注意,左侧的表LEFT JOIN保留其行数据,而不管右侧的表中是否匹配LEFT JOIN......因此为“LEFT”。

您可能想看看 Jeff Atwood对连接的直观解释,以了解不同JOIN类型的工作原理。

还要了解在连接WHERE进行评估,因此您指定的条件过滤将在连接发生后应用。因此,如果您只想要 table2 的行与 a 中 table1 的行匹配的所有行,则应指定.WHERELEFT JOINWHERE table2.fieldname IS NULL

于 2012-07-15T20:30:47.877 回答
0

听起来您想要内部联接而不是外部联接。内连接只返回连接条件成功的那些组合。左连接将始终为左表中的每一行返回至少一行。

要仅获得具有 alt 价格的产品,请执行以下操作:

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 子句,尽管除非您的数据库的查询优化器接管,否则效率可能会降低。

于 2012-07-15T19:26:20.350 回答
0

好的。终于找到了解决办法。

问题是,搜索将包含多个卖家,其中一些使用价格表,而另一些则不使用。

  • 如果我在价格表 B 上进行 INNER JOIN,我将不会获得不使用价格表的卖家的产品,因为他们在 B 中没有任何条目。
  • 如果我在价格表 B 上执行 LEFT JOIN,所有条目都将具有 NULL 或价格表 B 值,因此当我搜索对其某些产品使用价格表的卖家时,我将始终获得他的全部范围,而不管alt_price指定的
  • 如果我尝试过滤这些不需要的记录(卖家使用价目表,排除不在其中的产品),通过将B.alt_price != 0添加到 WHERE 子句,我也排除了所有不使用价目表的卖家的产品。

我这样解决了:-无论如何我都必须构建这条线:

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。看起来像这样:

    123,456,789...

  • 我将其添加到 WHERE 子句中:

    AND(如果(A.seller IN(123,456,789...),B.alt_price 不为空,1))

这样,我正在检查
(a) 记录是否来自适用于用户的价目表卖家,以及
(b) 如果是这种情况,则记录在 b.alt_price 中不得有 NULL 值,该记录不是价格表上会有,因为当 LEFT JOINING 时,sql 会将 NULL 添加到不在价格表 B 上的所有记录中。

那很难...

于 2012-07-15T19:37:41.520 回答