1

I'm using left join in MySQL as mentioned below:

SELECT Q.QUESTION_ID,
 school_id
FROM Q_MASTER AS Q
LEFT JOIN (
 SELECT keyword,
 school_id
 FROM E_HEADER
 WHERE low_q = 1
 AND school_id = 6
 ) AS X
 ON X.SCHOOL_ID = Q.SCHOOL_ID
WHERE Q.QUESTION_ID IN ( X.KEYWORD ) 

Here Q_MASTER is having question_id as primary key (INT). E_HEADER is having keyword as comma seperated values of question id. (VARCHAR100) Ex: 1,2,3,4

I want to exclude all question id's in select query from Q_MASTER which are present in "KEYWORD" column of E_HEADER

But above mentioned query is only execluding first value in comma seperated string. I tried , NOT EXISTS clause also, but every time only first comma seperated value is getting execluded.

Can you please let me know , how to solve this issue.

Sebastian Meine
9,1731 gold badge28 silver badges32 bronze badges
asked Sep 25, 2013 at 14:31

1 Answer 1

2

Storing a string of comma-separated values in a column is not an ideal design; ideally you would have a table of keywords and a 2-column map table with a row for every (E_HEADER.id,keyword_id).

However, given your current structure, the FIND_IN_SET() function should work, although this will not be the best possible performance, since a function in the where clause that takes a column as its argument will generally prevent the use of indexes for evaluating that condition -- but given your structure, you don't have an alternative.

FIND_IN_SET() returns the ordinal position of the first argument within the comma-separated string that is the second argument, or in this case "something true" if a match is found; no match returns 0 ("false") and if either argument is null, the function returns NULL.

Also, it's difficult to say without a better understanding of your structure exactly what you want the query to do, but the derived table seems unnecessary.

SELECT Q.question_id, Q.school_id
 FROM Q_MASTER Q
 LEFT JOIN E_HEADER X on X.school_id = Q.school_id AND X.low_q = 1 AND X.school_id = 6
 WHERE NOT FIND_IN_SET(Q.question_id, X.keyword);

This would select every question_id and school_id from Q_MASTER where there exists a row in E_HEADER with a matching school_id and low_q is equal to 1 and school_id is equal to 6 and where the value of Q.question_id is not found in the comma-separated string X.keyword.

Based on my interpretation of the original query, only Q_MASTER records with school_id = 6 will be returned in spite of the left join, because the join requires school_id to be identical, and will project a NULL for X.keyword otherwise; FIND_IN_SET() returns NULL if either argument is null, and the expression "NOT (NULL)" returns evaluates to NULL which will be considered untrue by the WHERE clause. The query will perform much better as an inner JOIN than a LEFT [outer] JOIN because fewer rows will need to be considered, but the ultimately correct approach requires a valid logical expression of what you actually need the server to do.

answered Sep 25, 2013 at 16:59
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.