I need to join 2 databases, with 2 tables each - sql

Dears,
I have an SQL problem. I need to join 2 databases, with 2 tables each. I have the pictures of the tables of the databases here. Thank you very much for your helps.

With a UNION ALL you can get 1 combined resultset from 2 selects.
Then you can group that and SUM the amounts per date.
So you're probably looking for something like this:
select
q.ID,
q.Name,
nullif(sum(case when q.Date = '2018-05-01' then q.Amount end), 0) as "5/1/2018",
nullif(sum(case when q.Date = '2018-05-02' then q.Amount end), 0) as "5/2/2018"
from
(
select u1.ID, u1.Name, a1.Date, a1.Amount
from DB1.Table1 AS u1
join DB1.Table2 AS a1 on (a1.ID = u1.ID and a1.Amount is not null)
where a1.Date IN ('2018-05-01', '2018-05-02')
union all -- combines the results of the 2 selects into one resultset
select u2.ID, u2.Name, a2.Date, a2.Amount
from DB2.Table1 AS u2
join DB2.Table2 AS a2 on (a2.ID = u2.ID and a2.Amount is not null)
where a2.Date IN ('2018-05-01', '2018-05-02')
) AS q
group by q.ID, q.Name
order by q.ID;
An alternative is to JOIN them all up.
select
coalesce(a1.ID, a2.ID) as ID,
max(coalesce(u1.Name, u2.Name)) as Name,
max(case
when coalesce(a1.Date, a2.Date) = '2018-05-01'
and coalesce(a1.Amount, a2.Amount) is not null
then coalesce(a1.Amount, 0) + coalesce(a2.Amount, 0)
end) as "5/1/2018",
max(case
when coalesce(a1.Date, a2.Date) = '2018-05-02'
and coalesce(a1.Amount, a2.Amount) is not null
then coalesce(a1.Amount, 0) + coalesce(a2.Amount, 0)
end) as "5/2/2018"
from DB1.Table2 AS a1
full join DB2.Table2 AS a2 on (a2.ID = a1.ID and a2.Date = a1.Date)
left join DB1.Table1 AS u1 on (u1.ID = a1.ID)
left join DB2.Table1 AS u2 on (u2.ID = a2.ID)
where coalesce(a1.Date, a2.Date) IN ('2018-05-01', '2018-05-02')
group by coalesce(a1.ID, a2.ID)
order by coalesce(a1.ID, a2.ID);
But then note that this way, that there's an assumption that the two Table2 have a uniqueness on (ID, Date)
T-Sql test data:
declare #DB1_Table1 table (id int, Name varchar(30));
declare #DB2_Table1 table (id int, Name varchar(30));
declare #DB1_Table2 table (id int, [Date] date, Amount decimal(8,2));
declare #DB2_Table2 table (id int, [Date] date, Amount decimal(8,2));
insert into #DB1_Table1 (id, Name) values (1,'Susan'),(2,'Juan'),(3,'Tracy'),(4,'Jenny'),(5,'Bill');
insert into #DB2_Table1 (id, Name) values (1,'Susan'),(2,'Juan'),(3,'Tracy'),(4,'Jenny'),(5,'Bill');
insert into #DB1_Table2 (id, [Date], Amount) values
(1,'2018-05-01',20),(2,'2018-05-01',null),(3,'2018-05-01',30),(4,'2018-05-01',50),(5,'2018-05-01',null),
(1,'2018-05-02',15),(2,'2018-05-02',40),(3,'2018-05-02',25),(4,'2018-05-02',8),(5,'2018-05-02',null);
insert into #DB2_Table2 (id, [Date], Amount) values
(1,'2018-05-01',null),(2,'2018-05-01',15),(3,'2018-05-01',20),(4,'2018-05-01',10),(5,'2018-05-01',null),
(1,'2018-05-02',15),(2,'2018-05-02',30),(3,'2018-05-02',35),(4,'2018-05-02',null),(5,'2018-05-02',30);

Related

Join results of multiple select statements in sql

I have four select statements and I want to join them all to only get the common rows.
In an example, I'm providing 2 select statements:
SELECT
h.userid, 'Activity' as table_name,
h.stamp,
DATEDIFF(dd, kh.LatestDate, GETDATE()) as days_since,
m.group_name
FROM
([Animal].[SYSADM].[activity_history] h
INNER JOIN
(SELECT userid, MAX(stamp) as LatestDate
FROM [Animal].[SYSADM].[activity_history]
GROUP BY userid) kh ON h.userid = kh.userid AND h.stamp = kh.LatestDate)
LEFT OUTER JOIN
[Animal].[SYSADM].secure_member m ON m.user_name = h.userid
WHERE
(DATEDIFF(dd, kh.LatestDate, GETDATE()) > 90)
AND NOT (m.group_name = 'inactive')
ORDER BY
userid
SELECT
h.userid, 'Person' as table_name, h.stamp,
DATEDIFF(dd, kh.LatestDate, GETDATE()) as days_since,
m.group_name
FROM
([Animal].[SYSADM].[person_history] h
INNER JOIN
(SELECT userid, max(stamp) as LatestDate
FROM [Animal].[SYSADM].[person_history]
GROUP BY userid) kh ON h.userid = kh.userid AND h.stamp = kh.LatestDate)
LEFT OUTER JOIN
[Animal].[SYSADM].secure_member m ON m.user_name = h.userid
WHERE
(DATEDIFF(dd, kh.LatestDate, GETDATE()) > 90)
AND NOT (m.group_name = 'inactive')
ORDER BY
userid
I have tried INTERSECT, but it's not returning any rows, I want to see the common rows from both the select statements (actually I have 4 so I believe what works for 2 will work for 4)
Thanks in advance.
Update:
I tried inner join on 2 select statements and it gave me the desired result but now the question is how I can use inner join on 4 select statements.
SELECT DISTINCT t1.userid as A_UserID, t2.userid as P_UserID, t1.stamp as A_stamp, t2.stamp as P_stamp, datediff(dd,t1.stamp,GetDate()) as A_days_since, datediff(dd,t2.stamp,GetDate()) as P_days_since, t1.group_name, t1.table_name, t2.table_name
from
(SELECT h.userid, 'Activity' as table_name, h.stamp, datediff(dd,kh.LatestDate,GetDate()) as days_since, m.group_name
FROM
( [Animal].[SYSADM].[activity_history] h
inner join (
select userid, max(stamp) as LatestDate
from [Animal].[SYSADM].[activity_history]
group by userid
) kh on h.userid = kh.userid and h.stamp = kh.LatestDate
)
left outer join [Animal].[SYSADM].secure_member m on m.user_name = h.userid
where
(datediff(dd,kh.LatestDate, GetDate()) > 90)
and not (m.group_name = 'inactive')) t1
inner join
(SELECT h.userid, 'Person' as table_name, h.stamp, datediff(dd,kh.LatestDate,GetDate()) as days_since, m.group_name
FROM
( [Animal].[SYSADM].[person_history] h
inner join (
select userid, max(stamp) as LatestDate
from [Animal].[SYSADM].[person_history]
group by userid
) kh on h.userid = kh.userid and h.stamp = kh.LatestDate
)
left outer join [Animal].[SYSADM].secure_member m on m.user_name = h.userid
where
(datediff(dd,kh.LatestDate, GetDate()) > 90)
and not (m.group_name = 'inactive')) t2
on
t1.userid = t2.userid
order by T1.userid
Query Result
Forget about the UNION for a moment. Imagine you take that result and insert into Table1
Then depend what you mean the "common rows". If you want exact value but in different tables
SELECT userid, h.stamp, days_since, m.group_name
FROM Table1
GROUP BY userid, h.stamp, days_since, m.group_name
HAVING COUNT( table_name ) = 2 -- in this case 2 because are two types
-- Activity and Persons
After viewing your query result you also need to add DISTINCT to each of the queries on the UNION.

SQL Case Reference

Using the code below (thank you #BHouse), I am attempting to adjust "ECOMMERCE" selling price to reflect "ENFIELD" selling price. As you can see from results, I am getting multiple entries.
Results can been seen here
SELECT
T1.STRTRADECODE AS [STORE],
T1.LINTITEMNUMBER AS [SKU],
CASE WHEN T1.STRTRADECODE = 'ECOMMERCE' THEN T2.CURNORMALSELL ELSE T1.CURNORMALSELL END AS [SELLINGPRICE]
FROM DAILYSALES T1
LEFT JOIN DAILYSALES T2 ON T1.LINTITEMNUMBER = T2.LINTITEMNUMBER AND T1.STRTRADECODE <> T2.STRTRADECODE
WHERE
T1.DTMTRADEDATE >= '2018-01-02 00:00:00'
AND T1.STRSALETYPE = 'I'
AND T1.STRTRADECODE IN ('ECOMMERCE', 'ENFIELD')
AND T1.LINTITEMNUMBER = '18760'
GROUP BY
T1.STRTRADECODE,
T1.LINTITEMNUMBER,
T1.CURNORMALSELL,
T2.CURNORMALSELL
ORDER BY
T1.STRTRADECODE DESC
Any help will be much appreciated.
Added Sku to the table , matching Sku and different store numbers will retrieve selling value for store2.
This query will help u, to use values matching another store
SELECT T1.STRTRADECODE AS [STORE], T1.LINTITEMNUMBER AS [SKU], T2.CURNORMALSELL AS [SELLINGPRICE]
FROM DAILYSALES T1
INNER JOIN (
SELECT *
FROM DAILYSALES
WHERE name = 'enfield'
) t2
ON t1.sku = t2.sku
WHERE T1.DTMTRADEDATE >= '2018-01-02 00:00:00' AND T1.STRSALETYPE = 'I' AND T1.STRTRADECODE IN (
'ECOMMERCE'
,'ENFIELD'
) AND T1.LINTITEMNUMBER = '18760'
ORDER BY T1.STRTRADECODE DESC
sample:
DECLARE #testtable TABLE (id INT identity(1, 1), name VARCHAR(100), sellingPrice FLOAT, sku BIGINT)
INSERT INTO #testtable (name, sellingPrice, sku)
SELECT 'Enfield', '60.50', '16043853021'
UNION
SELECT 'Ecommerce', '190.50', '16043853021'
UNION
SELECT 'Enfield', '120.45', '06062829018'
UNION
SELECT 'Ecommerce', '180.45', '06062829018'
;
select distinct t.id,t.name,t.sku,t2.sellingPrice
from #testtable t Inner join (select * from #testtable where name = 'enfield') t2
on t.sku = t2.sku

Unable to JOIN and get the final query

I'm having this following situation for which i'm unable to form a sql query. Please help me with this.
create table student(
studentName varchar(50)
);
Insert into student values('abc');
Insert into student values('mnop');
Insert into student values('xyz');
Insert into student values('pqrs');
create table workAssigned (
topic varchar(50),
creator varchar(50),
reviewer varchar(50),
creationCount decimal(4,2)
reviewCount decimal(4,2)
);
insert into workAssigned values('algebra','abc','mnop',1.25,0.75);
insert into workAssigned values('geometry','mnop','xyz',1.5,0.25);
insert into workAssigned values('algorithms','mnop','xyz',1.5,1.5);
insert into workAssigned values('derivative','xyz','abc',0.25,1);
final output reqiured is:
StudentName NumberOfWorkDone Effort
abc 2 2.25
mnop 3 3.75
xyz 3 2
pqrs NUll NULL
Where NumberOfWorkDone is SUM of creator and Reviewer, and
Effort is SUM of creationCount and reviewCount
You can try using Group By, Join and CASE with Aggregate functions,
SELECT studentName,
SUM(CASE WHEN W.creator = S.studentName OR S.studentName = W.reviewer THEN 1 ELSE NULL END ) AS NumberOfWorkDone,
SUM(CASE WHEN W.creator = S.studentName THEN W.creationCount WHEN S.studentName = W.reviewer THEN W.REVIEWCOUNT ELSE NULL END) AS Efforts
FROM student S
LEFT JOIN workAssigned W
ON S.studentName = W.creator OR S.studentName = W.reviewer
GROUP BY studentName
I have added NULL into Case statement for else part as your output was showing NULL but I think it would be better if you would replace that with 0.
Select studentName,NumberOfWorkDone,Effort
From student as A
Left Join
(
Select creator,count(creator) as NumberOfWorkDone,sum(creationCount) as Effort
From
(
Select creator,creationCount
from workAssigned as A
Union all
Select reviewer,reviewCount from workAssigned
)as A
Group by creator
)as B
On A.studentName=B.creator
select * from
(select count(col_X) as F, col_X
from
(select creator as col_X from workAssigned
UNION ALL
select reviewer as col_X from workAssigned) AS A
group by col_X) as E
left join
(select A, sum(B)
from
(select creator as A, creationCount as B
from workAssigned
UNION ALL
select revieweras A, reviewCount as B
from workAssigned) as C
group by A) as D
on E.F = D.A

Duplicate value in XMLAGG and RTRIM SQL Query

The Below query brings in duplicate values
SELECT maxuser.userid,
person.displayname,
maxuser.status,
sod_Report.severity,
sod_Report.scenario,
RTRIM(XMLAGG(Xmlelement(E,groupuser.groupname,',').EXTRACT('//text()') ORDER BY groupuser.groupname).GetClobVal(),',') groupname
FROM maxuser
INNER JOIN person
ON maxuser.userid = person.personid
LEFT OUTER JOIN maximo.groupuser
ON maxuser.userid = groupuser.userid
AND maxuser.userid = person.personid
LEFT OUTER JOIN sod_report
ON sod_report.userid = maxuser.userid
AND sod_report.userid = person.personid
WHERE 1 = 1
AND (( maxuser.userid LIKE '%XX%' ))
GROUP BY maxuser.userid,
person.displayname,
maxuser.status,
sod_Report.severity,
sod_Report.scenario
The output is coming as below
USERID DISPLAYNAME GROUPNAME
XXXX Test User A1,A1,B1,B1,C1,C1
Expected output
USERID DISPLAYNAME GROUPNAME
XXXX Test User A1,B1,C1
I have to use RTRIM and XMLAGG since the output of GROUPNAME should be displayed in single line separated by commas. This is for Oracle database , Please advise.
Demo
Add an additional step before the aggregation, that uses ROW_NUMBER.
create table groupuser (groupname varchar2(100));
insert into groupuser (groupname) values ('A1');
insert into groupuser (groupname) values ('A1');
insert into groupuser (groupname) values ('B1');
insert into groupuser (groupname) values ('B1');
insert into groupuser (groupname) values ('C1');
insert into groupuser (groupname) values ('C1');
select listagg (case when rn=1 then groupname end,',') within group (order by groupname)
from (select groupname
,row_number () over (partition by groupname order by null) as rn
from groupuser
)
;
select rtrim(xmlagg(case when rn=1 then xmlelement(e,groupname,',').extract('//text()') end order by groupname).getclobval(),',')
from (select groupname
,row_number () over (partition by groupname order by null) as rn
from groupuser
)
;
SELECT userid,
displayname,
status,
severity,
scenario,
RTRIM(XMLAGG(Xmlelement(E,groupname,',').EXTRACT('//text()') ORDER BY groupname).GetClobVal(),',') groupname
FROM (
SELECT maxuser.userid,
person.displayname,
maxuser.status,
sod_Report.severity,
sod_Report.scenario,
groupuser.groupname,
row_number () over (partition by groupuser.groupname order by null) as rn
FROM maxuser
INNER JOIN person
ON maxuser.userid = person.personid
LEFT OUTER JOIN maximo.groupuser
ON maxuser.userid = groupuser.userid
AND maxuser.userid = person.personid
LEFT OUTER JOIN sod_report
ON sod_report.userid = maxuser.userid
AND sod_report.userid = person.personid
WHERE 1 = 1
AND (( maxuser.userid LIKE '%XX%' ))
) t
GROUP BY userid,
displayname,
status,
severity,
scenario
;
You can use regular expression
select rtrim(regexp_replace('A1,A1,B1,B1,C1,C1','(\w+)(,(\1))+,?','\1,'),',') from dual

Selecting Distinct Fields From Joined Rows

I have a table ANIMAL and another table CALF_PARENT
Design of ANIMAL table is:
ID PK IDENTITY(1,1),
TagNo varchar(30)
and other columns...
Design of CALF_PARENT is:
ID PK IDENTITY(1,1),
Parent int (FK from Animal),
IsMother varchar(1)
I am writing following query to join two tables:
SELECT a.[TagNo]
,a.ID
,a2.TagNo
,isnull(cp.Parent,0)
,a3.TagNo
,isnull(cp.Parent,0)
FROM [dbo].[ANIMAL] a
LEFT JOIN [CALF_PARENT] cp
ON a.ID = cp.Calf
LEFT JOIN ANIMAL a2
ON a2.ID = cp.Parent AND cp.IsMother = 'Y' AND a2.ID IS NOT NULL
LEFT JOIN ANIMAL a3
ON a3.ID = cp.Parent AND cp.IsMother = 'N' AND a3.ID IS NOT NULL
Its returning me record like this:
Tag, CalfID, FatherTagNo, FatherID, MotherTagNo, MotherID
FA-56 21 AB-670 3
FA-56 21 CW-59 7
I want it to return me single row like this:
Tag, CalfID, FatherTagNo, FatherID, MotherTagNo, MotherID
FA-56 21 AB-670 3 CW-59 7
What would be the simplest way to implement it.
SELECT DISTINCT a.[TagNo] As Tag
,a.ID As CalfID
,MAX(a2.TagNo) As FatherTagNo
,MAX(isnull(cp.Parent,0)) As FatherID
,MAX(a3.TagNo) As MotherTagNo
,MAX(isnull(cp.Parent,0))As MotherID
FROM [dbo].[ANIMAL] a
LEFT JOIN [CALF_PARENT] cp
ON a.ID = cp.Calf
LEFT JOIN ANIMAL a2
ON a2.ID = cp.Parent AND cp.IsMother = 'Y' AND a2.ID IS NOT NULL
LEFT JOIN ANIMAL a3
ON a3.ID = cp.Parent AND cp.IsMother = 'N' AND a3.ID IS NOT NULL
GROUP BY a.[TagNo] ,a.ID
and with example
declare #t table (id varchar(10),cal int,father varchar(10),fatherid int,mother varchar(20),motherid int)
insert into #t(id,cal,father,fatherid,mother,motherid) values ('FA-56',21,'AB-670',3,NULL,NULL)
insert into #t(id,cal ,father,fatherid,mother,motherid) values ('FA-56',21,null,null, 'CW-59',21)
select distinct id As i,cal,MAX(father),MAX(fatherid),MAX(mother),MAX(motherid) from #t
group by id,cal
try this:
SELECT a.*, cpmd.*, cpfd.*
FROM dbo.ANIMAL a
LEFT JOIN CALF_PARENT cpm ON a.ID = cpm.Calf AND cpm.IsMother = 'Y'
LEFT JOIN ANIMAL cpmd ON cpmd.ID = cpm.Parent
LEFT JOIN CALF_PARENT cpf ON a.ID = cpf.Calf AND cpf.IsMother = 'N'
LEFT JOIN ANIMAL cpfd ON cpfd.ID = cpf.Parent
and your life would be easier if your calf_parent table would consist of 3 columns:
Animal_ID (PK), Father_ID, Mother_ID