我想获得具有基于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)
在这里,当TransactionNo为NULL时,它不返回任何记录,而它也应该返回该记录。
答案 0 :(得分:3)
绝对没有理由将NULL视为最大可能值。您可以随时使用ROW_NUMBER
技巧:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Code ORDER BY TransactionNo DESC) AS RN
FROM SaleOrder
)
SELECT * FROM cte
WHERE RN = 1
结果:
| 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 |
答案 1 :(得分:0)
当TransactionNo为NULL且查询返回无法分配给过滤器的多行
以下内容可能会帮助
SELECT * FROM SaleOrder O
WHERE TransactionNo = (SELECT TOP 1 MAX(ISNULL(NULL, 1)) FROM SaleOrder GROUP BY Code)
请注意,这可以记录任何TransactionNo值为NULL的记录。 隔离TransactionNo过滤器的逻辑将更易于扩展和维护。下面的示例:
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
答案 2 :(得分:0)
在使用=时,在where子句中选择它是完全错误的,因为这可能有多个记录,因此您必须像这样更改代码:
SELECT MAX(ISNULL(TransactionNo, 1)),code FROM SaleOrder O
GROUP BY Code
但是如果您只想返回一条记录,则可以这样使用它:
SELECT * FROM SaleOrder O
WHERE TransactionNo = (SELECT TOP 1 MAX(ISNULL(NULL, 1)) FROM SaleOrder GROUP BY Code)
答案 3 :(得分:0)
我认为此ISNULL
检查应该可以解决您的问题,并用=
子查询替换IN
可以返回多个记录
WHERE ISNULL(TransactionNo, 1) IN
答案 4 :(得分:0)
尝试一下:
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
说明:
在这一行coalesce(transactionno, count(*) over (partition by code) + 1) transactionno2
中,我为每个组(由code
划分)分配了最大值,其中为空。 但是请注意,当您有两个NULL
时,在这种情况下,行将被绑在一起,并且会不确定性。
答案 5 :(得分:0)
下面的代码将为您提供比您想要的信息更多的信息,您可以使用它,并在有任何疑问时添加一些注释。
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