Put value in minimum ID record in SQL data set - sql

I have a table where I'm trying to get the following result: CategoryType should be set to 0 for the member record with the lowest categoryID and 1 if that ID is NULL. CategoryType is not a field from the table so it should be added via a Case statement. I wrote a script using the Row_Number() window function to organize the records but I'm not sure how to put a 0 for the lowest record. I tried using a Min(Case) statement but that didn't work.
declare #t table(memberid int, lastname varchar(50), firstname varchar(50), categoryid int)
insert into #t
values(1, 'Jones', 'Tom', 2), (1, 'Jones', 'Tom', 4),
(2, 'Hanson', 'Ron', 3), (2, 'Hanson', 'Ron', 4),
(2, 'Hanson', 'Ron', 5),
(3, 'Smith', 'Jack', NULL);
This is the result I'm trying to get:
MemberID LastName FirstName CategoryID CategoryType
1 Jones Tom 2 0
1 Jones Tom 4 NULL
2 Hanson Ron 3 0
2 Hanson Ron 4 NULL
2 Hanson Ron 5 NULL
3 Smith Jack NULL 1

Or this:
select *
,case
when categoryid is null then 1
when FIRST_VALUE(categoryid) over (partition by memberid order by categoryid) = categoryid then 0 else null
end as x
from #t

I think you want this
SELECT *,CASE WHEN categoryid IS NULL THEN 1
WHEN ROW_NUMBER() OVER (PARTITION BY categoryid ORDER BY memberid) = 1
THEN 0
END CategoryType FROM #T

Easier to read/extend (if needed):
SELECT a.MemberID,a.LastName,a.FirstName,a.CategoryID
,CASE
WHEN a.rn = 1 AND a.CategoryID IS NULL THEN 1
WHEN a.rn = 1 THEN 0
ELSE NULL
END AS [CategoryType]
FROM (
SELECT t.MemberID,t.LastName,t.FirstName,t.CategoryID
,ROW_NUMBER()OVER(PARTITION BY t.MemberID ORDER BY t.CategoryID) AS [rn]
FROM #t t
) a
;

I think you want:
select t.*,
(case when categoryid is null
then 1
when row_number() over (partition by memberid order by categoryid) = 1
then 0
end) as categorytype
from #t t;
Here is a db<>fiddle.

Hope Can Help You
declare #t table(memberid int,
lastname varchar(50),
firstname varchar(50),
categoryid int)
insert into #t
values(1, 'Jones', 'Tom', 2),
(1, 'Jones', 'Tom', 4),
(2, 'Hanson', 'Ron', 3),
(2, 'Hanson', 'Ron', 4),
(2, 'Hanson', 'Ron', 5),
(3, 'Smith', 'Jack', NULL)
Select
A.*,
Case When a.categoryid is null Then '1'
When b.categoryid is not null Then '0' Else null End CategoryType
From #t A
Left Join (
Select memberid, min(categoryid) categoryid From #t
Group By memberid
) B On B.memberid = A.memberid and B.categoryid = A.categoryid

Related

Search for records that do not contain a specific value

I have a table that contains IDs from two other tables. Those are two integer numbers.
CustomerId SectionId
====================
1 1
1 2
1 3
2 2
2 3
3 1
3 2
3 3
4 2
4 3
What I am looking for is for those records that have the SectionId=1 missing. For the above example I need to retrieve CustomerId 2 and 4.
I cannot do a Select customer ID where SectionId <> 1 because it will bring me all records (1 to 4). I specifically need those that, independently of which SectionId they have, are missing SectionId=1
Thanks.
You need NOT EXISTS:
SELECT DISTINCT t1.CustomerId
FROM tablename t1
WHERE NOT EXISTS (SELECT 1 FROM tablename t2 WHERE t2.CustomerId = t1.CustomerId AND t2.SectionId = 1)
Or, with conditional aggregation:
SELECT CustomerId
FROM tablename
GROUP BY CustomerId
HAVING COUNT(CASE WHEN SectionId = 1 THEN 1 END) = 0
Try this
select distinct id
from Test
where id not in (
select distinct id
from Test
where section = 1
);
check 2 examples
Declare #t Table (CustomerId int, SectionId int)
insert into #t Values
(1, 1),
(1, 2),
(1, 3),
(2, 2),
(2, 3),
(3, 1),
(3, 2),
(3, 3),
(4, 2),
(4, 3)
select DISTINCT CustomerId from #t
where CustomerId not in (
select CustomerId from #t
where SectionId = 1
group by CustomerId
)
SELECT DISTINCT t1.CustomerId
FROM #t t1
WHERE NOT EXISTS (SELECT * FROM #t t2
WHERE t2.CustomerId = t1.CustomerId AND t2.SectionId = 1)

Get all subordinates based on line manager marker

I have an employees table that holds an employeeID, Name...etc.... and intLineManager. intLine manager is the employeeID of your line manager. Something like this, with Dave being the top boss with no manager.
intEmpID |Name|intLineManager
1 |Dave| NULL
2 |Sue |1
3 |Mike|1
4 |Matt|2
5 |Sara|3
6 |Paul|4
I'm looking for an SQL script that will return all employees that are underneath a person.
So a search on Mike will return Sara, a search on Sue will return Matt + Paul and finally a search on Dave will return everyone.
You can use a recursive CTE like so:
CREATE TABLE #Employees(EmpID int, Name varchar(10), LineManager int NULL)
INSERT INTO #Employees VALUES
(1, 'Dave', NULL),
(2, 'Sue', 1),
(3, 'Mike', 1),
(4, 'Matt', 2),
(5, 'Sara', 3),
(6, 'Paul', 4)
;WITH CTE as
(
SELECT EmpID, Name, LineManager
FROM #Employees
WHERE EmpID = 2 --Sue
UNION ALL
SELECT e.EmpID, e.Name, e.LineManager
FROM #Employees AS E
INNER JOIN CTE AS C ON c.EmpID = e.LineManager
)
SELECT *
FROM CTE
where EmpID > (SELECT TOP 1 EmpID FROM CTE)
ORDER BY EmpID
Result for sue(EmpID 2)
EmpID Name LineManager
----------- ---------- -----------
4 Matt 2
6 Paul 4

How to get first value from first row and last value from last row in SQL Server

I have a table in SQL Server as below
+---+-------------+-------------+-------------+
|Id | FromCity | ToCity | RequestId |
+---+-------------+-------------+-------------+
| 1 | Mysore | Atlanta | 12 |
+---+-------------+-------------+-------------+
| 2 | Atlanta | Singapore | 12 |
+---+-------------+-------------+-------------+
| 3 | Singapore | Pakistan | 12 |
+---+-------------+-------------+-------------+
| 4 | Pakistan | Myscot | 12 |
+---+-------------+-------------+-------------+
| 5 | Rome | Singapore | 13 |
+---+-------------+-------------+-------------+
Here, I am trying to get a value as From and To Cities (Round Trip Data) (i.e. Mysore - > Myscot for the RequestId =12). Ho to get this value?
When I pass RequestId=12, I should get the value as Mysore -> Myscot
I Tried as below:
SELECT MIN(FromCity) [From],
MAX(ToCity) [To]
FROM MyTable
WHERE RequestId = 12
But I'm getting Mysore -> Singapore (based on string MIN and MAX).
Check This :
SELECT M.FromCity [From],
M2.ToCity [To]
FROM #MyTable M
Inner join (select Min(ID) min ,Max(ID) max from #MyTable M2 WHERE M2.RequestId = 12 )
A on A.Min =ID
Inner join #MyTable M2 on M2.ID=A.Max
Output :
SELECT RequestId,
f.FromCity [From],
t.ToCity [To]
FROM MyTable t
CROSS APPLY (
SELECT TOP (1) FromCity
FROM MyTable
WHERE RequestId = t.RequestId
ORDER BY Id ASC
) f
CROSS APPLY (
SELECT TOP (1) ToCity
FROM MyTable
WHERE RequestId = t.RequestId
ORDER BY Id DESC
) t
WHERE RequestId = 12
The only logic I see is using the Id from your table and do something like this. Using CTE you will find the MIN and MAX id per request, that means from city - to city.
And after that you join your table to the CTE to find the actual values.
declare #tbl as table
([Id] int, [FromCity] varchar(9), [ToCity] varchar(9), [Date Created] datetime, [RequestId] int)
;
INSERT INTO #tbl
([Id], [FromCity], [ToCity], [Date Created], [RequestId])
VALUES
(1, 'Mysore', 'Atlanta', '2018-10-05 15:10:00', 12),
(2, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 12),
(3, 'Singapore', 'Pakistan', '2018-10-07 15:10:00', 12),
(4, 'Pakistan', 'Myscot', '2018-10-07 15:10:00', 12),
(5, 'UK', 'Atlanta', '2018-10-06 15:10:00', 13),
(6, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 13),
(7, 'Singapore', 'Italy', '2018-10-23 15:10:00', 13);
;with cte as (
select
MIN(Id) as [start]
,MAX(Id) as [end]
,RequestId
from #tbl
group by requestID
)
select
t1.FromCity
,t1.[Date Created]
,t2.ToCity
,t2.[Date Created]
from cte
inner join #tbl t1
on t1.Id = cte.[start]
and t1.RequestId = cte.RequestId
inner join #tbl t2
on t2.Id = cte.[end]
and t2.RequestId = cte.RequestId
Update: based on #Panagiotis Kanavos comment you can simplify the query like this
;with cte as (
select
MIN(Id) as [start]
,MAX(Id) as [end]
from #tbl
where RequestId = 12 ---> here you can use a variable containing the requestID
)
select
t1.FromCity
--,t1.[Date Created]
,t2.ToCity
--,t2.[Date Created]
from cte
inner join #tbl t1
on t1.Id = cte.[start]
inner join #tbl t2
on t2.Id = cte.[end]
If Id in main table is used to describe travel order then something like this will work:
SELECT startLocation.FromCity [From], endLocation.ToCity AS [To]
FROM (
SELECT MIN(Id) AS StartLocationId, MAX(Id) AS EndLocationId
FROM MyTable
WHERE RequestId = 12
) AS a
INNER JOIN MyTable AS startLocation ON a.StartLocationId = startLocation.Id
INNER JOIN MyTable AS endLocation ON a.EndLocationId = endLocation.Id
This is a example of solution for situation when ids are just ids and don`t match travel order:
declare #tbl as table
([Id] int, [FromCity] varchar(9), [ToCity] varchar(9), [Date Created] datetime, [RequestId] int)
;
INSERT INTO #tbl
([Id], [FromCity], [ToCity], [Date Created], [RequestId])
VALUES
(19, 'Mysore', 'Atlanta', '2018-10-05 15:10:00', 12),
(22, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 12),
(1, 'Singapore', 'Pakistan', '2018-10-07 15:10:00', 12),
(4, 'Pakistan', 'Myscot', '2018-10-07 15:10:00', 12),
(5, 'UK', 'Atlanta', '2018-10-06 15:10:00', 13),
(0, 'Atlanta', 'Singapore', '2018-10-06 15:10:00', 13),
(-1, 'Singapore', 'Italy', '2018-10-23 15:10:00', 13)
;
select * from #tbl
declare #Id int = 12
declare #FromStart nvarchar(255), #ToStart nvarchar(255)
declare #StartResult nvarchar(255), #ToResult nvarchar(255)
declare #StartResultFound bit = 0, #ToResultFound bit = 0
-- select random starting point
select #FromStart = [FromCity], #ToStart = [ToCity] from #tbl where [RequestId] = #Id
ORDER BY NEWID()
select #FromStart, #ToStart
while (#StartResultFound = 0)
begin
if exists (select top 1 1 from #tbl where [RequestId] = #Id and [ToCity] = #FromStart)
begin
select top 1 #FromStart = [FromCity] from #tbl where [RequestId] = #Id and [ToCity] = #FromStart
end
else
begin
set #StartResultFound = 1
set #StartResult = #FromStart
end
end
while (#ToResultFound = 0)
begin
if exists (select top 1 1 from #tbl where [RequestId] = #Id and [FromCity] = #ToStart)
begin
select top 1 #ToStart = [ToCity] from #tbl where [RequestId] = #Id and [FromCity] = #ToStart
end
else
begin
set #ToResultFound = 1
set #ToResult = #ToStart
end
end
select #StartResult, #ToResult
maybe this is whar you need
DECLARE
#t TABLE (
ID INT
, FromCity VARCHAR(250)
, ToCity VARCHAR(250)
, RequestId INT
)
INSERT INTO #t VALUES
(1,'Mysore','Atlanta',12)
,(2,'Atlanta','Singapore',12)
,(3,'Singapore','Pakistan',12)
,(4,'Pakistan','Myscot',12)
,(5,'Rome','Singapore',13)
SELECT DISTINCT
ISNULL(FromCity, ISNULL(NextCity, PreCity) ) FromCity
, ISNULL(ToCity, ISNULL(NextCity2, PreCity2) ) FromCity
FROM (
SELECT
CASE WHEN RN = 1 THEN FromCity END FromCity
, CASE WHEN RN = CNT THEN ToCity END ToCity
, LEAD(CASE WHEN RN = 1 THEN FromCity END) OVER(PARTITION BY RequestId ORDER BY ID) NextCity
, LEAD(CASE WHEN RN = CNT THEN ToCity END) OVER(PARTITION BY RequestId ORDER BY ID) NextCity2
, LAG(CASE WHEN RN = 1 THEN FromCity END) OVER(PARTITION BY RequestId ORDER BY ID) PreCity
, LAG(CASE WHEN RN = CNT THEN ToCity END) OVER(PARTITION BY RequestId ORDER BY ID) PreCity2
FROM (
SELECT
*, ROW_NUMBER() OVER(PARTITION BY RequestId ORDER BY ID) RN
, COUNT(ToCity) OVER(PARTITION BY RequestId) CNT
FROM #t
) D
WHERE
RN = 1 OR RN = CNT
) C
A recursive version, not depending on Ids order. The idea is to build the biggest chain of trip connected by To / From cities.
WITH cte1 AS (
-- start with all trips as 1 hop chain
SELECT [FromCity], [ToCity], 1 AS HOP
FROM Mytable
WHERE REQUESTID = 12
UNION ALL
-- recursively add one hop if we find a trip ending in start city of the chain
SELECT T.[FromCity], cte1.[ToCity], cte1.HOP + 1
FROM cte1
JOIN Mytable t
ON t.[ToCity] = cte1.[FromCity]
WHERE t.REQUESTID = 12
)
, cte2 AS (
-- order by number of hops
SELECT [FromCity], [ToCity], ROW_NUMBER() OVER (ORDER BY HOP DESC) AS N
FROM cte1
)
-- choose the chain with the more hops
SELECT [FromCity], [ToCity]
FROM cte2
WHERE N = 1
try this code
SELECT MIN(Id) [From],
MAX(Id) [To]
FROM MyTable
WHERE RequestId = 12

Limiting Join Qty

If I have a couple of tables like the following
Table1
-----------------------------
Name Qty
-----------------------------
John 1
Paul 2
...
Ringo 1
and
Table2
-----------------------------
Forename Surname Cost
-----------------------------
John Smith 123
John Jones 815
Paul Smith 273
Paul Jones 297
...
Ringo Smith 755
Ringo Jones 334
and I want to construct a query so the quantity returned from Table2 by each subset is ordered by Table2.Cost and limited by Table1.Qty, to return something like:
Results
-----------------------------
Forename Surname Cost
-----------------------------
John Jones 815
Paul Jones 297
Paul Smith 273
Ringo Smith 755
Is there a way to do this?
Try this one
SELECT T.Forename,T.Surname, T.Cost
FROM
(
SELECT *,
ROW_NUMBER() OVER ( PARTITION BY Forename ORDER BY Cost DESC )
AS rn
FROM Table2
) T
JOIN Table1 ON Table2.Foreman=Table1.Name
WHERE T.rn <=Qty;
SELECT Forename,
Surname,
Cost
FROM
(
SELECT *,
ROW_NUMBER() OVER ( PARTITION BY Forename ORDER BY Cost DESC )
AS rn
FROM Table2
)
WHERE rn = 1;
create table #table1(name varchar(100), qty int)
create table #table2 (forename varchar(100), surname varchar(100), cost int)
insert into #table1 values
('John',1),
('Paul',2),
('Ringo',1)
insert into #table2 values
('John' , 'Smith' , 123),
('John' , 'Jones' , 815 ) ,
('Paul' , 'Smith' , 273),
('Paul' , 'Jones' , 297),
('Ringo' , 'Smith' , 755),
('Ringo' , 'Jones' , 334)
select * from
#table1 t1 cross apply
(select top (t1.qty) * from #table2 t2 where t1.name = t2.forename order by t2.cost desc) t
Updated and Tested: If it's about getting the highest cost from Table 2 depending upon Qty from Table 1, then use the following:
CREATE TABLE #table1 (name NVARCHAR(100), qty INT);
CREATE TABLE #table2 (forename NVARCHAR(100), surname NVARCHAR(100), cost INT);
INSERT INTO #table1 VALUES
('John', 1),
('Paul', 2),
('Ringo', 1);
INSERT INTO #table2 VALUES
('John', 'Smith', 123),
('John', 'Jones', 815 ),
('Paul', 'Smith', 273),
('Paul', 'Jones', 297),
('Ringo', 'Smith', 755),
('Ringo', 'Jones', 334);
WITH DATA AS (
SELECT t2.forename, t2.surname, t2.cost, t1.qty,
rn = ROW_NUMBER() OVER (PARTITION BY t1.name ORDER BY t2.cost DESC)
FROM
#table1 t1
INNER JOIN #table2 t2 ON t1.name = t2.forename
)
SELECT d.forename, d.surname, d.cost
FROM
DATA d
WHERE d.rn <= d.qty

SQL query to reconstruct inherited EAV model

I have 5 tables in my database representing an inherited EAV model:
CREATE TABLE AttributeNames
("ID" int, "Name" varchar(8))
;
INSERT INTO AttributeNames
("ID", "Name")
VALUES
(1, 'Color'),
(2, 'FuelType'),
(3, 'Doors'),
(4, 'Price')
;
CREATE TABLE MasterCars
("ID" int, "Name" varchar(10))
;
INSERT INTO MasterCars
("ID", "Name")
VALUES
(5, 'BMW'),
(6, 'Audi'),
(7, 'Ford')
;
CREATE TABLE MasterCarAttributes
("ID" int, "AttributeNameId" int, "Value" varchar(10), "MasterCarId" int)
;
INSERT INTO MasterCarAttributes
("ID", "AttributeNameId", "Value", "MasterCarId")
VALUES
(100, 1, 'Red', 5),
(101, 2, 'Gas', 5),
(102, 3, '4', 5),
(102, 4, '$100K', 5),
(103, 1, 'Blue', 6),
(104, 2, 'Diesel', 6),
(105, 3, '3', 6),
(106, 4, '$80k', 6),
(107, 1, 'Green', 7),
(108, 2, 'Diesel', 7),
(109, 3, '5', 7),
(110, 4, '$60k', 7)
;
CREATE TABLE LocalCars
("ID" int, "MasterCarId" int)
;
INSERT INTO LocalCars
("ID", "MasterCarId")
VALUES
(8, '5'),
(9, '6'),
(10, NULL)
;
CREATE TABLE LocalCarAttributes
("ID" int, "AttributeNameId" int, "Value" varchar(6), "LocalCarId" int)
;
INSERT INTO LocalCarAttributes
("ID", "AttributeNameId", "Value", "LocalCarId")
VALUES
(43, 1, 'Yellow', 8),
(44, 3, '6', 9),
(45, 1, 'Red', 10),
(46, 2, 'Gas', 10),
(47, 3, '2', 10),
(48, 4, '$60k', 10)
;
I can retrieve all of master car attributes as follows:
SELECT MC.ID, MCA.AttributeNameId, MCA.Value
FROM MasterCars MC
left join MasterCarAttributes MCA on MC.ID = MCA.MasterCarId
order by MC.ID;
Likewise, I can retrieve all of the local car attributes as follows:
SELECT LC.ID, LCA.AttributeNameId, LCA.Value
FROM LocalCars LC
left join LocalCarAttributes LCA on LC.ID = LCA.LocalCarId
order by LC.ID;
If LocalCars.MasterCarId is not NULL, then that local car can inherit the attributes of that master car. A local car attribute with the same AttributeNameId overrides any master attribute with the same AttributeNameId.
So given the data above, I have 3 local cars each with 4 attributes (color, fuelType, doors, price). Inherited attribute values in bold:
Local Car Id = 1 (Yellow, Gas, 4, $100K)
Local Car Id = 2 (Blue, Diesel, 6, $80k)
Local Car Id = 3 (Red, Gas, 2, $60k)
I'm trying to find the necessary joins required to join the two queries above together to give a complete set of local cars attributes, some inherited:
LocalCarId AttributeNameId Value
------------------------------------------
1 1 Yellow
1 2 Gas
1 3 4
1 4 $100K
2 1 Blue
2 2 Diesel
2 3 6
2 4 $80K
3 1 Red
3 2 Gas
3 3 2
3 4 $60K
or possibly even:
LocalCarId AttributeNameId LocalValue MasterValue
-------------------------------------------------------------
1 1 Yellow Red
1 2 NULL Gas
1 3 NULL 4
1 4 NULL $100K
2 1 NULL Blue
2 2 NULL Diesel
2 3 6 3
2 4 NULL $80K
3 1 Red NULL
3 2 Gas NULL
3 3 2 NULL
3 4 $60K NULL
The problem can be solved by performing a union on all of your local car attributes and master car attributes. Each record is marked with an [IsMasterAttribute] flag. The next step is then use the ROW_NUMBER() window function to rank each of the duplicate attributes. The final step is to only select attributes which has a rank of 1.
;WITH CTE_CombinedAttributes
AS
(
SELECT 1 AS IsMasterAttribute
,LC.ID
,MC.ID AS MasterCarId
,MCA.AttributeNameId
,MCA.Value
FROM MasterCars MC
LEFT OUTER JOIN MasterCarAttributes MCA on MC.ID = MCA.MasterCarId
INNER JOIN LocalCars LC ON LC.MasterCarId = MC.ID
UNION ALL
SELECT 0 AS IsMasterAttribute
,LC.ID
,LC.MasterCarId
,LCA.AttributeNameId
,LCA.Value
FROM LocalCars LC
LEFT OUTER JOIN LocalCarAttributes LCA on LC.ID = LCA.LocalCarId
)
,
CTE_RankedAttributes
AS
(
SELECT [IsMasterAttribute]
,[ID]
,[AttributeNameId]
,[Value]
,ROW_NUMBER() OVER (PARTITION BY [ID], [AttributeNameId] ORDER BY [IsMasterAttribute]) AS [AttributeRank]
FROM CTE_CombinedAttributes
)
SELECT [IsMasterAttribute]
,[ID]
,[AttributeNameId]
,[Value]
FROM CTE_RankedAttributes
WHERE [AttributeRank] = 1
ORDER BY [ID]
The second output is also possible by performing a simple pivot on the final result:
;WITH CTE_CombinedAttributes
AS
(
SELECT 1 AS IsMasterAttribute
,LC.ID
,MC.ID AS MasterCarId
,MCA.AttributeNameId
,MCA.Value
FROM MasterCars MC
LEFT OUTER JOIN MasterCarAttributes MCA on MC.ID = MCA.MasterCarId
INNER JOIN LocalCars LC ON LC.MasterCarId = MC.ID
UNION ALL
SELECT 0 AS IsMasterAttribute
,LC.ID
,LC.MasterCarId
,LCA.AttributeNameId
,LCA.Value
FROM LocalCars LC
LEFT OUTER JOIN LocalCarAttributes LCA on LC.ID = LCA.LocalCarId
)
,
CTE_RankedAttributes
AS
(
SELECT [IsMasterAttribute]
,[ID]
,[AttributeNameId]
,[Value]
,ROW_NUMBER() OVER (PARTITION BY [ID], [AttributeNameId] ORDER BY [IsMasterAttribute]) AS [AttributeRank]
FROM CTE_CombinedAttributes
)
SELECT [ID]
,[AttributeNameId]
,MAX(
CASE [IsMasterAttribute]
WHEN 0 THEN [Value]
END
) AS LocalValue
,MAX(
CASE [IsMasterAttribute]
WHEN 1 THEN [Value]
END
) AS MasterValue
FROM CTE_RankedAttributes
GROUP BY [ID], [AttributeNameId]
ORDER BY [ID]
SQL Fiddle Demo
SELECT LC."ID" as LocalCarID,
COALESCE(LCA."AttributeNameId", MCA."AttributeNameId") as "AttributeNameId",
COALESCE(LCA."Value", MCA."Value") as "Value"
FROM LocalCars LC
LEFT JOIN MasterCars MC
ON LC."MasterCarId" = MC."ID"
LEFT JOIN MasterCarAttributes MCA
ON MC."ID" = MCA."MasterCarId"
LEFT JOIN LocalCarAttributes LCA
ON ( MCA."AttributeNameId" = LCA."AttributeNameId"
OR MCA."AttributeNameId" IS NULL)
-- This is the important part
-- Try to join with a MasterAtribute otherwise use the Car Atribute.
AND LC."ID" = LCA."ID"
OUTPUT
| LocalCarID | AttributeNameId | Value |
|------------|-----------------|--------|
| 1 | 1 | Blue |
| 1 | 2 | Gas |
| 2 | 1 | Green |
| 2 | 2 | Diesel |