Get Max value for each User in a specific period SQL - sql-server

I have the following query:
I am trying to select for each ACCOUNT_ID in the Table PAYMENT its maximum AMOUNT value.
It gives me a result but I suspect I am missing ACCOUNT_ID rows (I should get more ACCOUNT_ID)
SELECT a.REQUEST_DATE as PartyID, a.AMOUNT
FROM admin_all.PAYMENT a
LEFT OUTER JOIN admin_all.PAYMENT b
ON a.ACCOUNT_ID = b.ACCOUNT_ID AND a.AMOUNT < b.AMOUNT
WHERE b.ACCOUNT_ID IS NULL and a.TYPE='DEPOSIT' and a.STATUS='COMPLETED'
and (a.REQUEST_DATE between '2019-12-01' and '2019-12-17')
Can anybody indicate if my select is correct?

Maybe something like this
SELECT a.ACCOUNT_ID, MAX(a.AMOUNT)
FROM admin_all.PAYMENT a
WHERE a.TYPE='DEPOSIT' and a.STATUS='COMPLETED'
and (a.REQUEST_DATE between '2019-12-01' and '2019-12-17')
GROUP BY a.ACCOUNT_ID

--You can USE ROW_NUMBER() with OVER and PARTITION BY to break up the records
--into numbered rows ordered by the highest AMOUNT (DESC) and partitioned by the ID
--Then grab each record with a ROWNUM = 1
SELECT x.[PartyID], x.[AMOUNT]
FROM
(
SELECT a.REQUEST_DATE as PartyID, a.AMOUNT, ROW_NUMBER() OVER (PARTITION BY a.ACCOUNT_ID ORDER BY a.AMOUNT DESC) AS [RowNum]
FROM admin_all.PAYMENT a
LEFT OUTER JOIN admin_all.PAYMENT b
ON a.ACCOUNT_ID = b.ACCOUNT_ID AND a.AMOUNT < b.AMOUNT
WHERE b.ACCOUNT_ID IS NULL and a.TYPE='DEPOSIT' and a.STATUS='COMPLETED'
and (a.REQUEST_DATE between '2019-12-01' and '2019-12-17')
) AS x
WHERE x.[RowNum] = 1

Related

I need help in using Analytical or Aggregate function in my query

SELECT pid,oid,
item_to_buy AS item_purchase_count
FROM
(SELECT distinct A.pid,A.oid,
B.item_to_buy
//row_number()over(partition by A.oid order by item_to_buy) as RNK
FROM table A
JOIN table B
ON A.product_id=B.product_id
WHERE date='2022-03-03'
AND A.oid IS NOT NULL
AND A.oid=34721248
)
When I run the above query, I'm getting values which I have mentioned below:
PID OID ITEM_PURCHASE_COUNT
93012594908 10021248 NULL
93012594908 10021248 0
93012594908 10021248 1
I want to display only the 3rd row in the result. i.e., The result should look like below:
PID OID ITEM_PURCHASE_COUNT
93012594908 10021248 1
I tried using max, row_number,rank,dense_rank but I didn't get the correct result.
Need guidance on this.
Have you tried a
WHERE item_purchase_count = 1
Or are you trying to say you want the largest. Thus a qualify
QUALIFY row_number() over (partition by pid, oid order by item_purchase_count desc ) = 1
thus:
SELECT
pid,
oid,
item_to_buy AS item_purchase_count
FROM (
SELECT distinct
A.pid,
A.oid,
B.item_to_buy
FROM table A
JOIN table B
ON A.product_id = B.product_id
WHERE date='2022-03-03'
AND A.oid IS NOT NULL
AND A.oid = 34721248
)
QUALIFY row_number() over (partition by pid, oid order by item_purchase_count desc ) = 1
OR actually:
SELECT distinct
A.pid,
A.oid,
B.item_to_buy AS item_purchase_count
FROM table A
JOIN table B
ON A.product_id = B.product_id
WHERE date='2022-03-03'
AND A.oid IS NOT NULL
AND A.oid = 34721248
QUALIFY row_number() over (partition by A.pid, A.oid order by item_purchase_count desc ) = 1
OR if you want to write it in long form:
SELECT
pid,
oid,
item_to_buy AS item_purchase_count
FROM (
SELECT distinct
A.pid,
A.oid,
B.item_to_buy
row_number() over (partition by A.pid, A.oid order by B.item_to_buy desc ) as rnk
FROM table A
JOIN table B
ON A.product_id = B.product_id
WHERE date='2022-03-03'
AND A.oid IS NOT NULL
AND A.oid=34721248
)
WHERE rnk = 1;
helps if you partition the data, cell phones are not the best for writing answers on.. sigh

SQL Simple Join with two tables, but one is random

I am stuck with this. I have a simple set-up with two tables. One table is holding emailaddresses one table is holding vouchercodes. I want to join them in a third table, so that each emailaddress has one random vouchercode.
Unfortunatly I am stuck with this as there are no identic Ids to match both values. What I have so far brings no result:
Select
A.Email
B.CouponCode
FROM Emailaddresses as A
JOIN CouponCodes as B
on A.Email = B.CouponCode
A hint would be great as search did not bring me any further yet.
Edit -
Table A (Addresses)
-------------------
Column A | Column B
-------------------------
email1#gmail.com True
email2#gmail.com
email3#gmail.com True
email4#gmail.com
Table B (Voucher)
-------------------
ABCD1234
ABCD5678
ABCD9876
ABCD5432
Table C
-------------------------
column A | column B
-------------------------
email1#gmail.com ABCD1234
email2#gmail.com ABCD5678
email3#gmail.com ABCD9876
email4#gmail.com ABCD5432
Sample Data:
While joining without proper keys is not a good solution, for your case you can try this. (note: not tested, just a quick suggestion)
;with cte_email as (
select row_number() over (order by Email) as rownum, Email
from Emailaddresses
)
;with cte_coupon as (
select row_number() over (order by CouponCode) as rownum, CouponCode
from CouponCodes
)
select a.Email,b.CouponCode
from cte_email a
join cte_coupon b
on a.rownum = b.rownum
You want to randomly join records, one email with one coupon each. So create random row numbers and join on these:
select
e.email,
c.couponcode
from (select t.*, row_number() over (order by newid()) as rn from emailaddresses t) e
join (select t.*, row_number() over (order by newid()) as rn from CouponCodes t) c
on c.rn = e.rn;
Give a row number for both the tables and join it with row number.
Query
;with cte as(
select [rn] = row_number() over(
order by [Column_A]
), *
from [Table_A]
),
cte2 as(
select [rn] = row_number() over(
order by [Column_A]
), *
from [Table_B]
)
select t1.[Column_A] as [Email_Id], t2.[Column_A] as [Coupon]
from cte t1
join cte2 t2
on t1.rn = t2.rn;
Find a demo here

query is not returning distinct record

Hi can you please take a look why my query is not returning distinct record. i want result with following condition OE1='SCHEDCHNG', need only recent records per orderid or ordernum means only one record per ordernum or orderid and also dropdate is null. My query is as below
select DISTINCT TOP 100 OE.ORDERID,OE.ID,OE.ORDERNUM,OE.OE4 from OrderExports OE
inner join (
select ORDERNUM, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm
on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG' AND O.DROPDATE is null
Pretty sparse on details here but I think you are wanting something along these lines.
with SortedResults as
(
select OE.ORDERID
, OE.ID
, OE.ORDERNUM
, OE.OE4
, ROW_NUMBER() over(partition by OE.ORDERID, OE.ORDERNUM order by OE.OE4 desc) as RowNum
from OrderExports OE
inner join
(
select ORDERNUM
, max(OE4) as MaxDate
from OrderExports
group by ORDERNUM
) tm on OE.ORDERNUM = tm.ORDERNUM and OE.OE4 = tm.MaxDate
inner join orde_ O on OE.ORDERID = O.ORDERID
WHERE OE1='SCHEDCHNG'
AND O.DROPDATE is null
)
select ORDERID
, ID
, ORDERNUM
, OE4
from SortedResults
where RowNum = 1
You can try using max and group by as below :
SELECT a.ID, max(a.ORDERID) as OrderID, max(a.ORDERNUM) as OrderNum,MAX(OE.OE4) as OE4 FROM
(
--your query
) a
group by a.ID

Group by customer name

Demo
SELECT ROW_NUMBER() OVER (ORDER BY Visit_Date DESC,P_Master.P_Name ASC) AS RowNumber,
P_Master.P_Name,
(SELECT MAX(Visit_Date) FROM P_Visit v WHERE v.PID = p_Master.PID) as Visit_Date
FROM P_Master
LEFT JOIN P_VISIT
ON P_Master.PID=P_VISIT.PID
WHERE P_Master.P_Name LIKE 'j%'
I have to show max date of column Visit_Date if i search on '2013-10-29' then record shows those customers have date '2013-10-29' in coloumn i have to shown max date of customer
all its working fine but How to make group by PID(I have to show only one record for the given search )
Please try below query, it will also help in pagination
SELECT ROW_NUMBER() OVER (ORDER BY Visit_Date DESC,P_Name ASC) AS RowNumber, *
FROM (SELECT DISTINCT P_Master.P_Name,
(SELECT MAX(Visit_Date) FROM P_Visit v WHERE v.PID = p_Master.PID) as Visit_Date
FROM P_Master
LEFT JOIN P_VISIT
ON P_Master.PID=P_VISIT.PID
WHERE P_Master.P_Name LIKE 'j%') tbl
This will work:
SELECT DISTINCT
P_Master.P_Name,
(SELECT MAX(Visit_Date) FROM P_Visit v WHERE v.PID = p_Master.PID) as Visit_Date
FROM P_Master
LEFT JOIN P_VISIT
ON P_Master.PID=P_VISIT.PID
WHERE P_Master.P_Name LIKE 'j%'

RANK() Over Partition BY not working

When I run the code below the ROWID is always 1.
I need to the ID to start at 1 for each item with the same Credit Value.
;WITH CTETotal AS (SELECT
TranRegion
,TranCustomer
,TranDocNo
,SUM(TranSale) 'CreditValue'
FROM dbo.Transactions
LEFT JOIN customers AS C
ON custregion = tranregion
AND custnumber = trancustomer
LEFT JOIN products AS P
ON prodcode = tranprodcode
GROUP BY
TranRegion
,TranCustomer
,TranDocNo)
SELECT
r.RegionDesc
,suppcodedesc
,t.tranreason as [Reason]
,t.trandocno as [Document Number]
,sum(tranqty) as Qty
,sum(tranmass) as Mass
,sum(transale) as Sale
,cte.CreditValue AS 'Credit Value'
,RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.CreditValue)AS ROWID
FROM transactions t
LEFT JOIN dbo.Regions AS r
ON r.RegionCode = TranRegion
LEFT JOIN CTETotal AS cte
ON cte.TranRegion = t.TranRegion
AND cte.TranCustomer = t.TranCustomer
AND cte.TranDocNo = t.TranDocNo
GROUP BY
r.RegionDesc
,suppcodedesc
,t.tranreason
,t.trandocno
,cte.CreditValue
ORDER BY CreditValue ASC
EDIT
All the credit values with 400 must have the ROWID set to 1. And all the credit values with 200 must have the ROWID set to 2. And so on and so on.
Do you need something like this?
with cte (item,CreditValue)
as
(
select 'a',8 as CreditValue union all
select 'b',18 union all
select 'a',8 union all
select 'b',18 union all
select 'a',8
)
select CreditValue,dense_rank() OVER (ORDER BY item)AS ROWID from cte
Result
CreditValue ROWID
----------- --------------------
8 1
8 1
8 1
18 2
18 2
In your code replace
,RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.CreditValue)AS ROWID
by
,DENSE_RANK() OVER (ORDER BY cte.CreditValue)AS ROWID
You just don't have to use PARTITION, just DENSE_RANK() OVER (ORDER BY cte.CreditValue)
I think the problem is with the RANK() OVER (PARTITION BY clause
you have to partition it by item not by CreditValue
Try this
RANK() OVER (PARTITION BY cte.CreditValue ORDER BY cte.RegionDesc)AS ROWID
Edit: The issue here isn't actually the nesting of the subquery, it's potentially based on partition by having columns that truly make each row unique (or 1)
Rather than ranking within your complex query like this
select
rank() over(partition by...),
*
from
data_source
join table1
join table2
join table3
join table4
order by
some_column
Try rank() or row_number() on the resulting data set, not within it.
For example, using the query above, remove rank() and implement it this way:
select
rank() over(partition by...),
results.*
from (
select
*
from
data_source
join table1
join table2
join table3
join table4
order by
some_column
) as results

Resources