Reputation: 10397
I have a table, say, country_previous and another table country_current. Both are same in structure, only the names are different. See the structure of them below :
CREATE TABLE `country_previous` (
`name` varchar(70) NOT NULL DEFAULT '',
PRIMARY KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 MAX_ROWS=100000000 AVG_ROW_LENGTH=50
and the other one
CREATE TABLE `country_current` (
`name` varchar(70) NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 |
So as the names indicate, country_previous has all the country names until, say an year ago, and country_current has all the countries until now. So I want to get all the countries that were created after the last update of country_previous. I tried this query, but it has many entries from country_previous.
SELECT count(*) FROM country_previous NATURAL RIGHT OUTER JOIN country_current WHERE country_previous.name IS NULL;
That gives more count than expected. For eg: my country_previous has 90 countries and country_current has 110 countries. Then, I should get only the new countries since then(country_previous's last update), which is 110 - 90 = 20. But I get more than 20.
so what's wrong with the query and what should I do ?
Thanks in advance.
PS : This country idea is just an example that really helps me to make others understand what I really need and I am not doing anything with country names actually.
Upvotes: 0
Views: 120
Reputation: 4627
The query returns unexpected results cause there might be some countries in country_previous that doesn't exist in the table country_current. Thus, when you make the verification country_previous.name IS NULL, it doesn't work on these records.
Upvotes: 0
Reputation: 9853
You could try using the following query:
select count(*) from country_current cc
where cc.name not in (select cp.name from country_previous cp);
This will give you a count of all country names in country_current
that are not in country_previous
(which I think is what you are after?).
Or, if you fancy using a join to do this then you could use something like the following:
insert into country_current values ('USA');
insert into country_current values ('China');
insert into country_current values ('Russia');
insert into country_current values ('UK');
insert into country_current values ('France');
insert into country_previous values ('Russia');
insert into country_previous values ('UK');
insert into country_preivous values ('France');
and then run:
select sum(case when cp.name is null then 1 else 0 end) as newCountries
from country_current cc
left outer join country_previous cp on cc.name = cp.name;
Upvotes: 2
Reputation: 2113
If the country names are similar then minus query is as follows
SELECT count(*) from (
SELECT cc.name from country_current cc
MINUS
SELECT cp.name from country_previous cp)
Upvotes: 0