我的要求是获取SiteItemOnHand记录,按Businessunitid,inventoryitemid分组,并获取每个具有max(lastmodifiedtimestamp)的组中的整个SiteItemOnHand记录
我正在尝试为以下SQL查询编写nhibernate等效查询
Select x.* from
(
Select businessunitid,inventoryitemid,max(lastmodifiedtimestamp) as maxvalue from InventoryItemBUOnHand
group by businessunitid,inventoryitemid HAVING inventoryitemid in (939) and businessunitid=829
) as x
inner join
(
Select businessunitid,inventoryitemid,lastmodifiedtimestamp,inventoryitemonhandid from InventoryItemBUOnHand
where inventoryitemid in (939) and businessunitid=829
) as y
on x.businessunitid=y.businessunitid and x.inventoryitemid =y.inventoryitemid and x.maxvalue=y.lastmodifiedtimestamp
我有很多限制。我只允许使用Nhibernate 3.0版本,并且严格禁止编写sql查询(条件)。 我只能写下面的查询的一半。任何帮助,将不胜感激。
var query= _session.QueryOver<SiteItemOnHand>()
.Where(x => x.Businessunitid == siteID)
.Where(x => x.End == endDate)
.Where(x => x.CountID != filterCount.ID)
.WhereRestrictionOn(x => x.ItemID).IsIn(itemIdList.ToArray())
.SelectList(list => list
.SelectMax(x => x.LastModifiedTimestamp)
.SelectGroup(x => x.Businessunitid)
.SelectGroup(x => x.ItemId));
上面的查询正在生成下面的SQL查询,该查询仅返回三列,但是我需要整个记录,因为检索记录后我需要更新。我需要获取满足上述查询的所有SiteItemOnHand记录。
SELECT max(this_.lastmodifiedtimestamp) as y0_, this_.businessunitid as y1_, this_.inventoryitemid as y2_
FROM InventoryItemBUOnHand this_
WHERE this_.businessunitid = 567 and this_.enddate = '1/31/2019 1:18:17 AM' and not (this_.itemcountid = 958)
and this_.inventoryitemid in (744,755)
GROUP BY this_.businessunitid, this_.inventoryitemid
任何帮助将不胜感激。如果需要更多信息,请告诉我。
答案 0 :(得分:0)
如果我对您的理解正确,那么您就有类似的数据,并且需要标记的记录。我不知道iventoryitemonhandid
是否是表的id
,所以我不依赖它。
Table InventoryItemBUOnHand (mapped as SiteItemOnHand)
| businessunitid|inventoryitemid|lastmodifiedtimestamp|inventoryitemonhandid|
| 829| 939| 2019-01-01 00:00:00| 100| <--
| 829| 940| 2019-01-02 00:00:00| 101|
| 829| 940| 2019-01-03 00:00:00| 102| <--
| 829| 950| 2019-01-04 00:00:00| 103|
| 829| 950| 2019-01-10 00:00:00| 104| <--
| 829| 950| 2019-01-06 00:00:00| 105|
如果是,那么我将使用类似于此问题的SubQuery: SO: NHibernate - Select full records from aggregates
根据您的要求进行了修改(未经测试),看起来像这样:
int siteID = 829;
List<int> itemIdList = new List<int>() { 939, 940, 950 };
SiteItemOnHand siAlias = null;
var subQuery = QueryOver.Of<SiteItemOnHand>()
.Where(x => x.Businessunitid == siAlias.Businessunitid)
.And(x => x.ItemID == siAlias.ItemID)
.Select(Projections.Max<SiteItemOnHand>(y => y.lastmodifiedtimestamp));
var siteItems = Session.QueryOver<SiteItemOnHand>(() => siAlias)
.Where(x => x.Businessunitid == siteID)
.AndRestrictionOn(x => x.ItemID).IsIn(itemIdList.ToArray())
.WithSubquery.Where(x => siAlias.lastmodifiedtimestamp == subQuery.As<DateTime>())
.List();
这里的目标是使用子查询来过滤每个组的正确最大日期,然后使用它来过滤实际记录。
生成的SQL如下所示:
SELECT <field_list> FROM InventoryItemBUOnHand
WHERE Businessunitid = 829
AND inventoryitemid in (939, 940, 950)
AND this_.lastmodifiedtimestamp =
(SELECT max(this_0_.lastmodifiedtimestamp) as y0_
FROM InventoryItemBUOnHand this_0_
WHERE this_0_.Businessunitid = this_.Businessunitid and this_0_.ItemID = this_.ItemID)
警告::如果两个记录对于相同的lastmodifiedtimestamp
和businessunitid
具有相同的值,则比较inventoryitemid
可能会导致不良结果。如果发生这种情况,您可以添加OrderBy
并仅选择第一条记录。如果inventoryitemonhandid
是唯一索引,它将变得更加简单。