Get result on two table join - sql

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

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

Merge or join two tables SQL Server

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

Split a row on 2 or more rows depending on a column

I have a question
If I have one row that looks like this
|ordernumber|qty|articlenumber|
| 123125213| 3 |fffff111 |
How can I split this into three rows like this:
|ordernumber|qty|articlenumber|
| 123125213| 1 |fffff111 |
| 123125213| 1 |fffff111 |
| 123125213| 1 |fffff111 |
/J
You can use recursive CTE:
WITH RCTE AS
(
SELECT
ordernumber, qty, articlenumber, qty AS L
FROM Table1
UNION ALL
SELECT
ordernumber, 1, articlenumber, L - 1 AS L
FROM RCTE
WHERE L>0
)
SELECT ordernumber,qty, articlenumber
FROM RCTE WHERE qty = 1
SQLFiddleDEMO
EDIT:
Based on Marek Grzenkowicz's answer and MatBailie's comment, whole new idea:
WITH CTE_Nums AS
(
SELECT MAX(qty) n FROM dbo.Table1
UNION ALL
SELECT n-1 FROM CTE_Nums
WHERE n>1
)
SELECT ordernumber ,
1 AS qty,
articlenumber
FROM dbo.Table1 t1
INNER JOIN CTE_Nums n ON t1.qty >= n.n
Generating number from 1 to max(qty) and join table on it.
SQLFiddle DEMO
Here's a quick hack using an additional table populated with a number of rows suitable for the qty values you are expecting:
-- helper table
CREATE TABLE qty_splitter (qty int)
INSERT INTO qty_splitter VALUES (1)
INSERT INTO qty_splitter VALUES (2)
INSERT INTO qty_splitter VALUES (3)
INSERT INTO qty_splitter VALUES (4)
INSERT INTO qty_splitter VALUES (5)
....
-- query to produce split rows
SELECT t1.ordernumber, 1, t1.articlenumber
FROM table1 t1
INNER JOIN qty_splitter qs on t.qty >= qs.qty
You can do it using CTE
declare #t table (ordername varchar(50), qty int)
insert into #t values ('ord1',5),('ord2',3)
;with cte as
(
select ordername, qty, qty-1 n
from #t
union all
select ordername, qty, n-1
from cte
where n>0
)
select ordername,1
from cte
order by ordername
Also you can use option with master..spt_values system table.
SELECT t.ordernumber, o.qty, t.articlenumber
FROM dbo.SplitTable t CROSS APPLY (
SELECT 1 AS qty
FROM master..spt_values v
WHERE v.TYPE = 'P' AND v.number < t.qty
) o
However, for this purpose is preferable to use its own sequence table
See demo on SQLFiddle

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.

SQL select Distinct with where clause

I have i table like this.
PersonID, KvalifikationId
1 1
1 2
1 3
2 1
2 3
I want to write SQL querye returning all persons, that have not kvalifikation 2.
i Wrote
SELECT DISTINCT PersonID where NOT KvalifikationID = 2
But this return both person 1 and person 2.
How do i make select that only return personId's that not have kval2 ?
Try this,
SELECT DISTINCT PersonID
FROM tableName
WHERE PersonID NOT IN
(
SELECT PersonID
FROM tableName
WHERE KvalifikationId = 2
)
SQLFiddle Demo
Declare #t table(PersonID int,KvalifikationId int)
Insert Into #t Select 1 ,1
Insert Into #t Select 1, 2
Insert Into #t Select 1,3
Insert Into #t Select 2 ,1
Insert Into #t Select 2,3
Select PersonId From #t
Except
Select PersonID From #t where KvalifikationId = 2
Result
PersonId
2
By using your Person table rather than your N:N table in the outer query you can skip the distinct and the anti semi join to the sub query will have better performance since it is on a clustered index. (assuming PersonID is pk in the Person table)
SELECT PersonID
FROM tblPerson
WHERE NOT EXISTS
(
SELECT NULL
FROM tblPersonKvalifikation
WHERE KvalifikationId = 2 AND
tblPerson.PersonID = tblPersonKvalifikation.PersonID
)
SELECT DISTINCT person_id
FROM tableName t1
WHERE not exists
(
select 1
from tableName
where person_id = t1.person_id and KvalifikationId = 2
)
try this.
SELECT DISTINCT PersonID from tableName
WHERE KvalifikationId NOT IN ('2');