I’m working on multiple data tables, trying to figure out the best method of joining them. I’m using a primary table (let’s name it Devices
) along with additional ones, Settings
. All mentioned tables contain DeviceID
‘s, which I use as a device identifier.
Thing is, that when there are distinct device records in the Devices
table, the Settings
table may contain more than one record per device.
The basic device table structure looks like this:
| deviceId | deviceName | | -------- | -------------- | | 0001 | device01 | | 0002 | device02 | | 0003 | device03 |
Settings
however uses its own records identifier, thus looks like this is many cases:
| recordId | deviceId | settingState | | -------- | -------- | -------------- | | 1 | 0001 | OK | | 2 | 0001 | OK | | 3 | 0001 | NOK | | 4 | 0002 | NOK | | 5 | 0002 | N/A | | 6 | 0003 | N/A |
What I’m trying to achieve is this: if a device has a record present with an “OK” setting state (among all other records matching ‘deviceId’), this status is to be returned. If a machine has no “OK” matching record present – then “NOK” is considered a next priority, with “N/A” returned only, when there are no “OK” and “NOK” status records returned.
Example result:
| deviceId | deviceState | | -------- | -------------- | | 0001 | OK | | 0002 | NOK | | 0003 | N/A |
So far I succeeded without an issue with JOIN on devices, when there is a 1-1 relation, however I’m stuck on processing more than one records per device.
I tried with CASE
but I was unable to properly construct a JOIN
to work on DeviceId
through separate SELECT
statements. Thanks in advance!
Advertisement
Answer
You can use row_number()
:
select s.* from (select s.*, row_number() over (partition by deviceid order by case settingState when 'OK' then 1 when 'NOK' then 2 when 'N/A' then 3 else 4 end ) as seqnum from settings s ) s where seqnum = 1;
A fun method uses aggregation:
select deviceid, coalesce(max(case when settingState = 'OK' then settingState end), max(case when settingState = 'NOK' then settingState end), max(case when settingState = 'N/A' then settingState end), max(settingState) ) as settingState from settings s group by deviceid;