SQL joining 2 tables with some overlapping values - mysql

I am trying to create one table out of the following 2 tables and running into a lot of problems.
Table 1 has the following:
Month,
Salesperson_Assigned,
Product1_Revenue
Table 2 has the following (different product):
Month,
Salesperson_Assigned,
Product2_Revenue
The problem is that while all the months are the same, there are some salespeople in Table 1 not in Table 2, and vice versa. Obviously the revenue is different. I want to join the tables to look like Month, Salesperson, Product1_revenue + Product2_revenue.
Here's the query I'm using:
SELECT
Table1.month,
Table1.salesperson_assigned,
sum(Table1.revenue + Table2.revenue)
FROM
Table1
INNER JOIN Table 2 ON (Table1.month = Table2.month) AND (Table1.salesperson_assigned = Table2.salesperson_assigned)
The output isn't correct even though I confirmed the revenue values in each individual table are correct. The output seems to be making up additional values for the salespeople who appear in only 1 table for the field that should be null.
Anyone had any advice for how to join the 2 tables properly so it acts similar to a pivot table, adding the unique values to the "salesperson assigned" column and adding the revenue for both columns, but when a salesperson is in only ONE table having it respect that there is a zero value for revenue?

did you tried this way:
SELECT
Table1.month,
Table1.salesperson_assigned,
sum(Table1.revenue + Table2.revenue)
FROM
Table1 FULL OUTER JOIN Table2 on (Table1.month = Table2.month AND Table1.salesperson_assigned = Table2.salesperson_assigned)

Ideally for these type of situations FULL OUTER JOINS are useful - but apparently MySQL does not support FULL OUTER JOINS see: Full Outer Join in MySQL
Update (without using right outer join):
create table table1
(month int
,salesperson_assigned int
,Product1_revenue int);
create table table2
(month int
,salesperson_assigned int
,Product2_revenue int);
insert into table1 values(1,10,100);
insert into table1 values(2,10,200);
insert into table1 values(1,11,40);
insert into table1 values(2,11,800);
insert into table1 values(3,11,400);
insert into table2 values(1,10,100);
insert into table2 values(2,10,200);
insert into table2 values(1,12,40);
insert into table2 values(2,12,200);
select
table1.month
,table1.salesperson_assigned
,ifnull(table1.Product1_revenue,0) as Product1_revenue
,ifnull(table2.Product2_revenue,0) as Product2_revenue
,ifnull(table1.Product1_revenue,0)+ifnull(table2.Product2_revenue,0) as total_revenue
from table1
left outer join table2
on table1.salesperson_assigned=table2.salesperson_assigned and table1.month=table2.month
union
select
table2.month
,table2.salesperson_assigned
,ifnull(table1.Product1_revenue,0) as Product1_revenue
,ifnull(table2.Product2_revenue,0) as Product2_revenue
,ifnull(table1.Product1_revenue,0)+ifnull(table2.Product2_revenue,0) as total_revenue
from table2
left outer join table1
on table2.salesperson_assigned=table1.salesperson_assigned and table1.month=table2.month
order by 2,1;
returns:
Month salesperson_assigned Product1_revenue Product2_revenue total_revenue
1 10 100 100 200
2 10 200 200 400
1 11 40 0 40
2 11 800 0 800
3 11 400 0 400
1 12 0 40 40
2 12 0 200 200
ps:Please consider posting code to reproduce your data so that you can get quicker response.

Related

How to get all records from one table and null with other table

Hi i have two tables event_service and appointment_feedback in which i have
two records in event_service table and one record in appointment_feedback
so i want matching record with event_service table and null record with
appointment_feedback.
Please follow my table structure
First table:event_service
....................................
evsr_id evsr_ev_id staff_id
....................................
1 101 1
2 101 2
Second table:appoitment_feedback
....................................
fd_id fd_app_id fd_comment
....................................
1 101 test
I want this output:
.................................................
evsr_id evsr_ev_id staff_id fd_comment
.................................................
1 101 1 test
2 101 2 null
I have tried below query but it is not giving null value it is giving repeeated value of comment i.e. test but it has only one entry in appointment_feedback table so i want two record from event_service table
and one record from appointment_feedback table with corresponding to that
record.
SELECT appointment_feedback.`fd_id`,`fd_app_id`,`fd_comment`,`fd_service_rat`
FROM event_service
left join `appointment_feedback`
on event_service.evsr_ev_id=appointment_feedback.fd_app_id
WHERE appointment_feedback.fd_app_id='3959'
This query is giving wrong Output:-
..............................................
fd_id fd_app_id fd_comment fd_service_rat
.............................................
1 101 test 0
1 101 test 0
I have used simple LEFT JOIN it give requested output.
DECLARE #event_service AS Table
(
evsr_id INT,
evsr_ev_id INT,
staff_id INT
)
DECLARE #appoitment_feedback AS Table
(
fd_id INT,
fd_app_id INT,
fd_comment VARCHAR(50)
)
INSERT INTO #event_service VALUES(1,101,1)
INSERT INTO #event_service VALUES(2,101,2)
INSERT INTO #appoitment_feedback VALUES(1,101,'test')
SELECT
es.*,
af.fd_comment
FROM #event_service es
LEFT JOIN #appoitment_feedback af ON es.evsr_ev_id=af.fd_app_id
AND es.evsr_id=af.fd_id
Output:
According to your question, you had the right tools but you miss-used them.
This is your current query:
SELECT appointment_feedback.`fd_id`,`fd_app_id`,`fd_comment`,`fd_service_rat` FROM `appointment_feedback` left join event_service on event_service.evsr_ev_id=appointment_feedback.fd_app_id WHERE appointment_feedback.fd_app_id='3959'
All what you have to do is swap the tables in a way to select from event_service and left join appointment_feedback, so this should be your new query:
SELECT appointment_feedback.`fd_id`,`fd_app_id`,`fd_comment`,`fd_service_rat`
FROM event_service
left join `appointment_feedback`
on event_service.evsr_ev_id=appointment_feedback.fd_app_id
WHERE appointment_feedback.fd_app_id='3959'
LEFT JOIN performs a join starting with the first (left-most) table and then any matching second (right-most) table records.
Source

Sql: How to connect tables by just using the ID

so I have this problem: I have 3 different tables that need to be connected to one another. It's rather complex and my english skills aren't that good. Let me show you:
T1 T2 T3
ID_T1 |Name | |ID_T1|ID_T2| |ID_T2|Spent|
1 |James| | 1| 4| | 4 | 200 |
2 |Mike | | 2| 5| | 5 | 300 |
3 |Alex | | 3| 6| | 6 | 400 |
Basically I want to connect in Table T3 the amount spent with the names in T1 by using the ID I have in T2.
So I should "read" that James spent 200 dollars, Mike spent 300 and Alex 400.
Another thing to know is that the IDs are generated automatically, so I'm not supposed to be able to see them.
Do I have to pay attention on something when I create my Tables, or do I have to focus more on the INSERT INTO command (I work with Oracle sql Developer)?
Thank you very much! :)
#Burkinaboy might wanna try this
SELECT
T1.Name,
T3.SPent
FROM T1 t0 RIGHT JOIN T2 t1 ON T1.ID_T1 = T2.ID_T1 RIGHT JOIN T3 t2 ON T3.ID_T2=T2.ID_T2
This should give you an expected output.
Select a.Name, c.spend
From T1 a, T2 b, T3 c
Where a.Id_T1 = b.Id_T1
AND b.Id_T2 = c.Id_T2
Regarding your second question, you should know the relation between the tables meaning how they are connected.
Updating the answer as per your comments . Assuming that amount spend column you are going to hard code..
Select b.Id_T2 , "300"
From T1 a ,T2 b
Where a.Id_T1 = b.Id_T1
But in above case , all the values for column spend would be 300.
SELECT T1.name, T3.spent FROM T1, T3 WHERE T1.ID_T1=T2.ID_T1 AND T2.ID_T2=T3.ID_T2
select t1.name as name, t3.spent as spent
from t1
join t2 on t2.id_t1 = t1.id_t1
join t3 on t3.id_t2 = t2.id_t2
Use join instead of putting all tables in FROM clause.
Assuming you are inserting every spending in T3 table with a new ID, you can join the three tables and do a group by on it:
select
T1.ID_T1 ID,
T1.NAME,
SUM(T3.SPENT) SPENT
from T1 inner join T2 on T1.ID_T1 = T2.ID_T1
inner join T3 on T2.ID_T2 = T3.ID_T2
GROUP BY T1.ID_T1, T1.NAME;
As of now, It's not clear which database you're using exactly. (I assumed that it's Oracle as you're using Oracle SQL Developer. Similar solution should be available in other DBMS as well in case it's not.).
First, Let's create the tables:
create table t1 (
ID_T1 integer primary key,
Name varchar2(100)
);
create table t2 (
ID_T1 integer,
ID_T2 integer,
constraint pk primary key(ID_T1,ID_T2)
);
create table t3 (
ID_T2 integer primary key,
spent number(10,2)
);
Then create two sequences that'll be used while inserting:
create sequence t1_seq start with 1 increment by 1;
create sequence t2_seq start with 1 increment by 1;
Then a view which will display spendings per person:
create or replace view spendings
as
select
T1.ID_T1 ID,
T1.NAME,
SUM(T3.SPENT) SPENT
from T1 inner join T2 on T1.ID_T1 = T2.ID_T1
inner join T3 on T2.ID_T2 = T3.ID_T2
GROUP BY T1.ID_T1, T1.NAME;
Then create an INSTEAD OF trigger on the above view to make the proper inserts in underlying tables:
create or replace trigger spendings_trig
instead of INSERT or UPDATE or DELETE on SPENDINGS
for each row
declare
v_ID_T1 integer;
v_ID_T2 integer;
v_name t1.name%type;
begin
if not inserting then
raise_application_error(-20001,'Not supported');
end if;
begin
if :new.ID is null then
v_ID_T1 := T1_SEQ.NEXTVAL;
insert into T1 (ID_T1, NAME) values (v_ID_T1, :new.NAME);
end if;
select ID_T1,NAME into v_ID_T1,v_name from T1
where ID_T1 = :new.ID;
if :new.name is not null and v_name <> :new.name then
raise_application_error(-20002,'Incorrect name entered');
end if;
exception
when no_data_found then
v_ID_T1 := :new.ID;
insert into T1 (ID_T1, NAME) values (v_ID_T1, :new.NAME);
end;
v_ID_T2 := T2_SEQ.NEXTVAL;
insert into T2 values (v_ID_T1, v_ID_T2);
insert into T3 values (v_ID_T2, :new.spent);
end;
/
Now if you insert into the view like this (assuming there is no data in any of the tables):
insert into spendings (name, spent) values ('James',100);
T1 will get a row
ID_T1 NAME
------------
1 James
T2 will get a row
ID_T1 ID_T2
------------
1 1
T3 will get a row
ID_T2 SPENT
-------------
1 100
Now if you do:
insert into spendings (id,spent) values (1,100);
T1 will not be inserted as there is already row present for ID = 1
T2 will get a row:
ID_T1 ID_T2
------------
1 1
1 2
T3 will get a row
ID_T2 SPENT
-------------
1 100
2 100
And
select * from spendings;
will show:
ID NAME SPENT
------------------
1 James 200

Update access table with values from another table using VBA

I have two tables, table 1 and table 2, in a database.
I am trying to update table 1 using VBA code based on data in table 2.
Example:
Table 1
PartNo Price Description
--------------------------
A 100
B 200 Bad
C 300
Table 2
PartNo Price Description
--------------------------
A 700
B 200 Good
D 900 Used
After the update, table1 should be updated with those prices or descriptions that have changed where table1 PartNo = table 2 PartNo , and add any new items that were present in table 2.
Table 1
PartNo Price Description
--------------------------
A 700
B 200 Good
C 300
D 900 Used
I can't seem to get it quite right, appreciate the help.
You can do it with two statements, an update and an insert like this:
Update:
UPDATE Table1
INNER JOIN table2
ON(table1.partNo = table2.PartNo)
SET table1.price = table2.price,
table1.description = table2.description
And then an insert:
INSERT INTO table1 (PartNo,Price,Description)
SELECT PartNo,Price,Description FROM table2 t
WHERE NOT EXISTS(SELECT 1 FROM table1 s
WHERE t.PartNo = s.PartNo)

sql join data from two tables

I wonder if someone help me to join data from two tables...spending all the day didn't manage...
Code 1 selects:
Year | Turnover1 | Quantity1 | EurPerOrder1
SELECT Year(table1.ContractDate) AS Year,
Sum(table1.TPrice) AS Turnover1,
Count(table1.id) AS Quantity1,
ROUND(Sum(table1.TPrice) / Count(table1.id), 0) AS EurPerOrder1
FROM table1
GROUP BY Year(table1.ContractDate) * 100
ORDER BY table1.ContractDate DESC
Code2 selects:
Year | Turnover2 | Quantiry2 | EurPerOrder2
SELECT Year(table2.date) AS Year,
Sum(table2.price) AS Turnover2,
Count(table2.rid) AS Quantiry2,
ROUND(Sum(table2.price) / Count(table2.rid), 0) AS EurPerOrder2
FROM table2
GROUP BY Year(table2.date) * 100
ORDER BY table2.date DESC
And I need to join data like:
Year | Turnover1 | Quantity1 | EurPerOrder1 | Turnover2 | Quantiry2 | EurPerOrder2
I need to have all data from both tables grouped by years. Even table2 doesnt have year 2013 anyway I would like it showed 0 or empty...
I have tried different ways using examples but nothing worked so I think the problem can occur because second table doesn't have all the years which are on table1...
First: you can read pretty good explanation about the JOINS here
Ok, according the question you need LEFT JOIN. This means all data from table1 and only matching data from table2.
The SELECT must look like:
SELECT Year(table1.ContractDate) AS Year,
Sum(table1.TPrice) AS Turnover1,
Count(table1.id) AS Quantiry1,
ROUND(Sum(table1.TPrice) / Count(table1.id), 0) AS EurPerOrder1,
Sum(table2.price) AS Turnover2,
Count(table2.rid) AS Quantiry2,
ROUND(Sum(table2.price) / Count(table2.rid), 0) AS EurPerOrder2
FROM
table1 t1
LEFT JOIN table2 t2 ON Year(table1.ContractDate) = Year(table2.date)
GROUP BY
Year(table1.ContractDate) * 100, Year(table2.date) * 100
ORDER BY
table1.ContractDate DESC, table2.date DESC
Of course you need to process NULL values. See link
Please check SQL and correct it if there are erreors. I don't have live data to check (by running it).

Add a cell from two or more rows in the same MySql table

I have x rows of a column value and "simply" want to add them together and update the highest row number and zero out the other values:
SELECT rowId, addCol FROM table WHERE rowId=1 OR rowId=2
rowId | addCol
1 | 100
2 | 200
3 | 67
This is kind of what I want (I know it's completely wrong) but not sure how to express it!
UPDATE table SET addCol3=addCol1+addCol2+addCol3, addCol1=0, addCol2=0
rowId | addCol
1 | 0
2 | 0
3 | 367
UPDATE table t1
JOIN table t2 ON (t1.rowId > t2.rowId)
LEFT OUTER JOIN table t3 ON (t1.rowId < t3.rowId)
SET t1.addCol = t1.addCol + t2.addCol,
t2.addCol = 0
WHERE t3.rowId IS NULL;
Explanation: any SQL expression that references more than one row should be done with a JOIN. In this case, we want t1 to be the row that has no greater rowId in any other row. If t1 has the greatest rowId, this means t3 would find no matching row, and therefore t3 would be NULL.
Now that we know t1 has the greatest rowId, match that to all other rows (t2) with a lesser rowId. Zero out the t2 value after adding it to the cumulative total in t1.