【问题标题】:perform a JOIN if joined field has a value如果连接的字段有值,则执行 JOIN
【发布时间】:2015-09-02 15:51:13
【问题描述】:

在谷歌搜索和查看 SO 之后,我发现了一个针对特定类型查询的无效解决方案。我有一个表格,用于转换文本中另一个表格的值。比方说:

id - text
1 - House
2 - Villa
3 - Camper

主表是

id - valueA - valueB - valueC
1 - 1 - whastington - 3000
2 -  - NewYork - 5000

因此,如果我从主表中获取行,我会将 valueA 的值从 1 替换为 House,依此类推。

ValueA 在特定条件下设置。在任何其他情况下,它将留空(该字段不应为 NULL)。

如果我进行连接,第二行将被忽略,因为 valueA 为空白。查询是

SELECT id,text,valueB,valueC FROM main JOIN dic on main.valueA =  dic.id

所以我想说:只有在 valueA 不为空时才执行连接 我把这个条件写成:

SELECT id,text,valueB,valueC FROM main 
JOIN dic ON (main.valueA =  dic.id AND main.valueA <>'')

正如我在this question 中所读到的,但我没有得到我想要的,可能是因为这种情况下的 AND 条件是基于另一个字段而不是基于连接的字段。我可以在字典表中使用 0 - NONE 对添加另一行,并将所有空 valueA 变为 0,但我想了解我的查询是否在正确的路径上以及我做错了什么。这种所谓的“条件连接”在 mysql 中是可能的吗? 我还查看了this question,但这个解决方案会使这个查询过于复杂,在这种情况下,我会选择用 0 替换空的“B 计划”

【问题讨论】:

  • 您对示例数据的预期结果是什么?
  • 我想从 main 中选择两行。使用普通连接,我错过了第 2 行

标签: mysql join


【解决方案1】:

我无法理解你的目标。在我看来你只需要LEFT JOIN

SELECT main.id,
  dic.text,
  main.valueB,
  main.valueC 
FROM main 
LEFT JOIN dic 
on main.valueA =  dic.id

更新如果您想在查询结果中看到dic.id,只需将该字段添加到SELECT 部分以及valueA 中的valueA(如果需要):

SELECT main.id,
  dic.text,
  dic.id DIC_ID,
  main.valueA MAIN_VALUEA,
  main.valueB,
  main.valueC 
FROM main 
LEFT JOIN dic 
on main.valueA =  dic.id

DIC_ID 和 MAIN_VALUEA 只是列的别名,您可以设置自己的名称或将其留空。

【讨论】:

  • 是的。左连接是另一种选择。但是如果条件不是“非空白”而是“不是特定值”?是否必须将其放入没有其他选项的 where 条件?
  • @LelioFaieta 它适用于dic.id中没有出现的任何值。
  • 如果在 dic.id 我有 1,2 和 3 并且我只想对 1 和 2 进行连接并在主表中留下 3 而不是其文本? 3 在两个表中,并且加入工作,但我不想替换 3
  • WHAT? 在这个特定的上下文中没有 replacement 这样的东西。如果您想获得dic.id 的当前记录。就SELECT吧。检查更新。
  • replacement = text 而不是 valueA = 执行连接
【解决方案2】:

使用UNIONJOIN 与一个查询组合起来,该查询获取所有带有空valueA 的行。

SELECT id, text, valueB, valueC
FROM main
JOIN dic ON main.valueA != '' AND main.valueA = dic.id
UNION
SELECT id, '', valueB, valueC
FROM main
WHERE main.valueA = ''

【讨论】:

  • 好点,但为什么还要在第一个 SELECT 中添加 main.valueA != ''?
  • 我认为它是多余的,但它使意图更清晰。
  • 啊,好的。感谢您的提示!
【解决方案3】:

您也可以使用子查询来执行此操作(或 LEFT JOIN)

SELECT id, 
(SELECT text FROM dic WHERE dic.id = main.valueA), -- will return NULL of not found, use IFNULL if you want another value to be returned -- 
valueB, 
valueC
FROM main

【讨论】:

  • 子查询会影响性能!在这种特定情况下,左连接是唯一的方法。
【解决方案4】:

如果我理解正确,我认为您需要 LEFT OUTER JOIN,然后使用 IF 为 valueA 列返回不同的值(valueA 或文本)

类似这样的:-

SELECT main.id,
        IF(dic.id IS NULL, main.valueA, dic.text)
        main.valueB,
        main.valueC 
FROM main 
LEFT OUTER JOIN dic on main.valueA =  dic.id

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    • 2021-10-06
    相关资源
    最近更新 更多