我有一个订购产品的历史表
+----+------------+--------+
| id | IdProduct | status |
+----+------------+--------+
| 1 | 100 | 1 |
| 2 | 100 | 2 |
| 3 | 100 | 3 |
| | | |
| 4 | 200 | 1 |
| 5 | 200 | 2 |
| | | |
| 6 | 300 | 1 |
| 7 | 300 | 2 |
+----+------------+--------+
我想只获取状态为2
但不是3
的产品
+----+------------+
| id | IdProduct |
+----+------------+
| 5 | 200 |
| | |
| 7 | 300 |
+----+------------+
如何使用Linq请求实现此目的
答案 0 :(得分:2)
我没有看到问题的最后一行如何使用Linq请求实现此目的可能是downvote的原因..
如果有人希望在SQL
以下是使用Group by
和Having
子句
SELECT *
FROM yourtable
WHERE IdProduct IN (SELECT IdProduct
FROM Yourtable
GROUP BY IdProduct
HAVING Count(CASE WHEN status = 3 THEN 1 END) = 0
AND Count(CASE WHEN status = 2 THEN 1 END) > 0)
AND Status = 2
Count(CASE WHEN status = 3 THEN 1 END) = 0
此条件是为了确保每个status = 3
ID
不存在任何行
Count(CASE WHEN status = 2 THEN 1 END) > 0
这个条件是为每个status = 2
ID
答案 1 :(得分:2)
使用linq to sql可以:
var result = history.GroupBy(item => item.IdProduct)
.Where(grp => grp.Any(item => item.Status == 2) &&
!grp.Any(item => item.Status == 3))
.Select(grp => new {
IdProduct = grp.Key,
Id = grp.Max(item => item.Id)
});
或者:
var result = history.GroupBy(item => item.IdProduct)
.Where(grp => grp.Any(item => item.Status == 2) &&
!grp.Any(item => item.Status == 3))
.Select(grp => grp.Where(item => ite.Status == 2).FirstOrDefault());
在你的情况下,这两个都应该返回相同,因为max(id)与你想要的结果相关
如果您知道每个状态只存在一次,那么您可以尝试以下操作。想法是状态3项等于-1,2等于1,其余为0.只有状态为2但不是3的组将具有1的结果
var result = history.Select(item => new { Item = item, Valid = item.Status == 2 ? 1 : item.Status == 3 ? -1 : 0 })
.GroupBy(item => item.Item.IdProduct)
.Where(grp => grp.Sum(item => item.Valid) == 1)
.Select(item => item.Item);
答案 2 :(得分:1)
Declare @YourTable table (id int,IdProduct int,status int)
Insert Into @YourTable values
( 1 , 100 , 1 ),
( 2 , 100 , 2 ),
( 3 , 100 , 3 ),
( 4 , 200 , 1 ),
( 5 , 200 , 2 ),
( 6 , 300 , 1 ),
( 7 , 300 , 2 )
Select Id,IdProduct
From (
Select Id
,IdProduct
,MaxStatus = max(Status) over (Partition By IdProduct)
From @YourTable
Where Status in (2,3)
) A
Where MaxStatus = 2
返回
Id IdProduct
5 200
7 300