way to map the following to a Dictionary??
Sql sql = new Sql()
.Append("SELECT Count(*) ")
.Append("FROM Custumers")
.Append("WHERE CustomerId = #0", Id)
var result = database.Fetch<Dictionary<int,DateTime>>(sql);
I cannot use List as DateTime is also thr.
Petapoco always return a List<T>, but you can convert the List to a Dictionary afterwards:
var result = database
.Fetch<Pair<int,DateTime>>(sql)
.ToDictionary(i => i.ID, i => i.Date);
With NPoco you can write this: it will use the first 2 columns
var result = database.Dictionary<int, DateTime>(sql);
or use what #Eduardo said.
Related
I have the following query trying to get count of a query:
var testQuery = Db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Where(x => x.IsDeleted == false)
.OrderBy(x => x.ConvertedPrice);
var testCount = Db.Scalar<int>(testQuery.Select<Blog>(x => Sql.CountDistinct(x.Id)));
var results = Db.LoadSelect(testQuery.SelectDistinct());
It gives error:
42803: column "blog.converted_price" must appear in the GROUP BY clause or be used in an aggregate function
Issue seems to be the orderby statement. If I remove it then the error goes away. Why does this stop count distinct working?
I am having to clear orderby on all queries I do like this. Is it supposed to work this way?
Also I just realised count is wrong. Results is 501 unique records and testCount is 538.
What am I doing wrong?
Whenever in doubt with what an OrmLite query is generating, you can use the BeforeExecFilter to inspect the DB command before its executed or to just output the query to the Console you can use:
OrmLiteUtils.PrintSql();
You shouldn't be using OrderBy with aggregate scalar functions like COUNT which is meaningless and will fail in your case because it needs to included the GROUP BY clause for joined table queries.
Your specifically querying for COUNT(DISTINCT Id) if you wanted the row count for the query you can instead use:
var testCount = Db.RowCount(testQuery);
If you wanted to use COUNT(*) instead, you can use:
var testCount = Db.Count(testQuery);
I am trying to make this query in OrmLite:
select b.* from blog b
join blog_to_blog_category btbc on b.id = btbc.blog_id
join blog_category bc on btbc.blog_category_id = bc.id
where b.url like '%.com' and bc.id in (100, 583)
group by b.id
having count(distinct bc.id ) = 1
I can't figure out how to get the Having() method structured. I can see there is a Sql.CountDistinct() method but I can't figure out how to use it with Having().
I figure I need to do something along the lines of:
var q = db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where<BlogCategory>(x => Sql.In(x.Id, 100, 583))
.GroupBy<Blog>(bc => bc.Id)
.Having(x => Sql.CountDistinct("blog_category.id") == "2")
This gives error:
42883: operator does not exist: bigint = text
I can't see how to type it to take a table column name and return a number for comparison.
Is this query possible?
EDIT
I got around it by setting having expression explicitly
q.HavingExpression = $"having count(distinct {q.Table<BlogCategory>()}.{q.Column<BlogCategory>(bc => bc.Id)}) = 2";
I am still curious though if it is possible to do this with fluent api.
I've just added multiple typed table overloads for Having() in the latest v5.11.1 that's now available on MyGet which will allow you to reference a joined table properties in a typed expression, e.g:
var q = db
.From<Blog>()
.LeftJoin<BlogToBlogCategory>()
.Join<BlogToBlogCategory, BlogCategory>()
.Where<BlogCategory>(x => Sql.In(x.Id, 100, 583))
.GroupBy<Blog>(bc => bc.Id)
.Having<BlogCategory>(x => Sql.CountDistinct(x.Id) == 2)
I have this autoquery implementation
var q = AutoQuery.CreateQuery(request, base.Request).SelectDistinct();
var results = Db.Select<ProductDto>(q);
return new QueryResponse<ProductDto>
{
Offset = q.Offset.GetValueOrDefault(0),
Total = (int)Db.Count(q),
Results = results
};
The request has some joins:
public class ProductSearchRequest : QueryDb<GardnerRecord, ProductDto>
, ILeftJoin<GardnerRecord, RecordToBicCode>, ILeftJoin<RecordToBicCode, GardnerBicCode>
{
}
The records gets returned correctly but the total is wrong. I can see 40,000 records in database but it tells me there is 90,000. There is multiple RecordToBicCode for each GardnerRecord so it's giving me the number of records multiplied by the number of RecordToBicCode.
How do I match the total to the number of GardnerRecord matching the query?
I am using PostgreSQL so need the count statement to be like
select count(distinct r.id) from gardner_record r etc...
Dores OrmLite have a way to do this?
I tried:
var q2 = q;
q2.SelectExpression = "select count(distinct \"gardner_record\".\"id\")";
q2.OrderByExpression = null;
var count = Db.Select<int>(q2);
But I get object reference not set error.
AutoQuery is returning the correct total count for your query of which has left joins so will naturally return more results then the original source table.
You can perform a Distinct count with:
Total = Db.Scalar<long>(q.Select(x => Sql.CountDistinct(x.Id));
How can I select the count from a table and include a where clause to return a long? Ideally I would use db.Count instead of db.Select. I'm just not sure how to use db.Count and cannot find documentation on it.
long totalCount = 0;
using (IDbConnection db = dbFactory.OpenDbConnection())
{
totalCount = db.Count<Content>( ?? );
}
Console.WriteLine(totalCount);
You answered for you question in your comment ;) You should use Count extension method with expression parameter. Example below:
long amout = db.Count<Post>(x => x.Subject == "test");
OrmLite generates following sql:
SELECT Count(*) FROM POST WHERE (SUBJECT = 'test')
Is there a simple and concise way to check that two rows of a given Table contains the same data in all columns?
I haven't tested this, but it seems the most obvious solution:
// get an Sql instance
def db = [url:'jdbc:hsqldb:mem:testDB', user:'sa', password:'',
driver:'org.hsqldb.jdbcDriver']
def sql = Sql.newInstance(db.url, db.user, db.password, db.driver)
// Get 2 rows
GroovyRowResults row1 = sql.firstRow("select * from user where id = 4")
GroovyRowResults row2 = sql.firstRow("select * from user where email = 'me#example.org'")
// compare them
boolean identical = row1.equals(row2)
Not especally Groovy, but I'd make SQL do the lifting a la something like:
db.firstRow("SELECT COUNT(DISTINCT CONCAT(city,state,zip)) FROM Candidates WHERE id IN (1,2)")[0] == 0