在sql LEFT JOIN中只显示一个结果

时间:2017-12-29 09:53:45

标签: mysql sql left-join

  Table A
    id | kind  | item_name
    ---+-------+----------
    1  | one   | item_1
    2  | one   | item_2

    Table B
    tableA_id | kind  | price
    ----------+-------+------
    1         | all | $10
    1         | one | $2

然后我有这样的查询

    SELECT a.id, a.kind, a.name, b.price FROM table_a a 
     LEFT JOIN table_b b ON b.tableA_id = a.id 
     AND (a.kind = b.kind OR a.kind = 'all') 
    WHERE a.id = 1

基本上我想显示all的{​​{1}}价格table b,如果kind存在,那么只显示价格one例。但我的查询显示allone

about查询的结果如下:

        id | kind  | item_name | price
        ---+-------+-----------+------
        1  | all   | item_1    | $10
        1  | one   | item_1    | $2

我期待这个

        id | kind  | item_name | price
        ---+-------+-----------+------
        1  | one   | item_1    | $2

3 个答案:

答案 0 :(得分:2)

<强>更新

  

基本上我想显示所有类型的价格   在表b中,但是如果存在那种,那么只显示价格一   例如。

为此,您可以使用CASE表达式执行此操作:

SELECT a.id, a.kind, a.item_name,
CASE WHEN b.price IS NULL
       THEN (SELECT b2.Price
             FROM table_b AS b2 
             WHERE b2.kind = 'all')
        ELSE b.price
        END AS PRice
FROM table_a a 
LEFT JOIN table_b b ON b.tableA_id = a.id 
     AND b.kind = 'one' 
WHERE a.id = 1

updated fiddle demo

答案 1 :(得分:0)

这应该在理论上有效,但你要做两个连接:

SELECT a.id, a.kind, a.name, COALESCE(b1.price, b2.price) AS price
FROM table_a AS a
LEFT JOIN table_b AS b1
    ON b1.tableA_id = a.id
    AND b1.kind = a.kind
LEFT JOIN table_b AS b2
    ON b1.tableA_id = a.id
    AND b1.kind = 'all'
WHERE a.id = 1;

可能更有效率。基本上你首先要发现是否存在匹配价格和价格回落'all'的东西。

另外 - 如果table_b始终具有'all'的商品价格,您可以将该左连接更改为内连接。

答案 2 :(得分:0)

要为您的方案选择单行,您需要在查询中使用另一个自连接,并在表b中存在另一种类型时使用其他比较检查选择单行,否则显示kind = all

的行
SELECT a.id, a.kind, a.item_name, b.price
FROM table_a a 
INNER JOIN table_b b ON b.tableA_id = a.id 
LEFT JOIN table_b b1 ON b.tableA_id = b1.tableA_id 
AND b.kind < b1.kind
WHERE b1.tableA_id IS NULL; 

DEMO where kind exist

DEMO where kind doesn't exist

确保关键字“全部”以a开头,然后此b.kind < b1.kind可以正常运行,因为如果您这样做

select 'all' < 'one'; // will return true
select 'all' > 'one'; // will return false

Demo