0

I have two tables, "records", and "info".

The "records" table looks like:

mysql> SELECT * FROM records WHERE num = '7';
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+
| id  | city   | st | type | num | val | startdate  | status    | comments | updated             |
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+
| 124 | Encino | CA | AAA  | 7   |   1 | 1993-09-01 | allocated |          | 2014-02-26 08:16:07 |
+-----+--------+----+------+-----+-----+------------+-----------+----------+---------------------+

and so on. Think of the "num" field in this table as a Company ID.

The "info" table contains information about certain companies, and uses that company id as a unique identifier. Not all companies listed in "records" will be in "info". An example of the "info" table:

mysql> SELECT * FROM info LIMIT 2;
+-----+-------+--------------------------+---------------------+
| org | name  | description              | updated             |
+-----+-------+--------------------------+---------------------+
|   0 | ACME  |                          | 2014-02-19 10:35:39 |
|   1 | AT&T  | Some Phone Company, Inc. | 2014-02-18 15:29:50 |
+-----+-------+--------------------------+---------------------+

So "org" here will match "num" in the first table.

I want to be able to run a query that returns, on one line, everything but 'id', 'type' and 'val' from the 1st table, and IF APPLICABLE, the 'name' and 'description' from the 2nd table.

I can achieve what I want using this query:

SELECT city,st,num,startdate,status,comments,updated, \
( SELECT name FROM info WHERE org = '7') AS name, \
( SELECT description FROM info WHERE org = '7') AS description \
FROM records WHERE num = '7'

But I see at least two problems with it:

  1. It seems inefficient to run two subqueries
  2. When there is no record in "info", NULL is printed for the name and description. I would like to print some string instead.

To address the first problem, I tried to return an array. But when no corresponding record exists in the "info" table, then I get nothing, not even the valid info from the "records" table. Here's my array query:

SELECT city,st,num,startdate,status,comments,updated,asinfo.name AS name,asinfo.description AS description \
FROM records, \
( SELECT name,description FROM info WHERE org = '7') AS asinfo \
WHERE num = '7'

This query works fine if a given company id exists in both tables.

To address the second problem, I tried various incantations of IFNULL and coalesce, to no avail.

I'd appreciate any insight.

Thanks.

2
  • 2
    What's wrong with a normal LEFT JOIN? Commented Feb 27, 2014 at 13:38
  • probably nothing...I've never used it. I will research it now (unless you can post a quick example) Commented Feb 27, 2014 at 13:42

3 Answers 3

2

Apply LEFT JOIN syntax:

SELECT 
  r.city,
  r.st,
  r.num,
  r.startdate,
  r.status,
  r.comments,
  r.updated,
  IF(d.name IS NULL, 'Default', d.name) AS name,
  IF(d.description IS NULL, 'Default', d.description) AS description
FROM
  records AS r
    LEFT JOIN info AS d ON r.num=d.org
WHERE
  r.num='7'

that will work such way: LEFT JOIN looks into first table, and, if there are no corresponding records in second, it applies NULL. So you'll discover that with IF (or IFNULL) and do substitution of default string.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks for your response, @Alma Do. i appreciate your stringent syntax - makes it easier to understand.
1

Use a LEFT JOIN to get null values when there's no matching row in the info table.

SELECT city,st,num,startdate,status,comments,updated,
       IFNULL(name, 'Default Name') name, 
       IFNULL(description, 'Default Description') description
FROM records r
LEFT JOIN info i ON r.num = i.org
WHERE r.num = 7

1 Comment

Thanks @Barmar, that did the trick all right. I had to use r.updated b/c that field exists in both tables.
1

It sounds like a simple LEFT JOIN from record to info will do the trick.

LEFT JOIN rather than JOIN in order to ensure you ALWAYS get all rows from the record table, and then the corresponding data in info table if a xref exists for that ID.

Whether using your sub-queries or using joins, if you always want to see all rows in record table, then you will always get NULLs corresponding to the info table where no xref exists. The only way to avoid that is to run some code that calls everything from record, and then iterates over the results to query info, to conditionally add to the record data.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.