Merge or join two tables SQL Server - sql

I have a table with two columns Item, Qty and another table with Product, Quantity.
Table A
Item
Qty
a
10
a
15
a
5
b
10
Table b
Product
Quantity
a
10
a
20
b
5
b
5
The output that I'm looking for is this:
item
Qty
Product
Quantity
a
10
a
10
a
15
a
20
a
5
NULL
NULL
b
10
b
5
NULL
NULL
b
5

You will need to have some sort of order to guarantee consistent results. To simulate that, I added IDENTITY columns
Match Product to Item in Order Based on ROW_NUMBER()
DROP TABLE IF EXISTS #Table1
DROP TABLE IF EXISTS #Table2
CREATE TABLE #Table1 (ID INT IDENTITY(1,1),Item CHAR(1),Qty INT)
CREATE TABLE #Table2 (ID INT IDENTITY(1,1),Product CHAR(1),Qty INT)
INSERT INTO #Table1
VALUES ('a',10)
,('a',15)
,('a',5)
,('b',10)
INSERT INTO #Table2
VALUES ('a',10)
,('a',20)
,('b',5)
,('b',5)
;WITH cte_Table1 AS (
SELECT *,RankNum = ROW_NUMBER() OVER (PARTITION BY Item ORDER BY ID)
FROM #Table1
),
cte_Table2 AS (
SELECT *,RankNum = ROW_NUMBER() OVER (PARTITION BY Product ORDER BY ID)
FROM #Table2
)
SELECT *
FROM cte_Table1 AS A
FULL JOIN cte_Table2 AS B
ON A.Item = B.Product
AND A.RankNum = B.RankNum

Related

MariaDB concatenate 2 tables with same number of rows

Say I have 2 tables with exactly SAME number of rows, but no other obvious relations:
tableA
ID
items
1
banana
2
orange
tableB
itemID
volume
5550
50
5551
70
Can I join these 2 tables horizontally, to form 1 table like the following?
ID
items
itemID
volume
1
banana
5550
50
2
orange
5551
70
If you have 2 tables with exactly SAME number of rows, but no other obvious relations and on both tables , respectively ID and itemID defines the uniqueness of the rows you can apply MySQL ROW_NUMBER Function and join on the row_number, the order by clause is important.
Try:
SELECT tbla.ID, tbla.Items, tblb.ItemId, tblb.volume
FROM (
SELECT ID, Items, row_number() over( order by ID desc )row_numA
FROM TableA
)tbla
INNER join
( SELECT ItemId,volume,row_number() over(order by ItemId desc)row_numB
FROM TableB
) tblb ON tbla.row_numA=tblb.row_numB
order by tbla.ID asc;
https://dbfiddle.uk/?rdbms=mariadb_10.6&fiddle=15d13d29a84a55c4d029115c87eebe8f
try this
create table TableA(ID INT, Items varchar(20));
create table TableB(ItemId INT, volume varchar(20));
insert into TableA(Id, items) values (1, 'banana'), (2, 'orange');
insert into TableB(ItemId, volume) values (5550, '50'), (5551, '70');
SELECT A.ID, A.Items, B.ItemId, B.volume
FROM
(
SELECT ID, Items, rownum()R
FROM TableA
)A INNER join
(
SELECT ItemId,volume,rownum()R
FROM TableB
)B ON A.R=B.R

Finding Occurrence of the duplicate values

I have table with 3 columns (id, Name, Occurrence), I want to update the Occurrence column ,based on the id column, attached snap for the reference.
for example if my id column has "606" value 3 times then my occurrent column should have 3 against all the "606" value.
Below is the method which I tried.
I tried to find the duplicate values using group by and Having clause and saved it in a temp table and from there I tried to join the table value from the temp table.
you can use window functions in an updatable CTE for this.
You haven't supplied any actual sample data so this is untested, however the following should work:
with x as (
select Id, Occurence, count(*) over(partition by Id) qty
from Table
)
update x
set Occurence = Qty;
You can go for GROUP BY based approach also.
declare #TABLE TABLE(ID INT, NAME CHAR(3), occurance int null)
insert into #TABLE VALUES
(1,'AAA',NULL),(1,'AAA',NULL),(2,'CCC',NULL),(3,'DDD',NULL), (3,'DDD',NULL),(4,'EEE',NULL),(5,'FFF',NULL);
;WITH CTE_Table as
(
SELECT ID, COUNT(*) AS Occurance
FROM #table
group by id
)
UPDATE t
SET occurance = c.occurance
FROM #table t
INNER JOIN CTE_Table as c
on C.ID = T.ID
SELECT * FROM #TABLE
ID
NAME
occurance
1
AAA
2
1
AAA
2
2
CCC
1
3
DDD
2
3
DDD
2
4
EEE
1
5
FFF
1
You can use a CTE and calculate row number and update your table base on CTE
;WITH q
AS
(
SELECT Id,COUNT(1) 'RowNum'
FROM YourTable
GROUP BY Id
)
UPDATE YourTable
SET Occurrence=q.RowNum
FROM YourTable t
INNER JOIN q
ON t.Id=q.Id

How to Select one Value for each row after Joining of 2 Tables

I have 2 tables, the first one has 10 distinct values:
,
each GlobalPnID has many values on the second table, I want to join 2 tables and select one random value of PortionKey of the second table that match the condition and move to the next GlobalPnID
SELECT TOP 10 gpnp.PortionKey, tt.GlobalPnID
from #TempTable tt
LEFT JOIN [dbo].[GlobalPartNumberPortions] gpnp ON gpnp.GlobalPnId = tt.GlobalPnID
-- tt is the first table
-- gpnp is the second
SELECT TT.GlobalPnID,X.PortionKey
FROM #TempTable AS TT
CROSS APPLY
(
SELECT TOP 1 R.PortionKey
FROM [dbo].[GlobalPartNumberPortions] AS R
WHERE R.GlobalPnId=TT.GlobalPnID
ORDER BY R.PortionID
)X
You could use Row_Number with a CTE and set the criteria you want, for example:
DECLARE #TempTable TABLE
(
globalpnid INT
)
DECLARE #GlobalPartNumberPortions TABLE
(
portionid INT,
portionkey NVARCHAR(10),
globalpnid INT
)
INSERT INTO #TempTable
(globalpnid)
VALUES (1),(2),(3),(4)
INSERT INTO #GlobalPartNumberPortions
(portionid,
portionkey,
globalpnid)
VALUES (1,'ABC',1),
(2,'XYZ',1),
(3,'AZZ',2),
(4,'QWE',3),
(5,'TYU',4);
WITH cteportion
AS (SELECT portionkey,
globalpnid,
rn = Row_number()
OVER (
partition BY globalpnid
ORDER BY RAND(CHECKSUM(NEWID()))))
FROM #GlobalPartNumberPortions)
SELECT gpnp.portionkey,
tt.globalpnid
FROM #TempTable tt
LEFT JOIN cteportion gpnp
ON tt.globalpnid = gpnp.globalpnid
AND gpnp.rn = 1
This will partition the second table by the globalpnid ordering on ORDER BY RAND(CHECKSUM(NEWID()))) and you can then use this in the join gpnp.rn = 1. In the example I've included, you'll see that GlobalPnID = 1 will alternate between ABC and XYZ.
Edit: as suggested by #Thorsten Kettner in the comment, you can order by RAND(CHECKSUM(NEWID())))

Get result on two table join

I have a criteria where i want to join table 1 with table 2 , table 1 consists of products which were given to salesman to sell and table 2 has the sales data which salesman has sold out.
Now i want to know left over products of each sales with join.
Below is my data, here is what i am trying to do, but it return only salesman 1 data.
I need help to join these tables as per my requirement
CREATE TABLE Salesman_Product
(
SalesManID int,
ProductID int
)
INSERT INTO Salesman_Product (SalesManID,ProductID) Values (1,1),(1,2),(1,3),(1,4)
INSERT INTO Salesman_Product (SalesManID,ProductID) Values (2,1),(2,2),(2,3),(2,4)
--select * from Salesman_Product
CREATE TABLE Salesman_Sales
(
SalesManID int,
ProductID int,
Status varchar(3)
)
INSERT INTO Salesman_Sales (SalesManID,ProductID,Status) Values (1,1,'Yes'),(1,3,'Yes')
INSERT INTO Salesman_Sales (SalesManID,ProductID,Status) Values (2,1,'Yes'),(2,2,'Yes'),(2,3,'Yes')
--select * from Salesman_Sales
;WITH CTE_RES AS
(
SELECT * FROM Salesman_Product
WHERE ProductID NOT IN
(
SELECT Salesman_Sales.ProductID FROM Salesman_Sales INNER JOIN
Salesman_Product ON
Salesman_Sales.SalesManID =Salesman_Product.SalesManID
AND Salesman_Sales.ProductID =Salesman_Product.ProductID
--AND Salesman_Sales.SalesManID =1
)
)
SELECT * INTO #TEMP_RES FROM CTE_RES
SELECT * FROM #TEMP_RES
--DROP TABLE #TEMP_RES
required result
SALESMANID PRODUCTID
1 2
1 4
2 4
You are over complicating what should be a simple select with not exists:
SELECT SalesManID, ProductID
FROM Salesman_Product p
WHERE NOT EXISTS (
SELECT 1
FROM Salesman_Sales s
WHERE p.SalesManID = s.SalesManID and p.ProductID = s.ProductID
)
Results:
SalesManID ProductID
1 2
1 4
2 4
see fiddle here

Update 2 rows from three based on duplicated value

How can I update all duplicated site_id rows except the last one. I.e. if I have 3 duplicated site ids (2 in this case), how can I update the top two leaving the last (third) one untouched?
temp_id site_id amount
1 2 200
2 2 200
3 2 200
4 3 200
5 3 200
6 4 200
CREATE TABLE #site (temp_id NUMERIC IDENTITY,
site_id NUMERIC PRIMARY KEY
)
INSERT INTO #site VALUES(2),(3),(4)
CREATE TABLE #temp (temp_id NUMERIC IDENTITY,
site_id NUMERIC FOREIGN KEY (site_id) REFERENCES #site(site_id),
amount NUMERIC)
INSERT INTO #temp VALUES(2,200),(2,200),(2,200),(3,200),(3,200),(4,200)
update #temp
set amount = 2
where site_id in (
select distinct table1.site_id
from #temp table1
inner join #temp table2 on table1.site_id = table2.site_id
and table1.temp_id <> table2.temp_id
)
and site_id <> (
select max(site_id)
from #temp
);
SELECT t.* FROM #temp t
JOIN #site s ON s.site_id = t.site_id
DROP TABLE #temp
DROP TABLE #site
UPDATE temp_record
SET …
WHERE site_id = 2
AND temp_id <> (SELECT MAX(temp_id)
FROM my_table
WHERE site_id = 2)
If you want to update all such lines and temp_id is a unique key in temp_record:
UPDATE temp_record
SET …
WHERE temp_id NOT IN (
SELECT MAX(temp_id)
FROM temp_record
GROUP BY site_id)
My preferred way of doing this is with row_number():
with toupdate as (
select t.*,
row_number() over (partition by site_id order by temp_id desc) as seqnum
from t
)
update t
set . . .
where seqnum = 1
I'm not filling in the details. Just giving you an alternative approach.