getting wrong result - sql

Hospital_Visit
hid pid HospitalName DoctorId
41 1 abc 1
42 2 xyx 2
Patient_Master
pid PatientName
1 jill
2 rosy
Doctor_Master
DoctorID DoctorName
1 John
2 Jack
Hospital_Study
sid hid exam status
1 41 jjj sfvn
2 41 fks jdjd
select Hospital_Visit.Pid,PatientName,DoctorName from Patient_Master
inner join Hospital_Visit on Hospital_Visit.pid=Patient_Master.pid
inner join Doctor_Master on Doctor_Master.DoctorID= Hospital_Visit.DoctorID
inner join Hospital_Study on Hospital_Study.hid=Hospital_Visit.hid
Pid PatientName DoctorName exam status
1 Jill John jjj sfvn
2 rosy John fks jdjd
**
//Correct output i want
Pid PatientName DoctorName exam status
1 Jill John jjj sfvn
2 rosy Jack fks jdjd
**
i am getting wrong result repeting doctor
name in result because of inner join hid on Hospital_Visit and Hospital_Study
How can i takle this problem
(DTU Edit - Current sample data in usable form):
create table Hospital_Visit(hid int,pid int,HospitalName char(3), DoctorId int)
insert into Hospital_Visit(hid, pid, HospitalName, DoctorId) values
(41, 1, 'abc', 1),
(42, 2, 'xyx', 2)
create table Patient_Master(pid int, PatientName char(4))
insert into Patient_Master(pid, PatientName) values
(1, 'jill'),
(2, 'rosy')
create table Doctor_Master(DoctorID int, DoctorName char(4))
insert into Doctor_Master(DoctorID, DoctorName) values
(1, 'John'),
(2, 'Jack')
create table Hospital_Study(sid int, hid int, exam char(3), status char(4))
insert into Hospital_Study(sid, hid, exam, status) values
(1, 41, 'jjj' ,'sfvn'),
(2, 41, 'fks' ,'jdjd')

With the sample data given right now (revision 4), it's impossible to get the output you want.
Right now, your query returns this:
Pid PatientName DoctorName
1 jill John
1 jill John
What you want is this:
//Correct output i want
Pid PatientName DoctorName exam status
1 Jill John jjj sfvn
2 rosy Jack fks jdjd
...but the data in the Hospital_Study table doesn't match this, because both lines have hid = 41:
Hospital_Study
sid hid exam status
1 41 jjj sfvn
2 41 fks jdjd
So they both reference the first row from the Hospital_Visit table, which belongs to the patient named "Jill".
--> with this data, it's impossible to select the patient named "rosy", because there is no row in the Hospital_Study table that refers to rosy's visit (hid = 42).
To get the desired output, the data in the Hospital_Study would need to look like this:
Hospital_Study
sid hid exam status
1 41 jjj sfvn
2 42 fks jdjd
/\
||
this is different
With this data, and the exact query from your question, you get this result:
Pid PatientName DoctorName
1 jill John
2 rosy Jack

I have a doubt on your join
inner join Hospital_Study on Hospital_Study.hid=Hospital_Visit.hid
Hospital_Study.hid is Foreign key that's right but Hospital_Visit.hid is a primary key or is it a foreign key.
If Hospital_Visit.hid is a foreign key of then you have to add one more inner join on your Hospital's Master table (Hospital_Master).

Related

LEFT JOIN with EXTRA INFORMATION

I have 2 tables
table1: households
Serial_no
Address
sn1
New York
sn2
Maryland
sn3
France
table2: citizens
Serial_id
Fullname
Role
household_id
1
John
Head
sn1
2
Jane
Spouse
sn1
3
Johny
Son
sn1
4
Mike
Head
sn2
I want the output to be like this:
Serial_no
Address
Total_count
Head
sn1
New York
3
John
sn2
Maryland
1
Mike
sn3
France
0
null
I'm stuck here. please help. Thanks in advance!
You can use conditional aggregation with group by like below:
Schema and insert statements:
create table households(Serial_no varchar(10), Address varchar(50));
insert into households values('sn1', 'New York');
insert into households values('sn2', 'Maryland');
insert into households values('sn3', 'France');
create table citizens(Serial_id int, Fullname varchar(50), Role varchar(10), household_id varchar(10));
insert into citizens values(1,'John', 'Head', 'sn1');
insert into citizens values(2,'Jane', 'Spouse', 'sn1');
insert into citizens values(3,'Johny', 'Son', 'sn1');
insert into citizens values(4,'Mike', 'Head', 'sn2');
Query:
select Serial_no,Address,count(c.household_id) Total_count,
max(case when Role='Head' then Fullname end) Head
from households h
left join citizens c
on h.Serial_no=c.household_id
group by Serial_no,Address
Output:
Serial_no
Address
Total_count
Head
sn1
New York
3
John
sn2
Maryland
1
Mike
sn3
France
0
null
db<>fiddle here

Remove duplicate rows in Postgres

I have two tables:
Employee:
ID
Name
Surname
143
Amy
Flowers
245
Natasha
Smith
365
John
Alexander
445
Natasha
Smith
565
Monica
Withhouse
644
Amy
Flowers
1023
Amy
Alexander
And employee_details:
ID
Employee_id
Document_numer
1
644
XXXXXXXXX
2
245
XXXXXX
3
365
XXXXXX
I need to remove duplicate records that are in the Employee table and that are not related to the employee_details table. In the example data, I would like to delete the employee doublet with the id 143 and 445.
And I must admit that I have no idea how to do it.Could you give me a hint?
The base is postgres
Delete from Employee
Where id not in (
Select Employee_id
from employee_details
)
and name in (
Select name
from Employee
Group by name having count(name) > 1
)
Though the question is already answered I am adding two different answers here using cte.
create table Employee(ID int, Name varchar(50), Surname varchar(50));
insert into Employee values(143, 'Amy', 'Flowers');
insert into Employee values(245, 'Natasha', 'Smith');
insert into Employee values(365, 'John', 'Alexander');
insert into Employee values(445, 'Natasha', 'Smith');
insert into Employee values(565, 'Monica', 'Withhouse');
insert into Employee values(644, 'Amy', 'Flowers');
insert into Employee values(1023, 'Amy', 'Alexander');
create table employee_details ( ID int, Employee_id int, Document_numer varchar(50));
insert into employee_details values(1, 644, 'XXXXXXXXX');
insert into employee_details values(2, 245, 'XXXXXX');
insert into employee_details values(3, 365, 'XXXXXX');
Delete query 1:
with duplicate_employees as
(
select * , count(id)over(partition by name,surname) duplicate_count from Employee
)
delete from Employee where id in(
select id from duplicate_employees de
where duplicate_count >1
and not exists
(
select 1 from employee_details e where e.Employee_id = de.ID
)
)
select * from employee
Output:
id
name
surname
245
Natasha
Smith
365
John
Alexander
565
Monica
Withhouse
644
Amy
Flowers
1023
Amy
Alexander
db<>fiddle here
Delete query 2:
with cte as
(
Select *, count(*)over(partition by name,surname) duplicate_count,
(case when exists
(
select 1 from employee_details ed where ed.Employee_id = e.ID
)
then 1 else 0 end) exist_in_details
from Employee e
)
delete from Employee where id in (select id from cte where duplicate_count>1 and exist_in_details=0 )
select * from Employee
Output:
id
name
surname
245
Natasha
Smith
365
John
Alexander
565
Monica
Withhouse
644
Amy
Flowers
1023
Amy
Alexander
db<>fiddle here

Is there any way to make FULL OUTER JOIN table match with the correct record?

I'm trying to join two table using FULL OUTER JOIN that two table have different row of data and the column between this two table are same.
Table 2 FULL OUTER JOIN Table 1
Table 1
id name Payment Amount
=== ======== =====================
1 Jack 10000
2 May 20000
3 Amy 30000
Table 2
id name Payment Amount AccountID
=== ======== ==================== ============
1 Jack 10000 000001
2 Amy 30000 000002
Output that show after execute
id T1name
T2name Payment Amount AccountID
=== ======== ======== ==================== ============
1 Jack Jack 10000 000001
2 May Amy 20000 000002
3 Amy 30000
Output that I expect
id T1name
T2name Payment Amount AccountID
=== ======== ======== ==================== ============
1 Jack Jack 10000 000001
2 May 20000
3 Amy Amy 30000 000002
The table is order by Payment amount.
CREATE TABLE #Table1
([id] varchar(2), [name] varchar(4), [Payment Amount] int)
INSERT INTO #Table1
([id], [name], [Payment Amount])
VALUES
('S1', 'Jack', 10000),
('S2', 'May', 20000),
('S3', 'Amy', 30000)
CREATE TABLE #Table2
([id] varchar(2), [name] varchar(4), [Payment Amount] int)
;
INSERT INTO #Table2
([id], [name], [Payment Amount])
VALUES
('X1', 'Jack', 10000),
('X2', 'Amy', 30000)
select A.id,A.name T1name ,isnull(B.name,'') T2name,A.[Payment Amount] from #Table1 A left join #Table2 B on A.name=B.name
and A.[Payment Amount]=B.[Payment Amount]
output
id T1name T2name Payment Amount
S1 Jack Jack 10000
S2 May 20000
S3 Amy Amy 30000
You should always JOIN with primary key(specifically keys) or with unique key always. otherwise you will get duplicate values. Name column may not be unique and you will get Cartesian product .In your case in order to get your desired results you should join on t1.name=t2.name

SQL: vertically split table and create/populate keys, foreign key relationship

I would like to vertically split an existing (already filled with data).
Say my starting table (trip) looks like this:
ID Person Age Trip_to Date
... Alice 21 Los Angeles 2015-04-01
... Bob 35 New York 2015-03-15
... Bob 35 Chicago 2015-03-20
... Bob 35 San Francisco 2015-03-29
... Carol 29 Miami 2015-03-30
... Carol 29 Boston 2015-04-05
I would like to split this table into two tables, as it should be, one each for person and trip.
When copying each unique person into a table person, I want the automatically created uniqueidentifier column in that table person.pId (the primary key) to be copied into a newly created uniqueidentifier column trip.personid in the original table and turn that into a foreign key. (I would then delete the trip.person and trip.age column from the original table, and have the data structured as I want them.)
I thought I could use a trigger for that when I insert the person rows into the new table, like so:
CREATE TRIGGER tr_person
on person
after INSERT
as
begin
UPDATE Trip
SET personId=(SELECT i.pId from inserted i)
WHERE person=(SELECT i.person from inserted i) and age=(SELECT i.age from inserted i)
END
However, I get this:
Subquery returned more than 1 value.
This is not permitted when the subquery follows =, !=, <, <= , >, >=
or when the subquery is used as an expression.
Apparently the trigger only executes after all (potentially multiple!) inserts have been carried out, and by that time a query on inserted is no longer allowed for my SET statement.
I also thought about using an OUTPUT clause on the INSERT statement, but that wouldn't work either
Insert into person (Driver, Age)
OUTPUT inserted.pId INTO trip.personId WHERE trip.person=inserted.person AND trip.Age=inserted.Age
(Select DISTINCT Person, Age FROM Trip)
So I am wondering now, am going about this all wrong? Is there another way to automagically create the keys and relationships between the two newly split tables?
EDIT Desired result:
Table trip:
ID Trip_to Date PersonId
... Los Angeles 2015-04-01 xxxx1
... New York 2015-03-15 xxxx2
... Chicago 2015-03-20 xxxx2
... San Francisco 2015-03-29 xxxx2
... Miami 2015-03-30 xxxx3
... Boston 2015-04-05 xxxx3
Table person
pId Person Age
xxxx1 Alice 21
xxxx2 Bob 35
xxxx3 Carol 29
(The ID fields should all be uniqueidentifiers, of course)
Here is an idea:
First, you insert all distinct Person from Trip table to Person table:
CREATE TABLE Person(
pID UNIQUEIDENTIFIER PRIMARY KEY,
Person VARCHAR(10),
Age INT
)
INSERT INTO Person
SELECT
NEWID(), Person, Age
FROM(
SELECT DISTINCT Person, Age FROM Trip
)t
Then, add a new FK column to Trip table PersonId which references pId from the Person table:
ALTER TABLE Trip
ADD PersonId UNIQUEIDENTIFIER
FOREIGN KEY(PersonId) REFERENCES Person(pId)
Then, UPDATE the newly added FK column with values from Person table using a JOIN on Person and Age:
UPDATE t
SET PersonId = p.pID
FROM Trip t
INNER JOIN Person p
ON p.Person = t.Person
AND p.Age = t.Age
Finally, you can drop Person and Age from Trip table:
ALTER TABLE Trip DROP COLUMN Person
ALTER TABLE Trip DROP COLUMN Age
RESULT
Person
pID Person Age
------------------------------------ ---------- -----------
35815766-1634-45FF-A3F6-8194B43F3F65 Alice 21
8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67 Bob 35
D0EDCEA8-3825-4693-9352-BF7A04AEFCB2 Carol 29
Trip
ID Trip_to Date PersonId
------------------------------------ -------------------- ---------- ------------------------------------
77357A57-FAAE-43DE-923E-219038B8641E Los Angeles 2015-04-01 35815766-1634-45FF-A3F6-8194B43F3F65
C1B64E81-D30A-46A9-A868-1D92C4B64B8C New York 2015-03-15 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
21F3614A-8E76-4A64-8A0B-815D5343FC26 Chicago 2015-03-20 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
E1DB1926-4268-4BFA-B5E0-DA603DA8E1B7 San Francisco 2015-03-29 8EB3A7CC-CED1-4DBC-98B0-99D325BC7F67
F50E45E6-E689-444B-96C1-F936CA6F3D2A Miami 2015-03-30 D0EDCEA8-3825-4693-9352-BF7A04AEFCB2
C2FA7073-79D7-42E8-B2C8-6EEDBC374002 Boston 2015-04-05 D0EDCEA8-3825-4693-9352-BF7A04AEFCB2
Side note: You should not be storing the Age of the person. Instead, store the birthdate and compute the age on the fly.

How to insert a record in a table so that the string field with id?

I have a table to be imported from excel.It has an column called the sector table name "ExcelTable"
Name Title Sector
John manager Sofware
Sam Lawyer Jus
"ExcelTable" has 3284 rows.I create table called "SECTORS"."SECTORS" table's cloumn like this
SectorId SectorName
1 Sofware
2 Jus
It has 61 rows.
I inserted "EXCELTABLE" to "GLOBALCONTACTS".They has same rows number 3284 I want to insert "GLOBAL_CONTACTS" table sector by sectorid .It is now
ContactId Name Title Sector
1 John manager null
2 Sam Lawyer null
I want it to be like this
ContactId Name Title Sector
1 John manager 1
2 Sam Lawyer 2
I think you just want to join ExcelTable to Sectors for an INSERT:
INSERT INTO GLOBAL_CONTACTS (Name,Title,Sector)
SELECT e.Name,e.Title,s.SectorID
FROM ExcelTable e
INNER JOIN Sectors s
ON e.Sector = s.SectorName