Home > Software engineering >  Oracle SQL Select: getting duplicate results joining tables
Oracle SQL Select: getting duplicate results joining tables

Time:10-18

I'm starting with SQL and doing some exercises and I'm completely stuck on the last one. It is about looking for streets in the same country name. Two tables are used, locations and countries from the HR schema. The problem is that I don't know how to avoid duplicate results. For example if I have the street "x" in Canada and the street "y" also in Canada, it shows me twice:

  1. street x / Canada / street y
  2. street y / Canada / street x and I can't find a way to correct this.

My select is:

SELECT DISTINCT A.STREET_ADDRESS AS "CALLE A", C.COUNTRY_NAME, B.STREET_ADDRESS AS "CALLE B"
FROM HR.LOCATIONS A JOIN HR.LOCATIONS B ON (A.STREET_ADDRESS <> B.STREET_ADDRESS), HR.COUNTRIES C
WHERE A.COUNTRY_ID = B.COUNTRY_ID AND B.COUNTRY_ID = C.COUNTRY_ID
ORDER BY C.COUNTRY_NAME

I get this Result_

RESULT

Any ideas? Thank you.

CodePudding user response:

use < instead of <>

SELECT DISTINCT A.STREET_ADDRESS AS "CALLE A", C.COUNTRY_NAME, B.STREET_ADDRESS AS "CALLE B"
FROM HR.LOCATIONS A JOIN HR.LOCATIONS B ON (A.STREET_ADDRESS > B.STREET_ADDRESS), HR.COUNTRIES C
WHERE A.COUNTRY_ID = B.COUNTRY_ID AND B.COUNTRY_ID = C.COUNTRY_ID
ORDER BY C.COUNTRY_NAME

CodePudding user response:

All the correct answers should be logically equivalent. You may want to use a form closer to this, however.

Ignore the alignment, unless you feel it helps readability (I happen to).

I'm referring more to the JOIN / ON form (avoid comma separated table expressions in the FROM clause, called <table reference list> ... a single <table reference> is usually sufficient), as @jarlh mentioned, and to keep the join criteria (in the ON clauses) nearer to the corresponding tables in the FROM clause, unless you have a particular reason to separate any of the logic to the WHERE clause (try to avoid that, unless necessary).

Logically, we can write these in lots of different ways. Some may be a little easier to write/read.

SELECT A.STREET_ADDRESS AS "CALLE A"
     , C.COUNTRY_NAME
     , B.STREET_ADDRESS AS "CALLE B"
  FROM HR.LOCATIONS A
  JOIN HR.LOCATIONS B
    ON A.COUNTRY_ID     = B.COUNTRY_ID
   AND A.STREET_ADDRESS < B.STREET_ADDRESS
  JOIN HR.COUNTRIES C
    ON B.COUNTRY_ID     = C.COUNTRY_ID
 ORDER BY C.COUNTRY_NAME
;

The inequality, as @nbk points out, avoids the street reflections.

SELECT DISTINCT isn't really needed for this, if your join logic and selected detail is sufficient to identify unique locations. If not, the result probably isn't practically useful.

If this is a small subset of sample data and/or these street addresses are unique within each country, then you're also ok, and DISTINCT isn't needed.

  • Related