Mysql 根据另一个表中是否存在记录向select语句添加列

Mysql 根据另一个表中是否存在记录向select语句添加列,mysql,sql,Mysql,Sql,我正在编写一个SQL查询,希望向记录集中添加一列,该列的值基于另一个表中是否存在记录。我有一个连接表的左连接,我假设我必须在我的SQL中进行某种透视,但我不熟悉表透视 我现有的SQL是 SELECT tabs.name,tabs.id AS tabid,tabs.sort,fields.id AS fieldid, fields.label FROM tabs INNER JOIN fields ON tabs.id = fields.tabid LEFT JOIN fields_repor

我正在编写一个SQL查询,希望向记录集中添加一列,该列的值基于另一个表中是否存在记录。我有一个连接表的左连接,我假设我必须在我的SQL中进行某种透视,但我不熟悉表透视

我现有的SQL是

SELECT tabs.name,tabs.id AS tabid,tabs.sort,fields.id AS fieldid, fields.label
FROM tabs
INNER JOIN fields
  ON tabs.id = fields.tabid
LEFT JOIN fields_reports
  ON fields_reports.fieldid = fields.id
WHERE fields_reports.reportid = 57
GROUP BY fields.id
ORDER BY tabs.sort, fields.id
SQL中发生的事情是,它提取字段(这是语句的核心)和选项卡(本质上是类别)。fields_reports表将字段映射到我正在生成的报告

我需要做的是在我的语句中添加一列,该列显示:如果当前字段在fields_reports表中有一条记录,并且传入了报告编号(57),则将列值赋值为1,否则为0

编辑:我对查询有另一个问题。现在,查询只提取附加到一个报表的字段。有没有一种方法可以不使用case,而是通过子查询从fields\u reports表中进行选择,这样就可以提取所有字段,然后让列将其附加到报表

这是现在提取记录的查询,但只提取一个报告字段

SELECT tabs.name,tabs.id AS tabid,tabs.sort,fields.id AS fieldid, fields.label,
  CASE WHEN fields_reports.id IS null THEN 0 ELSE 1 END AS inReport
FROM fields
INNER JOIN tabs
  ON tabs.id = fields.tabid
LEFT JOIN fields_reports
  ON fields_reports.fieldid = fields.id
WHERE fields_reports.reportid = 57
GROUP BY fields.id
ORDER BY tabs.sort, fields.id
让我知道我是否应该就此提出一个新问题。

这句话应该是:

select ....
     , case when LeftJoinedTable.column is null then 0 else 1 end
  from ....
这是因为,当您离开联接并且联接表中不存在行时,列仍然存在于结果中,但它们都为null。因此,您可以测试此空值,以查看是否与联接右侧的行匹配

You can `SELECT ..., IF(field_reports.reportid=57),1,0), ... FROM ...`

编辑需要删除WHERE子句中对reportid的测试,否则这对于解决方案来说没有什么意义。(这要感谢@Dave Long。)

看看我对你的脚本做了什么:

SELECT tabs.name,tabs.id AS tabid,tabs.sort,fields.id AS fieldid, fields.label
FROM tabs
INNER JOIN fields
  ON tabs.id = fields.tabid
LEFT JOIN fields_reports
  ON fields.id = fields.id AND fields_reports.reportid = 57
GROUP BY fields.id
ORDER BY tabs.sort, fields.id
注意到不同的东西了吗?我删除了
WHERE
子句,并将条件移动到
左连接字段的
ON
子句
WHERE
,正如指定的那样,将左联接转换为内部联接,因此结果集将只尝试选择带有
字段的行。\u reports.reportid=57
。如果没有这样的行,则不会返回任何行,也就是说,这样您就无法让您的标志列工作

但现在可以这样定义,例如:

MAX(CASE fields_reports.reportid WHEN 57 THEN 1 ELSE 0 END) AS TheFlagColumn

只需将其附加到您的选择列表中。

虽然这会起作用,但我已经将答案授予托德·霍普,因为他的答案在更少的代码中是正确的。@Dave Long:您知道得更清楚,但我必须说,尽管托德的答案基本上是正确的,但它不能应用于您的查询。我的意思是,您的查询只能选择
reportid=57
,因此Todd定义的flag列毫无意义。在我的回答中,我已经解决了您刚才在原始问题的更新中提出的问题。我认为很明显,reportid上的WHERE子句测试必须删除。否则,正如你正确指出的,“解决方案”将毫无意义。你这样说是正确的。在Ted的帖子中,您确实需要删除where子句@Ted-你可能想在你的答案中添加这一点,因为在网上找到这篇文章的人可能不会觉得这很明显。一开始我没有。很抱歉把你的名字弄混了,我不是这个意思。:)实际上,你的答案似乎还有一个问题。
分组依据
列表不包括
字段和报告。reportid
,并且此字段不会在解决方案中聚合。这种情况下的状态:
服务器可以从组中自由返回任何值,因此除非所有值都相同,否则结果是不确定的。
显然,
字段的所有值\u报表。对于我们分组的任何特定
字段。id
,reportid不一定相同。