Reputation: 933
I have a view called "v_documents" where a i have a field "document_type_name" that is based on some fields. 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.
It give me 0 records.
But if i use =
istead of IN()
and i return only one record from the subquery it works.
The problem is that if i'm not wrong this code worked before. I don't know what is happening.
P.S The t_types
table DON'T HAVE null values!
EDIT: using the subquery in a field seems work. Why in the IN() not?
Here a screen: on the left the subquery used as field, on the right the return records from SELECT type FROM t_types
EDIT 2: Screen for @MatBailie's answere. But i used a LEFT JOIN
instead of LEFT OUTER JOIN
because i get a MySQL error.
Upvotes: 1
Views: 57
Reputation: 86765
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.
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...
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.
EDIT 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)
Upvotes: 1
Reputation: 2155
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);
Upvotes: 0
Reputation: 18600
Try this
SELECT *
FROM v_documents
WHERE trim(document_type_name) IN
( SELECT trim(TYPE)
FROM t_types);
Upvotes: 0