Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I'm a total SQL newbie. I have two tables. Each table has a primary key column (ID) and several other columns with integer values.
For example:
Now I want to merge both tables into one table - in a way that all apples, bananas and tomatoes are added per ID.
For example:
How does the SQL statement looks like for this task?
INSERT INTO NEWTABLE (ID, Apples, Bananas, Tomatoes)
SELECT ISNULL(a.Id, b.Id) as [Id],
ISNULL(a.Apples,0) + ISNULL(b.Apples,0) AS [Apples],
ISNULL(a.Bananas,0) + ISNULL(b.Bananas,0) AS [Bananas],
ISNULL(a.Tomatoes,0) + ISNULL(b.Tomatoes,0) AS [Tomatoes]
FROM Table1 AS a
FULL OUTER JOIN Table2 AS b on b.Id = a.Id
I think this will solve your issue. Just a INSERT and a SELECT combined.
Have no time to test it, but I would use a UNION and a GROUP BY:
SELECT ID,
SUM(APPLES) AS APPLES,
SUM(BANANAS) AS BANANAS,
SUM(TOMATOES) AS TOMATOES
FROM
(SELECT * FROM TABLEA
UNION ALL
SELECT * FROM TABLEB ) AS ALL
GROUP BY ID
If it works, this first creates a table with all entries and then combines the ones with the same ID. Anyone feel free to edit if there are problems.
Didn't see you want a third table, you don't need the column aliases then:
INSERT INTO
TABLEC
VALUES
(ID, APPLES, BANANAS, TOMATOES)
SELECT ID,
SUM(APPLES),
SUM(BANANAS),
SUM(TOMATOES)
FROM
(SELECT * FROM TABLEA
UNION ALL
SELECT * FROM TABLEB) AS ALL
GROUP BY ID
If that doesn't work, you can do one of the JOIN answers, but would change it to TABLEA JOIN TABLEB USING(ID).
The best approach is to use a full outer join, otherwise you may miss some id's. In your example, with left join you will miss id=4, while with right join you will miss id= 2.
Also be carefull with the ID, you want to take it from Table1 if exists, id from Table2 otherwise
So the best solution i think is something like this:
INSERT INTO Table3 (ID, Apples, Bananas, Tomatoes)
SELECT coalesce (a.Id, b.Id)
coalesce(a.Apples, 0) + coalesce(b.Apples, 0) AS Apples,
coalesce(a.Bananas, 0) + coalesce(b.Bananas, 0) AS Bananas,
coalesce(a.Tomatoes, 0) + coalesce(b.Tomatoes, 0) AS Tomatoes,
FROM Table1 a
FULL OUTER JOIN Table2 b on b.Id = a.Id
Try this
insert into tableC (ID, Apples, Bananas, Tomatoes)
select tableA.ID,
ISNULL(tableA.Apples,0) + ISNULL(tableB.Apples,0) as Apples,
ISNULL(tableA.Bananas,0) + ISNULL(tableB.Bananas,0) as Bananas,
ISNULL(tableA.Tomatoes,0) + ISNULL(tableB.Tomatoes,0) as Tomatoes
from tableA left join tableB
on tableA.ID = tableB.ID;
Related
I've got a join table that has 'account_id' and 'group id' in it, both represented by a GUID. I'm trying to merge the columns so we get a single 'account_id' with all of it's 'group_id's merged to a single Colum/row, but display the actual name of the account and group.
Tables
Account
account_id Name
1 Henry
2 Smith
Group
Group_id Group_nameName
3 User
4 Admin
Account_Group_Join_Table
account_id group_id
1 3
1 4
2 3
Desired Result:
Name Groups
Henry Dev,User
Smith User, Admin
Code so far to return 'account_id' with 'group_id' grouped to single row/column
select account_id,
stuff((SELECT distinct ', ' + group_id
FROM account_group_join t2
where t2.account_id = t1.account_id
FOR XML PATH('')),1,1,'') [Groups]
from account_group_join t1
group by account_id
You just need to join to your group table in the subquery so you can get the name rather than the ID. You also may as well just select from Account in the outer query and avoid an additional join to account to get the name:
SELECT a.account_id,
a.Name,
STUFF((SELECT DISTINCT ', ' + g.group_nameName
FROM account_group_join AS ag
INNER JOIN [Group] AS g
ON g.group_id = ag.group_id
WHERE ag.account_id = a.account_id
FOR XML PATH('')),1,1,'') AS [Groups]
from Account AS a;
n.b. I've changed your aliases from t1 and t2 to something that kind of represents the table I am aliasing, you'll find this much easier especially when working with larger queries. More reading here: Bad Habits to Kick : Using table aliases like (a, b, c) or (t1, t2, t3)
So I have some complicated production tables. What it comes down to, however, is that I'd like to be able to join to multiple tables depending on the where the value is that I'm seeking. Specifically, say I have an employee ID, "JHDOE", and I want to join it to the table where I can get that employee's name. The main table for employees is "Table A":
Notice that the field ID_2 does NOT have the value "JHDOE". Instead, it has "DOEJH". Well, there is another table that actually has the value I'm seeking, "Table B":
In this table, we do see "JHDOE" so at first I tried something like this:
from TableStart as start
left join TableB as b on
case
when start.EMP_ID like '[0-9]%'
then b.ID
else b.ID_2
end = start.EMP_ID
But this created other problems. So what I'd like to do is do something like join to EITHER table, or at least something to the same effect. One method I tried was this:
from TableStart as start
left join (select a.Name, a.ID, a.ID_2
from TableA as a
union
select b.Name, b.ID, b.ID_2
from TableB as b) names on
case
when start.EMP_ID like '[0-9]%'
then names.ID
else names.ID_2
end = start.EMP_ID
The result set for the union looks like this:
On my production data, this same scenario resulted in a blank. I suppose it doesn't know which row to join to? So I think I need to do something like pivot the rows into columns and then do an OR... but I'm not sure. I would be greatly appreciative of any guidance or instruction.
Instead of using a CASE in the join I think an IN operator would work. That will function as an OR (EMP_ID = ID or EMP_ID = ID_2). And if you LEFT JOIN from TableStart to both TableA and TableB and use the COALESCE function with each column from TableA and TableB you will get the first non-null value.
This assumes that if both TableA and TableB have a match for TableStart you are fine with taking the first non-null value which could result in a mixture of values from TableA and TableB if TableA has some null values.
select
start.*
, coalesce (a.Name, b.Name) as [Name]
, coalesce (a.ID, b.ID) as [ID]
, coalesce (a.ID_2, b.ID_2) as [ID_2]
from TableStart as start
left join TableA as a on start.EMP_ID in (a.ID, a.ID_2)
left join TableB as b on start.EMP_ID in (b.ID, b.ID_2)
Here is the full demo.
I'm working in SQL Server 2016. Confusing problem with SQL issue. I have a TEMP table that contains unique rows. I have to insert 5 PRODUCTID values for each row each row based on another column value, AgentNo, in this temp table. The PRODUCTID value, there are 5 of them, comes from another table but there is no relationship between the tables. So my question is how do I insert a row for each ProductID into this temp table for each unique row that is currently in the temp table.
Here is a pic of the TEMP table that requires 5 rows for each:
Here is a pic of what I'm needing to come away with:
Here is my SQL code for both TEMP tables:
IF OBJECT_ID('tempdb..#tempTarget') IS NOT NULL DROP TABLE #tempTarget
SELECT 0 as ProductID, 1 as [Status], a.AgentNo, u.UserID, u.[Password], 'N' as AdminID, tel.LocationSysID --, tel.OwnerID, tel.LocationName, a.OwnerSysID, a.AgentName
INTO #tempTarget
FROM dbo.TEST_EvalLocations tel
INNER JOIN dbo.AGT_Agent a
ON tel.LocationName = a.AgentName
INNER JOIN dbo.IW_User u
ON a.AgentNo = u.UserID
WHERE tel.OwnerID = 13313
AND tel.LocationSysID <> 15434;
SELECT * FROM #tempTarget WHERE LocationSysID NOT IN (15425, 15434);
GO
-- Create source table
IF OBJECT_ID('tempdb..#tempSource') IS NOT NULL DROP TABLE #tempSource
SELECT DISTINCT lpr.ProductID
INTO #tempSource
FROM dbo.Eval_LocationProductRelationship lpr
WHERE lpr.ProductID IN (16, 15, 13, 14, 12) --BETWEEN 15435 AND 15595
Sorry I could not get this into a DDL file as these are TEMP tabless. Any help/direction would be appreciated. Thanks.
CROSS JOIN will be the best solution for your case.
If you only want 5 rows for each data in First table means, simply use the below cross join query.
SELECT B.ProductID,
A.[Status],
A.AgentNo,
A.UserID,
A.[Password] AS Value,
A.AdminID,
A.LocationSysID
FROM #tempTarget A
CROSS JOIN tempSource B
If you want additional row with 0, then you have to insert a 0 into your second temp table and use the same query.
INSERT INTO #tempSource SELECT 0
If i understand correctly following is the scenario,
One Temp table has all the content.
select * from #withoutProducts
product table
select * from #products
Then following is the query your are looking for
select a.ProductID,[Status],AgentNo,UserID,[value]
from #products a cross join #withoutProducts b
order by AgentNO,a.productID
Based on the sql result above i want to divide the result like the image below
I tried using case it return duplicate data.
Anyone have done this or have any idea how to do this?
Can you try this one?
SELECT t1.*,t2.* from yourtable WHERE t1.hatch_num_1 != t2.hatch_num_1
JOIN yourtable t2 ON t1.delay_code_1=t2.delay_code_1
Afterwards you can mention exactly what columns you wan't from both t1 and t2 and mention with 'as' how do you wan't them to be named in your select statement, so instead of having 2 hatch_num_1 you wil have one with _1 and one with _3
;With
a As (SELECT * FROM yourtable X Where X.hatch= 'H1' ),
b AS (SELECT * FROM yourtable Y Where Y.hatch= 'H3')
SELECT A.* ,B.* FROM A , B WHERE A.[delay] = B.[delay]
If you have limited hatches and same time that are repeating then you can do it like this or show me some more records or details then i'll came to know...
These days, I've learned about DBMS. And now, I have trouble with using sqlplus.
The problem is I want these two table to be united without 'Union query'.
Table1 = '1','2','3','4','5'
Table2 = '1','2','6','7'
The Union result of these two tables is '1','2','3','4','5','6','7'
But I want to achieve the same result without using Union by only using create, select, or insert.
Please, I really want to know alternative resolution of Union.
technically, you can try
insert
into table1 ( col )
select col
from table2 t2
where not exists (
select 1
from table1 tt1
where tt1.col = t2.col
)
;
but i doubt that this will be much more efficient than a union in the first place.
similar comment holds for a construct like insert into table1 select col from table2 minus select col from table 1.