简体   繁体   中英

SQL LEFT JOIN on two possible columns

We are adding a table to our database schema. It has a relationship to an already existing table, which we added a foreign key for. Mind you, I didn't create this schema nor do I have permission to change much. The application has been running for a while and they are hesitant to change much.

USER_ACTIVITY_T (preexisint table - only relevant columns referred)

  • activity_id (pk)
  • username
  • machineid (fk - recently added)

MACHINE_T (new table)

  • machineid (pk - auto increment)
  • machinename (unique)

From the point where I added the machine table, it collects machine data; allowing users to see what machines were involved during the activity. This is useful but it only shows data from the point that it was implemented. A lead asked me to attempt to fill preexisting records by referring to the username associated with the machine. We understand that this is not 100% accurate but... yeah. Our idea was to add username to MACHINE_T and use as a way to populate the machinename in reports retroactively (which assumes that the user has only used one machine and never changed their username).

So, the new MACHINE_T table would look like:

MACHINE_T (new table)

  • machineid (pk - auto increment)
  • machinename (unique)
  • username

Right now, our current SQL is:

SELECT * FROM `USER_ACTIVITY_T` LEFT JOIN `MACHINE_T` 
ON MACHINE_T.machineid=USER_ACTIVITY_T.machineid

Anyone have any suggestions on how to join on the username if USER_ACTIVITY_T.machineid is null but has a matching username? I'm sorry. This is an odd request that I may spend far too much time over-analyzing. Thank you for any help. I'm almost tempted to just say it can be reasonably done.

You want to select the joins from a when the joined column is not null and from b when it is null.

You dont want repeat information however so UNION may cause problems on its own.

Try only selecting the not null entries on the first join and then exclude the null entries from the second join before you union them.

So:

   SELECT * 
   FROM `USER_ACTIVITY_T` 
   LEFT JOIN `MACHINE_T` 
   ON MACHINE_T.machineid = USER_ACTIVITY_T.machineid

   UNION ALL

   SELECT * 
   FROM `USER_ACTIVITY_T` 
   JOIN `MACHINE_T` 
   ON MACHINE_T.username = USER_ACTIVITY_T.username
   WHERE USER_ACTIVITY_T.machineid IS NULL

This way you are basically using one query for the null entries and one for the not null entries and UNIONing them.

And, I just discovered the UNIION operator which will help me solve this. However, I am open to other solutions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM