0

I have been investigating this topic but it is not quite what I need and I do not understand how to solve it.

Table: companies

Columns: id, cust_number, cust_name

There may be many records with the same cust_number, but all such records should have identical cust_name.

The query I am trying to write should display all records where this is not the case - like this:

| id | cust_number | cust_name |
| -- | ----------- | --------- | 
| 10 |    800      | Acme LTD  | 
| 11 |    700      | Globex    | 
| 12 |    800      | Acme LTD  | 
| 13 |    444      | Globex    | 
| 14 |    800      | Acme LTT  | 

From the table above the query should result in:

| id | cust_number | cust_name |
| -- | ----------- | --------- | 
| 10 |    800      | Acme LTD  | 
| 12 |    800      | Acme LTD  | 
| 14 |    800      | Acme LTT  | 

Because there are more than 1 records with the same cust_number but all 3 records does not have identical cust_name.

Thanks for all help!

oldeagle
  • 9
  • 1

3 Answers3

1

You can use EXISTS to check for records with the same cust_number but different name.

SELECT c1.id,
       c1.cust_number,
       c1.cust_name
       FROM companies c1
       WHERE EXISTS (SELECT *
                            FROM companies c2
                                 WHERE c2.cust_number = c1.cust_number
                                       AND c2.cust_name <> c1.cust_name);
sticky bit
  • 31,711
  • 12
  • 26
  • 38
  • I have tried this but it does not return anything. Please note that it should show records with the same cust_number, not the same ID... – oldeagle Mar 05 '20 at 12:56
  • @oldeagle: Changed `id` to `cust_number`, see the edit. – sticky bit Mar 05 '20 at 13:00
  • Thanks, sticky bit. That worked but the query takes a very long time to run. I may have to think of another way to solve the problem. – oldeagle Mar 05 '20 at 15:22
0

Assuming MySQL 8.0, you can use window functions for this:

select id, cust_number, cust_name
from (
    select 
        t.*,
        min(cust_name) over(partition by cust_number) min_cust_name,
        max(cust_name) over(partition by cust_number) max_cust_name
    from mytable t
) t
where min_cust_name <> max_cust_name
GMB
  • 188,822
  • 23
  • 52
  • 100
0

Probably an issue you're running into here is that (usually) string comparison in MySQL is case-insensitive - see "How can I make SQL case sensitive string comparison on MySQL? ".

i.e. SELECT ('Acme LTD' = 'Acme Ltd'); returns 1 or TRUE.

You can circumvent this by comparing the binary representation of the strings; SELECT (BINARY 'Acme LTD' = BINARY 'Acme Ltd'); returns 0.


With that in mind, the following query should return what you're looking for;

SELECT DISTINCT t1.id
              , t1.cust_number
              , t1.cust_name
FROM my_table t1
         JOIN my_table t2 ON t2.cust_number = t1.cust_number AND
                             (BINARY t2.cust_name <> BINARY t1.cust_name)
ORDER BY t1.id;
Job Curtis
  • 185
  • 10