简体   繁体   English

带有子查询的MySQL IN()停止工作了吗?

[英]MySQL IN() with subquery stopped working?

I have a view called "v_documents" where ai have a field "document_type_name" that is based on some fields. 我有一个名为“ v_documents”的视图,其中ai有一个基于某些字段的“ document_type_name”字段。 However the field is a string with a name. 但是,该字段是带有名称的字符串。

Now i want all documents where the type name is contained in another table. 现在,我要所有类型名称包含在另一个表中的所有文档。 But... 但...

This work: 这项工作:

SELECT * FROM v_documents WHERE document_type_name IN ('PREVENTIVO', 'FATTURA');

This not: 这不是:

SELECT * FROM v_documents WHERE document_type_name IN (
     SELECT type FROM t_types
);

Where t_types contains a list of document types and nothing more. 其中t_types包含文档类型列表,仅此而已。 It give me 0 records. 它给了我0条记录。

But if i use = istead of IN() and i return only one record from the subquery it works. 但是,如果我使用=代替IN()并且我从子查询中仅返回一条记录,则它可以工作。

The problem is that if i'm not wrong this code worked before. 问题是,如果我没记错的话,此代码之前就可以工作。 I don't know what is happening. 我不知道发生了什么

PS The t_types table DON'T HAVE null values! PS t_types没有空值!

EDIT : using the subquery in a field seems work. 编辑 :在字段中使用子查询似乎工作。 Why in the IN() not? 为什么不在IN()中?

Here a screen: on the left the subquery used as field, on the right the return records from SELECT type FROM t_types 这里是一个屏幕:左边的子查询用作字段,右边的是SELECT type FROM t_types的返回记录

在此处输入图片说明

EDIT 2 : Screen for @MatBailie's answere. 编辑2 :@MatBailie的应答屏幕。 But i used a LEFT JOIN instead of LEFT OUTER JOIN because i get a MySQL error. 但是我使用了LEFT JOIN而不是LEFT OUTER JOIN因为我遇到了MySQL错误。

在此处输入图片说明

This is only half an answer, but too long for a comment. 这只是答案的一半,但是对于评论来说太长了。

I would begin by using the following query to directly compare what is in each table... 我将从使用以下查询直接比较每个表中的内容开始...

SELECT
  *
FROM
(
  SELECT
    CONCAT('[', document_type_name, ']') AS document_type_name
  FROM
    v_documents
  GROUP BY
    document_type_name
)
  AS documents
FULL OUTER JOIN
(
  SELECT
    CONCAT('[', type, ']') AS type
  FROM
    t_types
  GROUP BY
    type
)
  AS types
    ON types.type = documents.document_type_name
ORDER BY
  COALESCE(document_type_name, type)

This will show every type that exists in both tables, with what matches and what doesn't. 这将显示两个表中都存在的每种类型,哪些匹配,哪些不匹配。 The concatenation of the '[' and ']' will help spot leading/trailing spaces. '['']'的串联将有助于发现前导/尾随空格。

I'd love to see the results in your question. 我希望看到您的问题的结果。


EDIT : 编辑:

And you are certain that the following does not work? 并且您确定以下操作无效? (Exactly as is, with no other changes or additions?) (按原样,是否没有其他更改或添加?)

SELECT
  *
FROM
  v_documents
WHERE
  document_type_name IN (SELECT type FROM t_types)

If so, I can't explain it. 如果是这样,我无法解释。 The existence of any matches from the first query "proves" (or so I thought) that the IN (SELECT) version should be fine. 来自第一个查询的任何匹配项的存在“证明” (或者我认为) IN (SELECT)版本应该很好。

That said, here are some alternatives. 也就是说,这里有一些替代方案。

SELECT
  *
FROM
  v_documents
WHERE
  EXISTS (SELECT * FROM t_types WHERE t_types.type = v_documents.document_type_name)

Or... 要么...

SELECT
  v_documents.*
FROM
  v_documents
INNER JOIN
  t_types
    ON t_types.type = v_documents.document_type_name

If there are duplicates in t_types , then you need to use this instead... 如果t_types存在重复t_types ,那么您需要使用它来代替...

SELECT
  v_documents.*
FROM
  v_documents
INNER JOIN
(
  SELECT type FROM t_types GROUP BY type
)
  AS t_types
    ON t_types.type = v_documents.document_type_name

As a side benefit, as the number of types in t_types increases, each of these alternatives will often out perform use of IN (SELECT) any way. 附带的好处是,随着t_types中类型数量的增加,这些替代方案中的每一个通常都会以任何方式执行IN (SELECT)使用。


EDIT 2 : 编辑2:

This shouldn't make any difference that I'm aware of, but what happens if you try this? 我不应该知道这有什么区别,但是如果您尝试这样做会怎样?

SELECT
  *
FROM
  v_documents
WHERE
  CONCAT('[', document_type_name, ']')
  IN
  (SELECT DISTINCT CONCAT('[', type, ']') FROM t_types)

Try this: 尝试这个:

  SELECT * FROM v_documents WHERE UPPER(trim(document_type_name)) IN
    ( SELECT UPPER(trim(TYPE)) FROM t_types WHERE type IS NOT NULL);

Try this 尝试这个

SELECT *
FROM v_documents
WHERE trim(document_type_name) IN
    ( SELECT trim(TYPE)
     FROM t_types);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM