How to Remove duplicate values from join query - sql

Hi ever one how can i remove the duplicate records from this join statement.
SELECT std_info.Reg_no, std_info.std_name, tut_fee.fee_month, class.class_name
FROM std_info
INNER JOIN tut_fee on std_info.Reg_no=tut_fee.Reg_no
INNER JOIN promot on std_info.Reg_no=promot.Reg_no
INNER JOIN class on class.class_id=promot.class_id
WHERE std_info.Reg_no not in (SELECT Reg_no
FROM tut_fee
WHERE tut_fee.fee_month=3
AND tut_fee.fee_year=2014)
It give the result
Reg_no std_name fee_month class_name
1. A01 name1 1 2nd
2. A01 name1 2 2nd
3. A02 name2 1 3rd
4. A02 name2 2 3rd
Thanks For all.

the dublicat Come from the column "tut_fee.fee_month,"

First I created the temporary table in database, name Fee_temp and then insert the record given by the query. And then make partition using Row_Number function.And delete all the record that is listed more than ones. Like give below.
insert into Fee_temp SELECT std_info.Reg_no,std_info.std_name,tut_fee.fee_month,class.class_name FROM
std_info Left JOIN tut_fee on std_info.Reg_no=tut_fee.Reg_no Left JOIN promot on std_info.Reg_no=promot.Reg_no Left JOIN
class on class.class_id=promot.class_id
WHERE std_info.Reg_no not in (select Reg_no FROM tut_fee where tut_fee.fee_month=3 and tut_fee.fee_year=2014)
SELECT * from Fee_temp
With A as
(
select Fee_temp.Reg_no,Fee_temp.std_name,Fee_temp.fee_month,Fee_temp.class_name,ROW_NUMBER()
OVER (Partition by Reg_no ORDER BY Fee_temp.std_name) As Number from Fee_temp
)
DELETE FROM A WHERE Number>1
SELECT * FROM Fee_temp

Related

How to fix sql query problem with two or more position which have one ID

I have sql query where I have to join three tables. One of this is a table with data of invoice, it looks like this:
INVOICE
ID CUSTOMER_NAME TAXID NUMBER LABEL GUID
1 CUSTOMER1 8739281100 FV001/2019 1 04EABFB3-0B9D-4749-B99D-A4EBEE079633
POSITION OF INVOICE
ID ID_INV POSITION_NAME COUNT
1 1 NAME1 3
2 1 NAME2 2,5
TABLE WITH LABEL
ID NAME VALUE GUID_INV
1 LABEL1 true 04EABFB3-0B9D-4749-B99D-A4EBEE079633
When I want to run this query I have statement like this multiple rows in singleton select.
This is for Firebird 2.5.
SELECT
a.ID,
a.GUID,
a.NUMBER,
a.CUSTOMER_NAME,
b.COUNT,
(select usrd.LABEL from USER_FIELD_DEFS usrd
where usrd.GUID_INV=a.GUID and (usrd.ID=1 and usrb.VALUE='true')) as LABEL_NAME
FROM INVOICE a
join POSITION_INVOICE b ON a.ID=b.ID_INV
I want to get result like this
1 04EABFB3-0B9D-4749-B99D-A4EBEE079633 FV001/2019 CUSTOMER1 3 LABEL1
1 04EABFB3-0B9D-4749-B99D-A4EBEE079633 FV001/2019 CUSTOMER1 2,5 LABEL1
Please help with this. I know that solution maybe is very simple but I have some eclipse of the mind:)
This should give you the rows you want based on the 3 tables you provided. If there is a chance that an invoice has no position then simply replace the inner join with left join
SELECT
I.[Id]
,I.[GUID]
,I.[NUMBER]
,I.[CUSTOMER_NAME]
,IP.[POSITION_NAME]
,L.[NAME]
FROM [INVOICE] I
INNER JOIN [IN_P] IP ON IP.ID_INV = I.Id
LEFT JOIN [LABEL] L ON L.[GUID_INV] = I.[GUID]
You are just missing one more join here. Assuming USER_FIELD_DEFS is the same as TABLE WITH LABEL that you have mentioned here
SELECT
a.ID,
a.GUID,
a.NUMBER,
a.CUSTOMER_NAME,
b.COUNT,
c.NAME
FROM INVOICE a
JOIN POSITION_INVOICE b ON a.ID=b.ID_INV
JOIN USER_FIELD_DEFS c ON c.GUID_INV = a.GUID AND c.ID=1 and c.VALUE='true'

Grouping the data and showing 1 row per group in postgres

I have two tables which look like this :-
Component Table
Revision Table
I want to get the name,model_id,rev_id from this table such that the result set has the data like shown below :-
name model_id rev_id created_at
ABC 1234 2 23456
ABC 5678 2 10001
XYZ 4567
Here the data is grouped by name,model_id and only 1 data for each group is shown which has the highest value of created_at.
I am using the below query but it is giving me incorrect result.
SELECT cm.name,cm.model_id,r.created_at from dummy.component cm
left join dummy.revision r on cm.model_id=r.model_id
group by cm.name,cm.model_id,r.created_at
ORDER BY cm.name asc,
r.created_at DESC;
Result :-
Anyone's help will be highly appreciated.
use max and sub-query
select T1.name,T1.model_id,r.rev_id,T1.created_at from
(
select cm.name,
cm.model_id,
MAX(r.created_at) As created_at from dummy.component cm
left join dummy.revision r on cm.model_id=r.model_id
group by cm.name,cm.model_id
) T1
left join revision r
on T1.created_at =r.created_at
http://www.sqlfiddle.com/#!17/68cb5/4
name model_id rev_id created_at
ABC 1234 2 23456
ABC 5678 2 10001
xyz 4567
In your SELECT you're missing rev_id
Try this:
SELECT
cm.name,
cm.model_id,
MAX(r.rev_id) AS rev_id,
MAX(r.created_at) As created_at
from dummy.component cm
left join dummy.revision r on cm.model_id=r.model_id
group by 1,2
ORDER BY cm.name asc,
r.created_at DESC;
What you were missing is the statement to say you only want the max record from the join table. So you need to join records, but the join will bring in all records from table r. If you group by the 2 columns in component, then select the max from r, on the id and created date, it'll only pick the top out the available to join
I would use distinct on:
select distinct on (m.id) m.id, m.name, r.rev_id, r.created_at
from model m left join
revision r
on m.model_id = r.model_id
order by m.id, r.rev_id;

SQL get latest row in one to many relationship using where clause only

I have two tables in which (roll_no) is same in both tables.
I have a table (student) having columns name and roll_no. e.g
roll_no name
----------------
123 John
It has relation with another table (student_changed). Which has columns name, roll_no and LastEditTime. e.g.
roll_no name LastEditTime
--------------------------------------
123 Johny 2017-11-09 06:00:00
123 John 2017-11-08 07:00:00
What I want to ask is, how can I get the join having the most recent LastEditTime.
There are many similar questions but my limitation is that I can only use/modify where clause.
e.g.
I cannot modify the select query as well.
Consider it like this
select * from student, student_changed <-- *this part cannot be changed*
where <-- This can be modified
You do not need the join. Table student_changed has all you need:
select roll_no, name, max(LastEditTime) as LastEditTime
from student_changed
group by roll_no, name
Try this query:
select roll_no,name, max(LastEditTime)
from table2
group by
roll_no,name;
Update 1:
select table1.roll_no,table1.name, max(table2.LastEditTime)
from table2 join table1 on table1.roll_no=table2.roll_no
group by
table1.roll_no,table1.name;
One table is enough for your requirement.
Update 2:
select table1.roll_no,table1.name, max(table2.LastEditTime)
from table2 join table1
where table1.roll_no=table2.roll_no
group by table1.roll_no,table1.name;
Update 3:
select table1.roll_no,table1.name,table2.LastEditTime
from table2 join table1
where
(table1.roll_no,table1.name,table2.lastEditTime) in (select table1.roll_no,table1.name, max(table2.LastEditTime) from table2 join table 1 on table1.roll_no=table2.roll_no
group by table1.roll_no,table1.name);
Thanks for all the answers but I managed to get it working by the following where clause.
where student.roll_no = student_changed.roll_no
and LASTEDITTIME in(select max(LASTEDITTIME) from student_changed where student.roll_no = student_changed.roll_no)

SELECT clause with group by expression

Table Name : TEST
//TEST
A# NAME
------------
1 CHIRS
2 MAY
3 JOHN
//APPLIES
A# P#
---------------------
1 HELLO
2 YES
1 HAPPY
When ever i use this query:
SELECT DISTINCT * FROM TEST t INNER JOIN APPLIES ap
on t.A#=ap.A# WHERE count(*)>1;
I want to show display only 1 or more records found in APPLIES where TEST.A#=APPLEIS.A#
Expected output:
A# NAME
-------------
1 CHIRS
You should indicate the column names individuallly in your code. Try this:
SELECT t.A#, t.NAME, t.ADDRESS, t.ACOMMENT
FROM TEST t INNER JOIN APPLIES ap
on t.A#=ap.A# GROUP BY t.A#, t.NAME, t.ADDRESS, t.ACOMMENT;
Grouping by all the fields is essentially the same as using distinct:
SELECT DISTINCT *
FROM test t
INNER JOIN applies ap ON t.A#=ap.A#;

Oracle Statement does not count correctly

I've got a SQL-statement with a - for me not explainable - strange behaviour.
Perhaps you could find what's wrong:
When I use the statement
select count(*) from department
I got 2755 results
Using the following statement
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
I got 2755 results too.
But when I want to combine the two statements with a left join:
select count(*) from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.buildingid = postadress.buildingid;
I got 3648513 results.
My expectation was, that I get only 2755 results.
Where's the mistake?
Thanks for help!
I assume that buildingid is not unique (for my reasoning to hold true, it can't be unique)
Imagine following simple tables
TableA
create TableA (name VARCHAR(32));
insert into TableA values ('Lieven');
insert into TableA values ('Lieven');
TableB
create TableB (name VARCHAR(32));
insert into TableB values ('Lieven');
insert into TableB values ('Lieven');
insert into TableB values ('AnyOtherValue');
Select statement
select * from TableA a left outer join TableB b on a.name = b.name
As each record of TableA is matched with each record of TableB where the name is equal, this will result in 4 records (the AnyOtherValue is dissmissed as it doesn't match)
The first record of TableA is returned with two of three records of `TableB'
The second record of TableA is returned with two of three records of `TableB'
The query
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
will return one row per department that has usepostaladresssupporter as either 0 or 1 (note that records with other values will not be included, this may or may not be a problem depending on the constrainst of this column).
The unique key of this query results is probably something like departmentid (you will need to include that column in your select criteria).
So the correct query should look something like this:
select * from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.departmentid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.departmentid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.departmentid = postadress.departmentid;
Your query will go wrong on data something like this:
Departmentid BuildingId Name
1 1 Dept1
2 2 Dept2
3 2 Dept3
The multiplying effect is not quite equal to deptcount * deptcount, but rather it is buildingcount * buildingcount + deptcount - buildingcount