How to update column coming from TOP 1 of another table - sql

I have 2 tables:
City table - columns CityID, Name, Period
Assets table - columns AssetID, Name
I have to update the Period column of the City table with AssetID of the Assets table matching with the top 1 where City.Name=Assets.Name. The Assets table have identical names for different assets.
Example Assets table:
AssetID Name
1 Asset1
2 Asset1
3 Asset2
4 Asset2
How can I do this? I tried with different queries but I am not able to get it.

UPDATE City
SET Period = a.AssetID
FROM (SELECT TOP 1 AssetID, Name FROM Assets ORDER BY AssetID ASC) AS a
WHERE City.Name = a.Name;

This should work:
update City
set Period = (
select top 1 a.AssetID
from Assets a
where City.Name = a.Name
order by a.AssetId asc)
Sample code to test:
create table #City (CityId varchar(20), [Name] varchar(20), Period varchar(20))
create table #Assets (AssetId varchar(20), [Name] varchar(20))
insert into #City values (1, 'Asset1', null)
insert into #City values (2, 'Asset2', null)
insert into #City values (3, 'Asset3', null)
insert into #Assets values (1, 'Asset1')
insert into #Assets values (2, 'Asset1')
insert into #Assets values (3, 'Asset1')
insert into #Assets values (4, 'Asset2')
insert into #Assets values (5, 'Asset2')
insert into #Assets values (6, 'Asset3')
insert into #Assets values (7, 'Asset3')
select * from #City
select * from #Assets
update #City
set Period = (
select top 1 a.AssetID
from #Assets a
where #City.Name = a.Name
order by a.AssetId asc)
select * from #City
drop table #City
drop table #Assets

Related

I need to migrate data from one old table to a new table by storing appropriate CityId instead CityName

I'm migrating data from one table to another table in SQL Server, In this process what I need to do is "I have 10 columns in old table one column is 'CityName' which is varchar and in the new table, I have a column 'CityId' which is an integer. And I have other table which has data about city id and names. I need store the appropriate cityId in new table instead of CityName. Please help me. Thanks in advance.
You'll need to join the source table to the CityName field in the city information table:
INSERT INTO dbo.Destination (CityID, OtherStuff)
SELECT t1.CityID, t2.OtherStuff
FROM CityInformationTable t1
INNER JOIN SourceTable t2
ON t1.CityName = t2.CityName
Below should give you an idea, you need to inner join to your look up table to achieve this.
declare #t_cities table (Id int, City nvarchar(20))
insert into #t_cities
(Id, City)
values
(1, 'London'),
(2, 'Dublin'),
(3, 'Paris'),
(4, 'Berlin')
declare #t table (City nvarchar(20), SomeColumn nvarchar(10))
insert into #t
values
('London', 'AaaLon'),
('Paris', 'BeePar'),
('Berlin', 'CeeBer'),
('London', 'DeeLon'),
('Dublin', 'EeeDub')
declare #finalTable table (Id int, SomeColumn nvarchar(10))
insert into #finalTable
select c.Id, t.SomeColumn
from #t t
join #t_cities c on c.City = t.City
select * from #finalTable
Output:
Id SomeColumn
1 AaaLon
3 BeePar
4 CeeBer
1 DeeLon
2 EeeDub

Converting row values separated by comma with inner joins tables query

I would like to convert row values separated by comma with inner joins tables query with other columns are also there.
My query is displaying like below records:
Name ID Services Type
xyz 1 s1 A
xyz 1 s2 A
xyz 1 s3 A
abc 2 s2 B
abc 2 s3 B
I'd like output like below:
Name, ID, Services, Type
xyz 1 s1,s2,s3 A
abc 2 s2,s3 B
Please use below code:
create table #name (name varchar(10), id int ,type varchar(10))
insert into #name values ('XYZ',1,'A')
insert into #name values ('abc',2,'B')
create table #services (id int ,[Services] varchar(10))
insert into #services (1,'s1')
insert into #services (1,'s1')
insert into #services (1,'s2')
insert into #services (1,'s3')
insert into #services (2,'s2')
insert into #services (2,'s3')
select Name, t.ID
, (select s1.[Services] +',' from #Services s1 where s1.id = s.id for xml path('')) AS services
,[TyPe]
from #name t
inner join #services s on s.id = t.id
create table #name ( name varchar(10), id int ,type varchar(10))
insert into #name values ('XYZ',1,'A') insert into #name values ('abc',2,'B')
create table #services ( id int ,[Services] varchar(10))
insert into #services values (1,'s1' )
insert into #services values (1,'s2' )
insert into #services values (1,'s3' )
insert into #services values (2,'s2' )
insert into #services values (2,'s3' )
select * from #name
select * from #services
select Name, t.ID ,
(select s1.[Services] +',' from #Services s1 where s1.id=t.id for xml
path('') ) AS sevices ,[TYPe] from #name t

SQL Server Getting where an data object was based in a Period of Time given Track Info

I have a doubt on how to conclude this in SQL Server 2008 R2.
I have a table that has some inputs and this inputs have a Parent tag and a timestamp.
Sometimes these objects have their parent Tag changed in a timestamp. This parent tag can change from time to time.
Let´s suppose that I have the table below. My current table has millions of data with different ObjectIDs. Seeing the Table, it is easy to see that the ParentID was changed in the timestamps 3 to 4, 6 to 7 and 8 to 9.
ProductID ParentID DateID value
-------- --------- ------- -------------
100 1 1 325,2
100 1 2 326,2
100 1 3 329,6
100 2 4 335,2
100 2 5 336,5
100 2 6 338,3
100 3 7 339,2
100 3 8 342,1
100 1 9 343,7
100 1 10 355,6
100 1 11 385,8
The Answer I want is to which ParentID the ObjectID belonged and the Start and End timestamp and what was the delta value between the timestamps (Timestamp = TS)
ProductID ParentID DateID_Start DateID_End DeltaValue
-------- --------- ---------- -------- ----------
100 1 1 4 10,0
100 2 4 7 4,0
100 3 7 9 4,5
100 1 9 11 42,1
What I have Accomplish so far is getting when there is a change, but it only gives me the changes, but not the table above.
ObjectID ParentID_Old ParentID_New DateID_Changed
-------- ------------ ------------ ------------
100 1 2 3 to 4
100 2 3 6 to 7
100 3 1 8 to 9
Here are the code to generate the table and the test inserts. Below as well is the Select to get the changes.
--Initial Insert Code
IF OBJECT_ID('tempdb..#Trackings') Is Not Null
Drop table #Trackings
Create Table #Trackings
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
And the SQL to get the changes I am using:
Select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
From #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
And ISNULL(A.StoreID,-1) <> ISNULL(B.StoreID,-1)
Any lights ideas Guys?
Thanks in advance!
EDITED: Just a little bit more "Business" info: ParentID would be like a store a product is and DateID the Time that it arrived there. So let's suppose that productID 100 is in the ParentID 1, it means that in the DateID 1 the productID 100 entered in Store 1. So for some reason it moved to Store 2 in DatedID 4. So my first row in the answer table means that ProductID 100 was in the StoreID 1 from DateID 1 up to DateID 4. The productID 100 then stayed in StoredID 2 from DateID 4 up to 7, then changed to StoredID 3 and finally it came back to StoreID 1 from DateID 9 up to our last DateID in the DateID range "selected". So that's why the answer table has 2 lines with ParentID 1.
OK, try this, using your updated sample data:
Declare #Trackings table
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
;
with t
as (select *, ROW_NUMBER() over (order by dateid) as rn
from #Trackings ),
cte1
(Productid,
Storeid,
DateID,
value,
rn,
set1)
as
(select ProductID, StoreID, DateID, value, rn , 1
from t
where rn = 1
union all
select t.productID, t.storeID, t.dateID, t.value, t.rn,
case when
cte1.Storeid = t.storeID then cte1.set1 else cte1.set1+1 end
from t join cte1 on t.rn = cte1.rn+1)
,
t2 as (select Productid, Storeid, set1, MIN(CAST(DateID as int)) as tmi, max(dateid) as tma
from cte1
group by Productid, Storeid, set1)
select t3.Productid, t3.Storeid, t3.set1, t3.date_min, t3.date_max, u.value - t.value
from
(select a.Productid, a.Storeid, a.set1, a.tmi as date_min, coalesce(b.tmi, a.tma) as date_max
from t2 a left join t2 b
on a.set1 + 1 = b.set1) t3 join #Trackings t
on t3.date_min = t.DateID
join #Trackings u
on t3.date_max = u.DateID
order by set1
The "Value" column confused me, as you are using commas (,) instead of periods (.) to separate the integer from the decimal part of your float.
I finally found a solution that based on my Initial Table has a better performance than using CTE and as sugested by https://stackoverflow.com/users/2522030/mike-abramczyk (the real table has 5k entries and using the his suggestion was taking a long time).
After querying the search table, I added two lines to the table for each ProductID. These lines would receive a dummy StoreID (i.e. -9999): one with a Min(DateID) - 1 and another One with a Max(DateID) + 1.
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
Then, I used the Query I posted to get the changes. So I could get the Change from Dummy(-9999) to the real StoreID (1) and the last change from a real StoreID(3) to Dummy(-9999).
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
This was the Crucial Step! Now I have I can create the result table with the DateIDs of the changes I was looking for. The Aux_Row_Number Column helped get a sequence in the changes to each product using (think that the last query has create the table #ProductStoreChanges - I will be posting the entire Soltion below):
select A.ID_FinalStore,A.DateID_Final,B.DateID_Final,A.ProductID,B.value_2,A.value_2,B.value_2 - A.value_2 DeltaValue
from #ProductStoreChanges A
Join #ProductStoreChanges B
On (A.Aux_Row_Number + 1 = B.Aux_Row_Number)
And A.ProductID = B.ProductID
Order by A.DateID_Final
Here is the Final Solution:
IF OBJECT_ID('tempdb..#Trackings') Is Not Null
Drop table #Trackings
IF OBJECT_ID('tempdb..#ProductStoreChanges') Is Not Null
Drop table #ProductStoreChanges
Create Table #Trackings
(
ProductID bigint
, value float
, StoreID int
, DateID int
, Aux_Row_Number int
, flg_changed bit Default(0)
)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,1,325.2,1)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,2,326.2,2)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,3,329.6,3)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,4,335.2,4)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,5,336.5,5)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,6,338.3,6)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,7,339.2,7)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,8,342.1,8)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,9,343.7,9)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,10,355.0,10)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,1,12,385.0,12)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,13,485.0,13)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,14,985.0,14)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,15,1585.0,15)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,3,16,3585.0,16)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,17,5585.0,17)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,18,6585.0,18)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,19,8585.0,19)
Insert into #Trackings(ProductID,StoreID,DateID,value,Aux_Row_Number) Values (100,2,20,9585.0,20)
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Min(Aux_Row_Number)-1 Aux_Row_Number,-9999 as StoreID, min(DateID)-1 as DateID,ProductID,Min(value)
From #Trackings
group by ProductID
Order by ProductID
Insert into #Trackings (Aux_Row_Number,StoreID,DateID,ProductID,value)
Select Max(Aux_Row_Number)+1 Aux_Row_Number,-9999 as StoreID, max(DateID)+1 as DateID,ProductID,Max(value)
From #Trackings
group by ProductID
Order by ProductID
CREATE TABLE #ProductStoreChanges
(
ID_InitialStore INT
, ID_FinalStore INT
, ProductID INT
, value_1 BIGINT
, value_2 BIGINT
, DateID_Initial BIGINT
, DateID_Final BIGINT
, Aux_Row_Number INT
)
INSERT INTO #ProductStoreChanges
(
ID_InitialStore
, ID_FinalStore
, ProductID
, value_1
, value_2
, DateID_Initial
, DateID_Final
, Aux_Row_Number
)
select ISNULL(A.StoreID,-1)
, ISNULL(B.StoreID,-1)
, A.ProductID
, A.value
, B.value
, A.DateID
, B.DateID
, ROW_NUMBER() OVER (Partition by B.ProductID Order by A.DateID)
from #Trackings A
Join #Trackings B
On A.ProductID = B.ProductID
And A.Aux_Row_Number + 1 = B.Aux_Row_Number
AND ISNULL(A.StoreID,0) <> ISNULL(B.StoreID ,0)
select A.ID_FinalStore,A.DateID_Final,B.DateID_Final,A.ProductID,B.value_2,A.value_2,B.value_2 - A.value_2 DeltaValue
from #ProductStoreChanges A
Join #ProductStoreChanges B
On (A.Aux_Row_Number + 1 = B.Aux_Row_Number)
And A.ProductID = B.ProductID
Order by A.DateID_Final

Copy an existing row "n" number of times in SQL Server

If I have a table with a row, can I insert into the same table "x" number of times making a copy of everything in the row except a few columns. Something along the lines:
INSERT INTO #tbl
(City, Region, Country)
SELECT
"Different city", Same region, Same country 5 times.
I am trying to do this without using a loop.
If you have the cities in a separate table, you should be able to do the following:
DECLARE #tbl TABLE (City varchar(20), Region varchar(20), Country varchar(20))
INSERT INTO #tbl
VALUES('Malmo', 'Skane', 'Sweden')
--Borrowing some code from #aF.
DECLARE #cities TABLE (city varchar(20))
INSERT INTO #cities values ('London')
INSERT INTO #cities values ('Lisbon')
INSERT INTO #cities values ('Paris')
INSERT INTO #cities values ('New York')
INSERT INTO #cities values ('Barcelona')
INSERT INTO #tbl
SELECT cities.city, tbl.Region, tbl.Country
FROM (select top 1 Region, Country from #tbl) tbl, #cities cities
If you have the cities in another table you can do it like this:
create table #cities (
city varchar(30)
)
INSERT INTO #cities values ('London')
INSERT INTO #cities values ('Lisbon')
INSERT INTO #cities values ('Paris')
INSERT INTO #cities values ('New York')
INSERT INTO #cities values ('Barcelona')
INSERT INTO #tbl
(City, Region, Country)
SELECT c.city, 'REGION', 'COUNTRY' from #cities c
drop table #cities

Querying a Many to Many Structure for a subset of joined rows

I have a simple many to many db structure:
Table 1: ITEM
Columns:
ITEM_ID, ITEM_NAME
Table 2: Attribute
Columns:
ATTRIBUTE_ID, ATTRIBUTE_NAME
Table 3: ITEM_ATTRIBUTE
ITEM_ID, ATTRIBUTE_ID
What I want is to "get all items that have the following x attributes". X can be any number of attributes.
The best I've come up with is the following, but I believe there has to be a better way using joins and/or "select where in" clauses...but I can't think of it.
SELECT * FROM Item
WHERE Item.ITEM_ID IN
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =1)
and Item.ITEM_ID in
(SELECT ITEM_ATTRIBUTE.item_ID FROM ITEM_ATTRIBUTE WHERE ITEM_ATTRIBUTE.attribute_ID =3);
I'd rather not have to add an additional "ITEM_ID in (...) for each attribute in the list.. esp if the list of attributes is 20+ long
I would suggest populating a temporary table with the attributes that you would like to require. Once you have this table, the query becomes much cleaner and maintainable.
DECLARE #Item TABLE (
Item_Id INT,
Item_Name VARCHAR(50)
)
DECLARE #Attribute TABLE (
Attribute_Id INT,
Attribute_Name VARCHAR(50)
)
DECLARE #Item_Attribute TABLE (
Item_Id INT,
Attribute_Id INT
)
INSERT INTO #Item VALUES (1, 'Widget')
INSERT INTO #Item VALUES (2, 'Woozle')
INSERT INTO #Attribute VALUES (1, 'foo')
INSERT INTO #Attribute VALUES (2, 'bar')
INSERT INTO #Attribute VALUES (3, 'baz')
INSERT INTO #Attribute VALUES (4, 'qux')
INSERT INTO #Item_Attribute VALUES (1, 1)
INSERT INTO #Item_Attribute VALUES (1, 2)
INSERT INTO #Item_Attribute VALUES (1, 3)
INSERT INTO #Item_Attribute VALUES (2, 1)
INSERT INTO #Item_Attribute VALUES (2, 4)
DECLARE #Required_Attribute TABLE (
Attribute_Id INT
)
INSERT INTO #Required_Attribute VALUES (1)
INSERT INTO #Required_Attribute VALUES (2)
SELECT *
FROM #Item i
WHERE NOT EXISTS (
SELECT 1
FROM
#Required_Attribute ra
LEFT JOIN #Item_Attribute missingAttribute
ON ra.Attribute_Id = missingAttribute.Attribute_Id
AND missingAttribute.Item_Id = i.Item_Id
WHERE
missingAttribute.Attribute_Id IS NULL
)