Reputation: 1495
I want to get the row with maximum Transaction number Grouped on the basis of Code
.
CREATE TABLE SaleOrder
(
TransactionNo Int,
SaleOrderDate DATE,
Code VARCHAR(25),
Quantity INT,
TotalAmount Numeric(18,2),
Remarks VARCHAR(25)
)
INSERT INTO SaleOrder VALUES (NULL, '2018-10-01', 'SO-001-OCT-18', 6, 2500, 'Hello');
INSERT INTO SaleOrder VALUES (1, '2018-10-01', 'SO-001-OCT-18', 8, 2600, 'Hello');
INSERT INTO SaleOrder VALUES (2, '2018-10-01', 'SO-001-OCT-18', 12, 3400, 'Hello');
INSERT INTO SaleOrder VALUES (3, '2018-10-01', 'SO-001-OCT-18', 9, 2900, 'Hello');
INSERT INTO SaleOrder VALUES (4, '2018-10-01', 'SO-001-OCT-18', 2, 900, 'Hello');
INSERT INTO SaleOrder VALUES (NULL, '2018-10-01', 'SO-002-OCT-18', 6, 2500, 'Hello');
INSERT INTO SaleOrder VALUES (NULL, '2018-10-01', 'SO-003-OCT-18', 6, 2500, 'Hello');
INSERT INTO SaleOrder VALUES (0, '2018-10-01', 'SO-004-OCT-18', 6, 2500, 'Hello');
SELECT * FROM SaleOrder O
WHERE TransactionNo = (SELECT MAX(ISNULL(TransactionNo, 1)) FROM SaleOrder GROUP BY Code)
Here when TransactionNo is NULL it's not returning any record against it while it should return that too.
Upvotes: 2
Views: 117
Reputation: 272406
There is absolutely no reason to treat NULL as largest possible value. You can always use the ROW_NUMBER
trick:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Code ORDER BY TransactionNo DESC) AS RN
FROM SaleOrder
)
SELECT * FROM cte
WHERE RN = 1
Result:
| TransactionNo | SaleOrderDate | Code | Quantity | TotalAmount | Remarks | RN |
|---------------|---------------|---------------|----------|-------------|---------|----|
| 4 | 2018-10-01 | SO-001-OCT-18 | 2 | 900.00 | Hello | 1 |
| NULL | 2018-10-01 | SO-002-OCT-18 | 6 | 2500.00 | Hello | 1 |
| NULL | 2018-10-01 | SO-003-OCT-18 | 6 | 2500.00 | Hello | 1 |
| 0 | 2018-10-01 | SO-004-OCT-18 | 6 | 2500.00 | Hello | 1 |
Upvotes: 3
Reputation: 1864
Below code will give you much more info than you requested, you can play with it, add some comment if have any questions.
CREATE TABLE #SaleOrder
(
TransactionNo Int,
#SaleOrderDate DATE,
Code VARCHAR(25),
Quantity INT,
TotalAmount Numeric(18,2),
Remarks VARCHAR(25)
)
INSERT INTO #SaleOrder VALUES (NULL, '2018-10-01', 'SO-001-OCT-18', 6, '2500', 'Hello');
INSERT INTO #SaleOrder VALUES (1, '2018-10-01', 'SO-001-OCT-18', 8, '2600', 'Hello');
INSERT INTO #SaleOrder VALUES (2, '2018-10-01', 'SO-001-OCT-18', 12, '3400', 'Hello');
INSERT INTO #SaleOrder VALUES (3, '2018-10-01', 'SO-001-OCT-18', 9, '2900', 'Hello');
INSERT INTO #SaleOrder VALUES (4, '2018-10-01', 'SO-001-OCT-18', 2, '900', 'Hello');
INSERT INTO #SaleOrder VALUES (NULL, '2018-10-01', 'SO-002-OCT-18', 6, '2500', 'Hello');
INSERT INTO #SaleOrder VALUES (NULL, '2018-10-01', 'SO-003-OCT-18', 6, '2500', 'Hello');
INSERT INTO #SaleOrder VALUES (0, '2018-10-01', 'SO-004-OCT-18', 6, '2500', 'Hello');
-- final select
SELECT top 1 -- optional, if you want to return 1 record
Code,
sum(Quantity) as totalQuantity,
sum(TotalAmount) as totallAmount,
count(1) as totalOrdersPerCode
FROM #SaleOrder O
group by Code
order by count(1) desc
-- drop temp table
drop table #SaleOrder
Upvotes: 0
Reputation: 37500
Try this:
select TransactionNo,SaleOrderDate,Code,Quantity,TotalAmount,Remarks from (
select TransactionNo,SaleOrderDate,Code,Quantity,TotalAmount,Remarks,
row_number() over (partition by code order by transactionno desc) rn
from (
select TransactionNo,SaleOrderDate,Code,Quantity,TotalAmount,Remarks,
coalesce(transactionno, count(*) over (partition by code) + 1) transactionno2
from SaleOrder
) a
) a where rn = 1
Explanation:
With this line coalesce(transactionno, count(*) over (partition by code) + 1) transactionno2
I assign greatest value per group (partitioned by code
) where it's null. But be aware when you have two NULL
s, rows will be tied in this case and it would be non-deterministic.
Upvotes: 0
Reputation: 5656
I think this ISNULL
check should solve your problem and replace =
with IN
subquery can return multiple records
WHERE ISNULL(TransactionNo, 1) IN
Upvotes: 0
Reputation: 1243
when you use = select in your where clause its totally wrong because this is possible you have multiple records,so you have to change your code like this:
SELECT MAX(ISNULL(TransactionNo, 1)),code FROM SaleOrder O
GROUP BY Code
but if you want to return only one record you can use it like this:
SELECT * FROM SaleOrder O
WHERE TransactionNo = (SELECT TOP 1 MAX(ISNULL(NULL, 1)) FROM SaleOrder GROUP BY Code)
Upvotes: 0
Reputation: 155
When TransactionNo is NULL and query returns more than one row that could not assigned to the filter
The below may help
SELECT * FROM SaleOrder O
WHERE TransactionNo = (SELECT TOP 1 MAX(ISNULL(NULL, 1)) FROM SaleOrder GROUP BY Code)
Note that this could take any record with TransactionNo having a NULL value. Segregating the logic for TransactionNo filter would be easier to extend and maintain. Example below:
DECLARE @TransactionNo int
SELECT TOP 1 @TransactionNo = MAX(ISNULL(TransactionNo, 1)) FROM SaleOrder GROUP BY Code -- (OR) Logic here
SELECT * FROM SaleOrder O
WHERE TransactionNo = @TransactionNo
Upvotes: 0