I have a table with id and code entries. Codes are unique, but id is the primary key.
ID Code
1 ABC1234T
2 ABC6789Y
3 ABC9999A
4 QAZ1234G
5 QAZ6574U
6 QAZ9999A
7 TRE1234Y
8 REW1234U
I need to find prefixes (first 3 letters) that don't have *999A entry. In the given example it'll be TRE and REW. My query is slow, it takes 17 seconds to run on ~9000 records. I understand it's mostly because I'm using NOT IN and subquery. Could anyone give me some ideas how to optimize it?
SELECT distinct LEFT(newcode, 3) as codeprefix FROM diatcode where (LEFT(newcode, 3)) NOT in (select DISTINCT LEFT(newcode, 3) from diatcode where newcode like '___9999A' ) order by newcode
You can do a left join and then filter based on null values. It avoids the subquery, but I am not sure that this is the fastest solution.
SELECT DISTINCT LEFT(d1.newcode, 3) as codeprefix
FROM diatcode d1
LEFT JOIN (SELECT DISTINCT LEFT(d2.newcode, 3) as codeprefix
FROM diatcode d2
WHERE d2.newcode LIKE '___9999A') t2
ON LEFT(d1.newcode, 3)=t2.codeprefix
WHERE t2.codeprefix IS NULL;
Although lp_'s solution is perfectly OK, I'd personally go for the much more readable syntax of WHERE NOT EXISTS()
SELECT distinct LEFT(d1.newcode, 3) as codeprefix
FROM diatcode d1
WHERE NOT EXISTS ( SELECT *
FROM diatcode d2
WHERE d2.newcode = LEFT(d1.newcode, 3) + '9999A' )
Should be similarly fast, if not faster, especially if there is a unique index/constraint on the newcode
column.
PS: your original query had ORDER BY newcode while in fact said field is not part of the resultset. I presume you wanted to add ORDER BY Left(d1.newcode, 3)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.