selecting duplicate values with a condition from a mysql table - mysql

I have the following table in mysql:
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
1 1234567 123 2013-12-31 3 10 2014-02-27 2014-03-10
2 1234567 123 2013-12-31 2 12 2014-03-10 9999-12-31
3 1234579 123 2013-12-31 3 12 2014-05-15 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
6 1224470 123 2015-11-11 2 12 2015-11-11 9999-12-31
7 1224471 123 2015-11-11 3 15 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
If there are records which has the same "FD", I need to get the ones which 's "FA" is "1", if exists.
Basically, I want this output.
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
It looks a complicated query, and I couldn't manage to do it.
How can I do it?
Thanks

Looks like a job for
...
GROUP BY FD
...
HAVING COUNT(FD) > 1
I don't see why you'd want 2012-06-30 in your results? I thought you only wanted ones where there is an FA of 1?

Try out following query:
select * from tbl group by fd having count(*)=1
union all
select t1.* from tbl t1 inner join (
select max(`key`) as `key` from tbl where fa=1 group by fd
) t2 on t1.`key`=t2.`key` group by FD;

SELECT T1.*
FROM table_name T1 LEFT JOIN
(SELECT * FROM table_name GROUP BY `FD` HAVING COUNT(*)>1 ) T2 ON T1.`FD`=T2.`FD` AND T1.`FA` <>1
WHERE T2.`FD` IS NULL
Can you check this.
Hope this helps.

Related

Join tables with the nearest date

installment_table:
acc_no
installment_no
due_date
12
1
2022-04-22
12
2
2022-05-22
12
3
2022-06-22
12
4
2022-07-22
12
5
2022-08-22
transaction_table:
acc_no
txn_date
12
2022-04-22
12
2022-05-24
12
2022-06-18
12
2022-07-18
12
2022-08-25
resulting_table:
acc_no
installment_no
due_date
txn_date
days_diff
12
1
2022-04-22
2022-04-22
0
12
2
2022-05-22
2022-05-24
2
12
3
2022-06-22
2022-06-18
-4
12
4
2022-07-22
2022-07-18
-4
12
5
2022-08-22
2022-08-25
3
I want to join the tables based on the account number and the nearest transaction date. Is there a way to do it in MySQL 8.0.37?
You can use a lateral join to evaluate the days difference and select the minimum for each row:
select *
from installment i,
lateral(
select txn_date, DateDiff(txn_date, due_date) days_diff
from transaction t
where t.acc_no = i.acc_no
order by Abs(DateDiff(txn_date, due_date))
limit 1
)t;
See Example fiddle

How to filter a sql request with DISTINCT and multiple results [duplicate]

This question already has answers here:
How can I SELECT rows with MAX(Column value), PARTITION by another column in MYSQL?
(22 answers)
Closed 4 years ago.
I want to filter the results, by not showing the same SAISON_ID, but to choose the SAISON_ID that have the most recent DATE_START
SELECT saison_id, date_start, date_end FROM saison
This request give me this result :
saison_id date_start date_end
0 2018-01-05 2018-01-12
0 2019-01-19 2019-02-05
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
If I do that :
SELECT DISTINCT(saison_id), date_start, date_end FROM saison GROUP BY saison_id
I have this new result :
saison_id date_start date_end
0 2018-01-05 2018-01-12
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
How can I get this instead ? (look the saisonID 0)
saison_id date_start date_end
0 2019-01-19 2019-02-05
1 2018-01-15 2018-02-13
2 2018-02-17 2018-03-24
3 2018-03-25 2018-06-12
4 2018-06-13 2018-09-18
5 2018-07-05 2018-11-19
6 2018-08-28 2018-11-20
7 2018-11-21 2019-01-17
Hi use this query to get the desired result
select id,[start],[end]
from
(select Row_Number() over(Partition By id order by [start] Desc) as Rownum,* from #session) a
where Rownum =1
In case this query is little complex to you then you can use this one also with the same result
select a.id,a.[start],a.[end] from #session a
inner join (select id, max([start]) as mx_s from #session group by id) b
on a.id = b.id and a.[start] = b.mx_s

ranking based on multiple tables

select a.no, a.Dtime,count(b.Dtime)+1 as Rank
from table1 a left
join table1 b on a.Dtime>b.Dtime and a.no=b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
table1 Input:
NO Dtime
1 08:10:00
1 09:10:00
1 09:40:00
1 10:10:00
2 09:30:00
2 10:15:00
3 09:00:00
Output:
NO Dtime Rank
1 08:10:00 1
1 09:10:00 2
1 09:40:00 3
1 10:10:00 4
2 09:30:00 1
2 10:15:00 2
3 09:00:00 1
But I am looking for Output in mysql where table2 Rank links to table1 and table2 Dtime i.e. table1.Dtime>table2.time
table2 Input
NO Dtime
1 08:30:00
1 09:15:00
1 09:50:00
2 08:30:00
2 09:45:00
3 09:50:00
Output:
NO table1.Dtime Rank table2.Dtime
1 08:10:00 0 00:00:00
1 09:10:00 1 08:30:00
1 09:40:00 2 09:15:00
1 10:10:00 3 09:50:00
2 09:30:00 1 08:30:00
2 10:15:00 2 09:45:00
3 09:00:00 0 00:00:00
You can use the same approach with your initial query. Just left join to table2. To get the Dtime from table2 you can use a correlated subquery:
select a.no, a.Dtime,
count(b.Dtime) as Rank,
coalesce((select c.Dtime
from table2 as c
where c.no = a.no and a.Dtime > c.Dtime
order by c.Dtime desc limit 1), '00:00:00') as t2Dtime
from table1 a
left join table2 b on a.Dtime > b.Dtime and a.no = b.no
group by a.no,a.Dtime
order by a.no, a.Dtime
Demo here

selecting duplicate values with a condition from a mysql table

I have the following table in mysql:
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
1 1234567 123 2013-12-31 3 10 2014-02-27 2014-03-10
2 1234567 123 2013-12-31 2 12 2014-03-10 9999-12-31
3 1234579 123 2013-12-31 3 12 2014-05-15 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
6 1224470 123 2015-11-11 2 12 2015-11-11 9999-12-31
7 1224471 123 2015-11-11 3 15 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
If there are records which has the same "FD", I need to get the ones which 's "FA" is "1", if exists.
Basically, I want this output.
Key DI CI FD FA NM Valid_from Valid_to
0 1224468 123 2012-06-30 3 6 2013-01-23 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
8 1224472 123 2015-11-10 2 13 2015-11-10 9999-12-31
9 1224473 123 2015-11-10 3 12 2015-11-10 9999-12-31
I have tried the following code, but it gives a weird output:
Code:
SELECT T1.*
FROM findoc T1 LEFT JOIN
findoc T2
ON DATE(T1.`Financial_date`) = DATE(T2.`Financial_date`) AND T2.`Fig_audit` <> 1
WHERE T2.`Fig_audit` IS NULL OR T1.`Fig_audit` = 1
Output:
Key DI CI FD FA NM Valid_from Valid_to
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
4 1234595 123 2013-12-31 1 12 2014-06-30 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
5 122469 123 2015-11-11 1 6 2015-11-11 9999-12-31
It looks a complicated query, and I couldn't manage to do it.
How can I do it?
Thanks.
you can do case based aggregation to find out if there exists row with same date and with atleast one row with column value for FA as 1
select F.* from finddoc F
inner join
(
select fd , sum( case when fa = 1 then 1 else 0 end) as faOneCount
from finddoc
group by fd
) T
on (F.FD = T.FD and T.faOneCount = 1 AND F.FA =1)
or ( F.FD = T.FD and T.faOneCount =0 )
If I understand your question correctly (and I'm not sure I do), you could try something like this:
SELECT T1.*
FROM findoc T1
where T1.NM in (select distinct NM from findoc where FA = 1);
I'm assuming that NM is the common field for which you want to return all results if the FA for any of those NM entries is 1. But that could be a wrong assumption.

SQL query to show zero instead of not shown record

I have these two tables:
Reception
id reception_date tin_lot company_id client_id quantity weight
1 2013-12-03 00:00:00 1 1 1 10 1980.00
2 2013-12-03 00:00:00 2 1 1 1 150.00
3 2013-12-13 00:00:00 3 1 2 10 4500.00
4 2013-12-13 00:00:00 4 2 5 5 2300.00
Payment
id payment_date amount reception_id
1 2013-12-03 00:00:00 500.0 1
2 2013-12-03 00:00:00 1200.0 3
The result I want to obtain is the following:
Expected result
id reception_date tin_lot client_id weight payment_made
1 2013-12-03 00:00:00 1 1 1980.00 500.0
2 2013-12-03 00:00:00 2 1 150.00 0.0
3 2013-12-13 00:00:00 3 2 4500.00 1200.0
4 2013-12-13 00:00:00 4 5 2300.00 0.0
I'm trying this query:
select rec.id
rec.reception_date,
rec.tin_lot,
rec.client_id,
rec.weight,
pay.payment_made
from liquidation.reception rec, liquidation.payment pay
where pay.recepcion_id=rec.id
But it doesn't list the receptions with no payment.
Please help me. Thanks in advance.
you need to Left Join the payment table:
from liquidation.reception rec
left join liquidation.payment pay on ( pay.recepcion_id=rec.id)
That is because you need to learn to use left outer join and proper join syntax. Just don't use a comma in a from clause any more.
Here is the query you want:
select rec.id, rec.reception_date, rec.tin_lot, rec.client_id, rec.weight,
coalesce(pay.payment_made, 0) as payment_made
from liquidation.reception rec left outer join
liquidation.payment pay
on pay.recepcion_id = rec.id;