左连接的挣扎 - 产品

Kav*_*aft 5 mysql

我有一个很简单的问题要问你。

我有一张桌子

 products [ID,Name,Category,Price]
Run Code Online (Sandbox Code Playgroud)

和一张桌子

product_client[ID,product_ID,client_ID]
Run Code Online (Sandbox Code Playgroud)

产品表包含当然所有的产品,但什么product_client所做的是,它是存储一些产品是专为某个客户。

所以我为此写了一个小查询

SELECT * 
FROM product
LEFT JOIN product_client ON product.ID = product_client.product_id
WHERE product_client.client_id =1
Run Code Online (Sandbox Code Playgroud)

一切正常,专门为该客户退回产品。但我想要的更多 -产品表就像一本字典,在该客户之上有他自己的产品。所以我需要得到整个products表,加上上面的查询输出。

有小费吗?以这种方式设置它是个好主意吗?

考虑以下情况:

  • 在数据库中,我们有 ids 1.2.3.4.5
  • 产品 ID 1.2 分配给客户 1
  • 产品 ID 3.5 分配给客户端 2。

我们要查询客户端 1。所以我们希望得到以下 id:1.2.5,因为 3 属于客户端 2,而数字 4 是一个全局产品(未分配)。任何未分配的都是全局产品。

产品表

 products [ID,Name,Category,Price]
Run Code Online (Sandbox Code Playgroud)

客户表

product_client[ID,product_ID,client_ID]
Run Code Online (Sandbox Code Playgroud)

product_client 表

SELECT * 
FROM product
LEFT JOIN product_client ON product.ID = product_client.product_id
WHERE product_client.client_id =1
Run Code Online (Sandbox Code Playgroud)

client_ID = 1 的期望输出

+-----+-------------+-----------+-------+
| ID  |    Name     | Category  | Price |
+-----+-------------+-----------+-------+
|  1  | Paper       | Material  |    10 |
|  2  | Wool        | Material  |     4 |
|  3  | Cleaning    | Service   |    10 |
|  4  | Something   | Service   |     1 |
|  5  | Something2  | Service   |     2 |
+-----+-------------+-----------+-------+
Run Code Online (Sandbox Code Playgroud)

sev*_*ist 6

您的“where”子句将其限制为与客户端产品匹配的产品(您可能知道,左连接从左侧返回所有内容,从右侧返回匹配条目,否则为 NULL。但随后您将其过滤为特定的客户价值)-我会将您的 WHERE 子句修改为:

WHERE 
    product_client.client_id = 1 
    OR product_client.client_id IS NULL
Run Code Online (Sandbox Code Playgroud)

我的逻辑是 - 您正在匹配特定客户端,或者与另一个(例如 client_id = 2)客户端“不匹配”的值。当产品与特定客户不匹配时,client_id 为 null 。

要确定哪一个是全球产品,哪一个是客户的唯一产品,请添加到 select 语句中:

CASE 
    WHEN product_client.client_id IS NULL 
        THEN 'Global' 
    ELSE 'Client' 
END
Run Code Online (Sandbox Code Playgroud)

对于 MySQL/PHP,在语句周围添加 ( )。

ISNULL(client_id,"Global")如果指定了特定客户端,或者其他“全局”客户端,您也可以使用它。