How to Avoid Duplicate ID's In Access SQL - sql

I have a problem that I hope you can help me.
I have the next query on Access SQL.
SELECT
ID_PLAN_ACCION, ID_SEGUIMIENTO,
Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM
SEGUIMIENTOS
WHERE
(((ID_PLAN_ACCION) = [CODPA]))
GROUP BY
ID_PLAN_ACCION, ID_SEGUIMIENTO;
And it returns this information:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
-----------------------------------------------
A1-01 1 16/01/2014
A1-01 2 30/01/2014
But I really need that it throws off this:
ID_PLAN_ACCION ID_SEGUIMIENTO MAX_FECHA
----------------------------------------------
A1-01 2 30/01/2014
As you can see I only need the record that has the most recently date, not all the records
The GROUP BY doesn't work.
Please can you tell me what can I do? I am new on all this.
Thank you so much!!
PD: Sorry for my english, I'm learning

This will produce the results you want:
SELECT ID_PLAN_ACCION, max(ID_SEGUIMIENTO) as ID_SEGUIMIENTO, Max(FECHA_SEGUIMIENTO) AS MAX_FECHA
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
GROUP BY ID_PLAN_ACCION;
I removed id_sequiimiento from the group by and added an aggregation function to get the max value. If the ids increase along with the date, this will work.
Another way to approach this query, though, is to use top and order by:
SELECT top 1 ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS
WHERE ID_PLAN_ACCION = [CODPA]
ORDER BY FECHA_SEGUIMIENTO desc;
This works because you are only returning one row.
EDIT:
If you have more codes, that you are looking at, you need a more complicated query. Here is an approach using where/not exists:
SELECT ID_PLAN_ACCION, ID_SEGUIMIENTO, FECHA_SEGUIMIENTO
FROM SEGUIMIENTOS s
WHERE not exists (select 1
from SEGUIMIENTOS s2
where s.ID_PLAN_ACCION = s2.ID_PLAN_ACCION and
s2.FECHA_SEGUIMIENTO > s.FECHA_SEGUIMIENTO
)
ORDER BY FECHA_SEGUIMIENTO desc;
You can read this as: "Get me all rows from SEGUIMIENTOS where there is no other row with the same ID_PLAN_ACCION that has a larger date". Is is another way of saying that the original row has the maximum date.

Related

Fetch latest date records with group by

I am trying to fetch the records with latest records with unique report_ids (col_1_0_ ).
Possible group by col_1_0_ and fetch the latest of that group record using this column col_10_0_ timestamp.
I tried to search this forum to find the way but it did not worked for me . It will be helpful if anyone help me to find the similar thread or help to make to get the results.
col_1_0_|ppi_event_id|col_2_0_ |col_10_0_ |
--------|------------|--------------------------|-----------------------|
149056| 3249|Draft |2020-08-25 13:01:49.016|
149056| 3249|Submitted | 2020-08-25 13:10:22.01|
149056| 3249|Submitted to administrator|2020-08-25 13:12:39.367|
149056| 3249|Validated |2020-08-25 13:13:28.879|
149060| 3249|Submitted to administrator|2020-08-25 13:32:41.924|
The expected result is
col_1_0_|ppi_event_id|col_2_0_ |col_10_0_ |
--------|------------|--------------------------|-----------------------|
149056| 3249|Validated |2020-08-25 13:13:28.879|
149060| 3249|Submitted to administrator|2020-08-25 13:32:41.924|
Anyone help in this regard.
Update : I have tried the solution mentioned below but sometimes it shows the first record "Draft" rather than "Validated"
Any other option to try ?
In Postgres, I would recommend using distinct on: that's a nice extension to the SQL standard, that was built exactly for the purpose you describe.
select distinct on (col_1_0) t.*
from mytable t
order by col_1_0, col_10_0_ desc
Traditional SQL format is to use row_number()
Demo
SELECT * FROM (
SELECT A.*,
ROW_NUMBER() OVER( PARTITION BY col_1_0_ ORDER BY col_10_0_) AS RN
FROM TABLE1 A ) X WHERE RN = 1;

SQL: Selecting between date range

My query returns 1 value if I use the Max(SampleDateTime) or Min( ) on the Date/Time field I want, but it returns no values if I leave out the Max or Min. I want to return ALL the values, but I can't seem to figure this out.
I want all the Quality Samples between the Start and Stop times of a Production Run.
RunSamples:
Select Max([SampleDateTime])
FROM [QualitySamples] AS [GoodSamples]
WHERE [GoodSamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND [GoodSamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate]
ProductionRuns_tbl:
RunStartDate RunEndDate
1/1/2017 12 AM 1/5/17 12 AM
...
QualitySamples Tbl:
ID SampleDateTime
1 1/1/2017 2 am
2 1/1/2017 3 am
...
Here's the full SQL code:
SELECT ProductionRuns_tbl.RunName, ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
(Select Max([SampleDateTime])
FROM [QualitySamples] AS [GoodSamples]
WHERE [GoodSamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND [GoodSamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate])
AS RunSamples
FROM ProductionRuns_tbl
WHERE (((ProductionRuns_tbl.RunName)=[Forms]![Home]![RunName]));
Try to use join instead:
SELECT ProductionRuns_tbl.RunName,
ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
GoodSamples.SampleDateTime
FROM QualitySamples GoodSamples INNER JOIN ProductionRuns_tbl ON
GoodSamples.SampleDateTime >= ProductionRuns_tbl.RunStartDate AND
GoodSamples.SampleDateTime <= ProductionRuns_tbl.RunEndDate
WHERE ProductionRuns_tbl.RunName=[Forms]![Home]![RunName]
I'm taking a risk posting right now, because I had to try to read your mind on what you're trying to do (plus, I don't know if this will work in Access, but it will work in SQL server)
Since you want all the data, is this what you're looking for?
SELECT
ProductionRuns_tbl.RunName,
ProductionRuns_tbl.RunStartDate,
ProductionRuns_tbl.RunEndDate,
[QualitySamples].[SampleDateTime]
FROM
ProductionRuns_tbl
LEFT JOIN
[QualitySamples]
ON
[QualitySamples].[SampleDateTime] >= [ProductionRuns_tbl].[RunStartDate]
AND
[QualitySamples].[SampleDateTime] <= [ProductionRuns_tbl].[RunEndDate]
WHERE
(((ProductionRuns_tbl.RunName)=[Forms]![Home]![RunName]));
This should list the RunName, Start and End dates repeated for each individual SampleDateTime. Based on your more specific requirements, you can then refine the results from there.
Dont have WHERE, MAX or MIN. Just have the SELECT query.
Select [SampleDateTime]
FROM [QualitySamples] AS [GoodSamples]

compare records within same table

I have Student_Table with following structure.
Student_Note Table
student_id seq_num note
11212 1 firstnote
11212 2 secondNote
11212 3 thirdNote
21232 1 secondstudentnote1
21232 2 secondstudentnote2
so on
I want to get latest note (which has largest seq_num) for a particilar student.
I have tried following query
select tn.note from Student_Note tn JOIN Student_Note tn1
ON (tn.student_id =tn1.student_id AND tn.seq_num < tn1.seq_num)
where tn.student_id=11212
it is giving more than one row. How to achieve aforementioned scenario ?
I forgot mention that I am using above query as subquery . As per sybase TOP clause will not work in subquery.
P.S. I am using sybase.
OK - changed as apparently cannot use TOP.........
select tn.note from Student_Note tn
where tn.student_id=11212
and tn.seq_num = (SELECT MAX(seq_num) from Student_Note WHERE Student_Note.Student_Id = tn.Student_Id)
Please try this
select substring(max(str(seq_num,10,'0') + note),11,len(note))
from Student_Note
where student_id=11212

Assistance with SQL Query (aggregating)

I have a requirement to create a Sales report and I have a sql query:
SELECT --top 1
t.branch_no as TBranchNo,
t.workstation_no as TWorkstation,
t.tender_ref_no as TSaleRefNo,
t.tender_line_no as TLineNo,
t.tender_code as TCode,
T.contribution as TContribution,
l.sale_line_no as SaleLineNo
FROM TENDER_LINES t
LEFT JOIN SALES_TX_LINES l
on t.branch_no = l.branch_no and t.workstation_no = l.workstation_no and t.tender_ref_no = l.sale_tx_no
where l.sale_tx_no = 2000293 OR l.sale_tx_no = 1005246 --OR sale_tx_no = 1005261
order by t.tender_ref_no asc,
l.sale_line_no desc
The results of the query look like the following:
The results I am trying to achieve is:
With only 1 line for transaction 2 either SaleLineNo 1 or 2, while still have=ing both lines for transaction 1 because the TCode is different.
Thanks
I am using SSQL2012.
Not exactly sure on what data you have, but you might want to try
GROUP BY TlineNo, TCode ...
But you have to keep a look on not to group by something that would result in duplicate contribution values.
You can use the ROW_NUMBER function that allows to partition the rows in groups, and number the lines inside each group starting by one. If you choose the right columns to define the partition, and keep only the rows with "row_number = 1`, you have solved the first part of your problem, i.e. discarding the lines that don't have to appear in the report. (See the sample sin the linked documentation, they're quite clear).
Once you have solved this problem, you simply have to repeat what you're doing, but on the result of this data, instead of the original data. You can use a view, a CTE, or a subselect to achieve your result, i.e.
With view:
CREATE VIEW FilteredData AS -- here the rank function query, then selct from the view
SELECT --here your current query --
FROM FilteredData
With CTE
WITH -- here the rank function query
SELECT -- your current querym, from the CTE
With subselect
SELECT -- your current query
FROM (SELECT FROM -- here the rank function query -- )
Appreciate your assistance with my query. After playing around, I have found a solution that works just as I want. It is as below: I did a Group by as hinted by #Yogesh86 on a few fields.
SELECT
MAX(t.branch_no) as TBranchNo,
Max(t.workstation_no) as TWorkstation,
t.tender_ref_no as TSaleRefNo,
Max(t.tender_line_no) as TLineNo,
t.tender_code as TCode,
MAx(T.contribution) as TContribution,
MAX(l.sale_line_no) as SaleLineNo
FROM TENDER_LINES t
LEFT JOIN SALES_TX_LINES l
on t.branch_no = l.branch_no and t.workstation_no = l.workstation_no and t.tender_ref_no = l.sale_tx_no
where l.sale_tx_no = 2000293 OR l.sale_tx_no = 1005246 --OR sale_tx_no = 1005261
GROUP BY
t.tender_ref_no,
t.tender_line_no,
t.tender_code

How to combine this query

In the query
cr is customers,
chh? ise customer_pays,
cari_kod is customer code,
cari_unvan1 is customer name
cha_tarihi is date of pay,
cha_meblag is pay amount
The purpose of query, the get the specisified list of customers and their last date for pay and amount of money...
Actually my manager needs more details but the query is very slow and that is why im using only 3 subquery.
The question is how to combine them ?
I have researched about Cte and "with clause" and "subquery in "where " but without luck.
Can anybody have a proposal.
Operating system is win2003 and sql server version is mssql 2005.
Regards
select cr.cari_kod,cr.cari_unvan1, cr.cari_temsilci_kodu,
(select top 1
chh1.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh1 where chh1.cha_kod=cr.cari_kod order by chh1.cha_RECno) as sontar,
(select top 1
chh2.cha_meblag
from dbo.CARI_HESAP_HAREKETLERI chh2 where chh2.cha_kod=cr.cari_kod order by chh2.cha_RECno) as sontutar
from dbo.CARI_HESAPLAR cr
where (select top 1
chh3.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh3 where chh3.cha_kod=cr.cari_kod order by chh3.cha_RECno) >'20130314'
and
cr.cari_bolge_kodu='322'
or
cr.cari_bolge_kodu='324'
order by cr.cari_kod
You will probably speed up the query by changing your last where clause to:
where (select top 1 chh3.cha_tarihi
from dbo.CARI_HESAP_HAREKETLERI chh3 where chh3.cha_kod=cr.cari_kod
order by chh3.cha_RECno
) >'20130314' and
cr.cari_bolge_kodu in ('322', '324')
order by cr.cari_kod
Assuming that you want both the date condition met and one of the two codes. Your original logic is the (date and code = 322) OR (code = 324).
The overall query can be improved by finding the record in the chh table and then just using that. For this, you want to use the window function row_number(). I think this is the query that you want:
select cari_kod, cari_unvan1, cari_temsilci_kodu,
cha_tarihi, cha_meblag
from (select cr.*, chh.*,
ROW_NUMBER() over (partition by chh.cha_kod order by chh.cha_recno) as seqnum
from dbo.CARI_HESAPLAR cr join
dbo.CARI_HESAP_HAREKETLERI chh
on chh.cha_kod=cr.cari_kod
where cr.cari_bolge_kodu in ('322', '324')
) t
where chh3.cha_tarihi > '20130314' and seqnum = 1
order by cr.cari_kod;
This version assumes the revised logic date/code logic.
The inner subquery select might generate an error if there are two columns with the same name in both tables. If so, then just list the columns instead of using *.