SQL query last transactions - sql

You can't see on the image but I have many till_id numbers. (1,2,3,4,5).
What I want to do is just showing the last "trans_num" without repeating the till_id.
For example:
till_id trans_num
1 14211
2 14333
3 14555

A typical way to do this is:
select t.*
from t
where t.trans_date = (select max(t2.trans_date)
from t t2
where t2.till_id = t.till_id
);

select till_id ,trans_num, max(transdate) from tableA
group by till_id ,trans_num
Filter the columns you need in outer query or write inner query in where condition

You can use group by till_id in subselect
Select a.till_id a.trans_num
from your_table as a
where (a.trans_date. a.till_id) = (select max(b.trans_date), b-till_id
from your_table as b
group_by b.till_id
);

Related

SQL Oracle Find Max of count

I have this table called item:
| PERSON_id | ITEM_id |
|------------------|----------------|
|------CP2---------|-----A03--------|
|------CP2---------|-----A02--------|
|------HB3---------|-----A02--------|
|------BW4---------|-----A01--------|
I need an SQL statement that would output the person with the most Items. Not really sure where to start either.
I advice you to use inner query for this purpose. the inner query is going to include group by and order by statement. and outer query will select the first statement which has the most items.
SELECT * FROM
(
SELECT PERSON_ID, COUNT(*) FROM TABLE1
GROUP BY PERSON_ID
ORDER BY 2 DESC
)
WHERE ROWNUM = 1
here is the fiddler link : http://sqlfiddle.com/#!4/4c4228/5
Locating the maximum of an aggregated column requires more than a single calculation, so here you can use a "common table expression" (cte) to hold the result and then re-use that result in a where clause:
with cte as (
select
person_id
, count(item_id) count_items
from mytable
group by
person_id
)
select
*
from cte
where count_items = (select max(count_items) from cte)
Note, if more than one person shares the same maximum count; more than one row will be returned bu this query.

SQL ACCESS - select max(date) and corresponding value

How can I get the corresponding value of MAX(date).
Access it returns me an error when I select directly the column with the specified value.
For example, I want to be shown only the line from the image.
Thank you.
Use TOP and ORDER BY:
select top 1 *
from t
order by date desc;
EDIT:
If you want the last date per code, then use a correlated subquery:
select t.*
from t
where t.date = (select max(t2.date) from t t2 where t2.code = t.code);
select * from tblName where DocumentDate in (select max(DocumentDate ) from tblName)
Please use this
If you need last date per code then try this one
SELECT Code, MAX(DocumentDate)
FROM table
GROUP BY Code
You mast creat the join query. For example find MAX(DocumentDate):
SELECT DocumentNumber, Code, SoldPuncte, DocumentDate
from yourTable a inner join
(SELECT DocumentNumber, Code, SoldPuncte, MAX(DocumentDate) as
DocumentDate
from yourTable group by DocumentNumber) b
on a.DocumentNumber=b.DocumentNumber and a.DocumentDate = b.DocumentDate

Select a NON-DISTINCT column in a query that return distincts rows

The following query returns the results that I need but I have to add the ID of the row to then update it. If I add the ID directly in the select statement it will return me more results then I need because each ID is unique so the DISTINCT statement see the line as unique.
SELECT DISTINCT ucpse.MemberID, ucpse.ProductID, ucpse.UserID
FROM UserCustomerProductSalaryExceptions as ucpse
WHERE EXISTS (SELECT NULL
FROM UserCustomerProductSalaryExceptions as upcse2
WHERE ucpse.userid = upcse2.userid AND ucpse.MemberID = upcse2.MemberID AND ucpse.ProductID = upcse2.ProductID
GROUP BY upcse2.UserID, upcse2.memberid, upcse2.productid
HAVING COUNT(UserID) >= 2
)
So basically I need to add ucpse.ID in the Select statement while keeping DISTINCT values for MemberID,ProductID and UserID.
Any Ideas ?
Thank you
According to you comment:
If the data has been duplicated 67 times for a given employee with a given product and a given client, I need to keep only one of thoses records. It's not important which one, so this is why I use DISTINC to obtain unique combinaison of given employee with a given product and a given client.
You can use MIN() or MAX() and GROUP BY instead of DISTINCT
SELECT MAX(ucpse.ID) AS ID, ucpse.MemberID, ucpse.ProductID, ucpse.UserID
FROM UserCustomerProductSalaryExceptions as ucpse
WHERE EXISTS (SELECT NULL
FROM UserCustomerProductSalaryExceptions as upcse2
WHERE ucpse.userid = upcse2.userid AND ucpse.MemberID = upcse2.MemberID AND ucpse.ProductID = upcse2.ProductID
GROUP BY upcse2.UserID, upcse2.memberid, upcse2.productid
HAVING COUNT(UserID) >= 2
)
GROUP BY ucpse.MemberID, ucpse.ProductID, ucpse.UserID
UPDATE:
From you comments I think the below query is what you need
DELETE FROM UserCustomerProductSalaryExceptions
WHERE ID NOT IN ( SELECT MAX(ucpse.ID) AS ID
FROM #UserCustomerProductSalaryExceptions
GROUP BY ucpse.MemberID, ucpse.ProductID, ucpse.UserID
HAVING COUNT(ucpse.ID) >= 2
)
If all you want is to delete the duplicates, this will do it:
WITH X AS
(SELECT ID,
ROW_NUMBER() OVER (PARTITION BY MemberID, ProductID, UserID ORDER BY ID) AS DupRowNum<br
FROM UserCustomerProductSalaryExceptions
)
DELETE X WHERE DupRowNum > 1
ID's not necessary - try:
UPDATE uu SET
<your settings here>
FROM UserCustomerProductSalaryExceptions uu
JOIN ( <paste your entire query above here>
) uc ON uc.MemberID=uu.MemberId AND uc.ProductID=uu.ProductId AND uc.UserID=uu.UserId
From the sound of your data structure (which I would STRONGLY advise normalizing as soon as possible), it sounds like you should be updating all the records. It sounds as if each duplicate is important because it contains some information about an employee's relation to a customer or product.
I would probably update all the records. Try this:
UPDATE UCPSE
SET
--Do your updates here
FROM UserCustomerProductSalaryExceptions as ucpse
JOIN
(
SELECT UserID, MemberID, ProductID
FROM UserCustomerProductSalaryExceptions
GROUP BY UserID, MemberID, ProductID
HAVING COUNT(UserID) >= 2
) T
ON ucpse.UserID = T.UserID AND ucpse.MemberID = T.MemberID AND ucpse.ProductID = T.ProductID

Ensuring only distinct records are returned with DISTINCT

Given the following table:
date_field_one date_field_two arbitrary_value
---------------- ---------------- -----------------
1/1/11 1/3/11 cheese
1/1/11 1/4/11 the color orange
2/2/11 2/3/11 1
2/2/11 2/4/11 2
My problem: I'm not sure how to go about structuring a query using a set based approach that yields the following results:
for each distinct date, the record with the earliest
date_field_two value is returned
Any ideas?
Edit for new response! The solution posted by M.Ali may be the best fit for your specific case as it will ensure you only ever get one row result from your base data, even if there exist multiple candidate rows for your answer ( as in, date_field_one, date_field_two combinations are not distinct ). The following will return multiple results per date_field_one, date_field_two combination in the not-distinct scenario:
SELECT t.date_field_one, t.date_field_two, t.arbitrary_value
FROM ( SELECT date_field_one,
date_field_two = MIN( date_field_two )
FROM dbo.[table]
GROUP BY date_field_one ) dl
LEFT JOIN dbo.[table] t
ON dl.date_field_one = t.date_field_one
AND dl.date_field_two = t.date_field_two;
;WITH CTE
AS
(
SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY date_field_one ORDER BY date_field_two
ASC)
FROM TableName
)
SELECT * FROM CTE
WHERE rn = 1
Something like this:
select date_field_one, min(date_field_two)
from yourtable
group by date_field_one
select date_field_one, min(date_fileld_two)
from table
group by date_field_one
try this for latest...........
select date_field_one ,min(date_field_two) date_field_two
from table group by date_field_one

Finding non distinct rows

Assuming the following structure, I need to find if there are cases where there's more than one DESC for each CP4+CP3 combination. I need only to know if they exist. Not where they are.
CP4, integer
CP3, integer
DESC, varchar(50)
You can check using a self join: if the following query returns any rows, there's more than one DESC for a CP4+CP3 combination:
select *
from YourTable a
inner join YourTable b
on a.CP3 = b.CP3
and a.CP4 = b.CP4
and a.DESC <> b.DESC
A group by would work too:
select count(*)
from YourTable
group by CP3, CP4
having count(distinct DESC) > 1
By the way, DESC is a SQL keyword; you might have to escape it in a way specific to your database.
SELECT COUNT(DESC)
FROM [Table]
GROUP BY CP4, CP3
HAVING COUNT(DESC) > 1
Check if this query returns more than 0 rows then true, else false.