我有一个SQL查询,我在创建使用NHibernate Criteria时遇到了麻烦:
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT ID FROM (SELECT MAX(ID) as ID, COLA FROM table WHERE COLB='something' GROUP BY COLA) subquery)
ORDER BY ID DESC
我最初有一个稍微简单的查询:
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT MAX(ID) FROM table WHERE COLB='something' GROUP BY COLA)
ORDER BY ID DESC
但是,对于NHibernate,如果我使用“GROUP BY”,它会自动将字段添加到SELECT语句中,而我无法阻止它(据我所知)。
基本上,我需要找到按任意列分组的最新记录(在本例中为“COLA”)。我正在选择最大ID以尝试获取最新记录(尽管这可能是其他内容,例如“MAX(UPDATED)”)。获取最新记录集后,我将进一步过滤它们(“WHERE COLC ='something'”),并在结果中选择我需要的列。
如果有更好的方法可以获得相同的结果,我会很高兴听到它。我的SQL技能充其量只是平庸。
在NHibernate中,我可以正确地获得两个查询,但是中间的那个 - “SELECT ID FROM”将不起作用。
主要查询:
DetachedCriteria.For<table>()
.Add<table>(x => x.COLC == "something")
.Add(LambdaSubquery.Property<table>(x => x.ID).In(subquery));
子查询:
DetachedCriteria.For<table>()
.Add<table>(x => x.COLB == "something")
.SetProjection(Projections.ProjectionList()
.Add(LambdaProjection.Max<table>(x => x.ID))
.Add(LambdaProjection.GroupProperty<table>(x => x.COLA)));
子查询标准将“COLA”放在选择列表中(因为GroupProperty),因此它本身无法使用,这就是我需要弄清楚如何进行“SELECT ID FROM(SELECT ...”)的原因。在组合中,它们会产生以下无效的SQL(因为子查询返回多个列):
SELECT ID, COLA, COLB, COLC
FROM table
WHERE COLC='something' AND ID IN (SELECT MAX(ID), COLA FROM table WHERE COLB='something' GROUP BY COLA)
ORDER BY ID DESC
编辑:查看我想要的数据和结果可能也会有所帮助:
ID COLA COLB COLC
1 1 someone someother
2 1 something someone (Matches subquery, but not the max. ID)
3 1 something something (Matches subquery and main query)
4 2 someone something
5 2 something someother (Only matches subquery)
6 3 someone someother
我想要的结果是给定的一组“COLA”的最大ID,其中“COLB”匹配“某事”,所以我希望子查询返回{3,5}。最后,查询只会返回ID 3的记录(外部WHERE子句除掉5,因为COLC是错误的)。 COLB和COLC中的实际数据无关紧要 - 我只是用它来进一步过滤结果。
我认为,在它的核心,我想要每组COLA的最新记录(最大ID)
SELECT ID, COLA, COLB
FROM table
WHERE ID IN (SELECT MAX(ID) FROM table GROUP BY COLA)
ORDER BY ID DESC
答案 0 :(得分:2)
因此,假设您正在寻找具有最大ID和COLA值的记录,并且其中包含相应MAX ID的COLB,您可以使用类似的内容。
var test =
ActiveRecordLinq.AsQueryable<table>().Where(
y =>
y.COLB == "Something" &&
y.ID == (from x in ActiveRecordLinq.AsQueryable<table>()
where x.COLA == "Something"
select x).Max(z => z.ID))
我尝试使用我的一些对象和测试数据,它似乎工作。让我知道它是怎么回事。
修改强>
对于COLA的最大ID列表,您可以使用此查询。首先,我将向您展示我用于测试的那个,然后你的应该是什么样的。
我有一个电子邮件组对象,其中包含标题和TXDX对象,该对象具有我正在搜索的ID。
var maxes = (from x in ActiveRecordLinq.AsQueryable<Email_Group>()
group x by x.Headline
into g
select new {COLA = g.Key, MaxID = g.Max(z => z.TXDX.TXDX_ID)});
此致:
var maxes = (from x in ActiveRecordLinq.AsQueryable<table>()
group x by x.COLA
into g
select new {COLA = g.Key, MaxID = g.Max(z => z.ID)});
我还在处理整个查询。试着在一个电话中完成它。一旦我得到它,我会发布,但它是星期五,我在工作之间这样做。
答案 1 :(得分:2)
我找到了另一种解决方案,因为我无法弄清楚如何使用NHibernate中的条件API获得正确的结果 - 请改用视图。
视图只使用我原先想要的查询(没有一些额外的过滤):
SELECT ID, COLA, COLB, COLC, ...
FROM table
WHERE ID IN
(SELECT MAX(ID)
FROM table
GROUP BY COLA)
然后,在NHibernate中,我将视图映射为常规表(除了我使其不可变):
<class name="View" table="View" lazy="false" mutable="false">
<id name="ID" type="Int32">
<generator class="assigned"/>
</id>
<property name="COLA" type="String" length="100">
<column name="COLA" />
</property>
<property name="COLB" type="String" length="100">
<column name="COLB" />
</property>
<property name="COLC" type="String" length="100">
<column name="COLC" />
</property>
<!-- Other fields -->
</class>
创建了要映射到的类:
public class View
{
public virtual int ID { get; set; }
public virtual string COLA { get; set; }
public virtual string COLB { get; set; }
public virtual string COLC { get; set; }
// Other fields
}
最后,为视图创建了一个查询:
DetachedCriteria.For<View>()
.Add<View>(x => x.COLB == "something")
.Add<View>(x => x.COLC == "something")
// Any other filtering criteria
.AddOrder<View>(x => x.COLA, Order.Desc);
我宁愿在NHibernate中使用单个条件查询,但这完成了工作。