80

I have a table with 3 columns like this:

+------------+---------------+-------+  
| Country_id | country_title | State |  
+------------+---------------+-------+    

There are many records in this table. Some of them have state and some other don't. Now, imagine these records:

1 | Canada  | Alberta  
2 |  Canada | British  Columbia  
3 | Canada  | Manitoba  
4 | China   |

I need to have country names without any duplicate. Actually I need their id and title, What is the best SQL command to make this? I used DISTINCT in the form below but I could not achieve an appropriate result.

SELECT DISTINCT title,id FROM tbl_countries ORDER BY title

My desired result is something like this:

1, Canada  
4, China
shA.t
  • 16,580
  • 5
  • 54
  • 111
Mohammad Saberi
  • 12,864
  • 27
  • 75
  • 127
  • 1
    What result did you get from the query you tried, and how does it differ from what you want? – Mark Byers Sep 02 '12 at 19:44
  • I'm getting a result set with many records containing Canada. – Mohammad Saberi Sep 02 '12 at 19:45
  • What do you want to happen instead? Can you show what your desired result set is. Make it explicit. By that I mean don't just describe what you want in your own words. Update your question showing the *exact* results you get and the *exact* results you want, in tabular format, and in a clear and precise way. – Mark Byers Sep 02 '12 at 19:47
  • You write "Actually I need their id and title" (i.e two columns) but in your edit the desired result only has one column. Please explain this discrepancy. – Mark Byers Sep 02 '12 at 19:50
  • It was my mistake, sorry for it. I will edit it – Mohammad Saberi Sep 02 '12 at 19:55
  • So you want the minimum ID for each country, right? – Mark Byers Sep 02 '12 at 19:58
  • 1
    @MarkByers I need to prevent duplicated records on country name. I mean I don't like to show the second Canada when I had 1 before. – Mohammad Saberi Sep 02 '12 at 20:04
  • 1
    Badly worded question - you give one set of column headings at top - then proceed to use another set in the SQL. – JGFMK Feb 18 '19 at 17:57

8 Answers8

130

Try this:

SELECT MIN(id) AS id, title
FROM tbl_countries
GROUP BY title
Mark Byers
  • 811,555
  • 193
  • 1,581
  • 1,452
52

DISTINCT is the keyword
For me your query is correct

Just try to do this first

SELECT DISTINCT title,id FROM tbl_countries

Later on you can try with order by.

shA.t
  • 16,580
  • 5
  • 54
  • 111
Immu
  • 746
  • 5
  • 10
  • 8
    Results of query will just remove `State` column, And it's not that the OP needs ;). – shA.t Apr 28 '15 at 07:03
  • 3
    This only makes sure that each resulting tuple from the query is unique, not that each value in a column is unique. – Jodo1992 May 02 '17 at 18:36
19

For using DISTINCT keyword, you can use it like this:

SELECT DISTINCT 
    (SELECT min(ti.Country_id) 
     FROM tbl_countries ti 
     WHERE t.country_title = ti.country_title) As Country_id
    , country_title
FROM 
    tbl_countries t

For using ROW_NUMBER(), you can use it like this:

SELECT 
    Country_id, country_title 
FROM (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY country_title ORDER BY Country_id) As rn
    FROM tbl_countries) t
WHERE rn = 1

Also with using LEFT JOIN, you can use this:

SELECT t1.Country_id, t1.country_title
FROM tbl_countries t1
    LEFT OUTER JOIN
    tbl_countries t2 ON t1.country_title = t2.country_title AND t1.Country_id > t2.Country_id
WHERE
    t2.country_title IS NULL

And with using of EXISTS, you can try:

SELECT t1.Country_id, t1.country_title
FROM tbl_countries t1   
WHERE
    NOT EXISTS (SELECT 1 
                FROM tbl_countries t2 
                WHERE t1.country_title = t2.country_title AND t1.Country_id > t2.Country_id)
shA.t
  • 16,580
  • 5
  • 54
  • 111
  • can this be used to select all data in a row? As all the examples im finding have the columns set and when i run it with select * it doesnt work. Not sure whether to pursue troubleshooting if these solutions wont work for Select * – Mafster Aug 28 '18 at 05:46
2

Try this one

SELECT country_id, country_title 
FROM (SELECT country_id, country_title,
CASE
WHEN country_title=LAG(country_title, 1, 0) OVER(ORDER BY country_title) THEN 1
ELSE 0
END AS "Duplicates"
FROM tbl_countries)
WHERE "Duplicates"=0;
M. Salem
  • 21
  • 2
1

In MySQL a special column function GROUP_CONCAT can be used:

SELECT GROUP_CONCAT(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'computers' AND
    TABLE_NAME='Laptop' AND
    COLUMN_NAME NOT IN ('code')
ORDER BY ORDINAL_POSITION;

It should be mentioned that the information schema in MySQL covers all database server, not certain databases. That is why if different databases contains tables with identical names, search condition of the WHERE clause should specify the schema name: TABLE_SCHEMA='computers'.

Strings are concatenated with the CONCAT function in MySQL. The final solution of our problem can be expressed in MySQL as:

SELECT CONCAT('SELECT ',
(SELECT GROUP_CONCAT(COLUMN_NAME)
 FROM INFORMATION_SCHEMA.COLUMNS
 WHERE TABLE_SCHEMA='computers' AND
    TABLE_NAME='Laptop' AND
        COLUMN_NAME NOT IN ('code')
 ORDER BY ORDINAL_POSITION
), ' FROM Laptop');

http://www.sql-ex.ru/help/select20.php

RMcLeod
  • 2,561
  • 1
  • 22
  • 38
1
select Country_id,country_title from(
   select Country_id,country_title,row_number() over (partition by country_title 
   order by Country_id  ) rn from country)a
   where rn=1;
Rich
  • 6,470
  • 15
  • 32
  • 53
Ashah
  • 11
  • 1
0

Ignore duplicate rows in SQL. I think this may help you.

    SELECT res2.*
    FROM
    (SELECT res1.*,ROW_NUMBER() OVER(PARTITION BY res1.title ORDER BY res1.id)as num
     FROM 
    (select * from [dbo].[tbl_countries])as res1
    )as res2
    WHERE res2.num=1
Selim Reza
  • 1,004
  • 9
  • 12
-2

Having Clause is the easiest way to find duplicate entry in Oracle and using rowid we can remove duplicate data..

DELETE FROM products WHERE rowid IN (
  SELECT MAX(sl) FROM (
  SELECT itemcode, (rowid) sl FROM products WHERE itemcode IN (
  SELECT itemcode FROM products GROUP BY itemcode HAVING COUNT(itemcode)>1
)) GROUP BY itemcode);
Jonathan
  • 6,507
  • 5
  • 37
  • 47
SUERSH K
  • 15
  • 1
  • 7
    Not a good idea to tell people to delete their data when they only want to view it. – moto Oct 29 '19 at 17:54