Flutter sqflite, retreiving data from a rawQuery - flutter

I have the following rawQuery
final maps = await db.rawQuery("""
select r.id, r.name, r.description,r.created_by,
a.id,a.name,a.description from Resources r
left join Resource_Attribute ra on ra.resource_id = r.id
left join AttributeItems a on ra.attribute_id=a.id
""");
My question is how do I retrieve the data from all the columns in my query? Doing the following
maps.forEach((dbItem){
String resourceId = dbItem["r.id"];
doesn't seem to work. dbItems is a map but contains only the four columns in the Resources table. dbItem["r.id"] returns a null.
dbItems does contain a "row" field which is an array with all the field. Is there way to access that?

If you look at dbItem.keys, you will see that it is ['id','name',...] not ['r.id','r.name'].
You can access your resource id using:
var resourceId = dbItem['id'] as String;
You can name a column explicitely using AS. For example:
var resultSet = await db.rawQuery("SELECT r.id AS r_id FROM test r");
// Get first result
var dbItem = resultSet.first;
// Access its id
var resourceId = dbItem['r_id'] as String;

As alextk suggested , I changed my query to
select r.id as resource_id, r.name as resource_name, r.description as resource_descr,r.created_by as resource_created_by,
a.id as attribute_id,a.name as attribute_name,a.description as attribute_descr from Resources r
left join Resource_Attribute ra on ra.resource_id = r.id
left join AttributeItems a on ra.attribute_id=a.id
and that did the trick.

Related

Postgresql, how to SELECT json object without duplicated rows

I'm trying to find out how to get JSON object results of selected rows, and not to show duplicated rows.
My current query:
SELECT DISTINCT ON (vp.id) jsonb_agg(jsonb_build_object('affiliate',a.*)) as affiliates, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors FROM
affiliates a
INNER JOIN related_affiliates ra ON a.id = ra.affiliate_id
INNER JOIN related_vendors rv ON ra.product_id = rv.product_id
INNER JOIN vendor_partners vp ON rv.vendor_partner_id = vp.id
WHERE ra.product_id = 79 AND a.is_active = true
GROUP BY vp.id
The results that I receive from this is:
[
affiliates: {
affiliate: affiliate1
affiliate: affiliate2
},
vendors: {
vendor: vendor1,
vendor: vendor1,
}
As you can see in the second record, vendor is still vendor1 because there are no more results, so I'd like to also know if there's a way to remove duplicates.
Thanks.
First point : the result you display here above doesn't conform the json type : the keys are not double-quoted, the string values are not double-quoted, having dupplicated keys in the same json object ('{"affiliate": "affiliate1", "affiliate": "affiliate2"}' :: json) is not be accepted with the jsonb type (but it is with the json type).
Second point : you can try to add the DISTINCT key word directly in the jsonb_agg function :
jsonb_agg(DISTINCT jsonb_build_object('vendor',vp.*))
and remove the DISTINCT ON (vp.id) clause.
You can also add an ORDER BY clause directly in any aggregate function. For more information, see the manual.
You could aggregate first, then join on the results of the aggregates:
SELECT a.affiliates, v.vendors
FROM (
select af.id, jsonb_agg(jsonb_build_object('affiliate',af.*)) as affiliates
from affiliates af
group by af.id
) a
JOIN related_affiliates ra ON a.id = ra.affiliate_id
JOIN related_vendors rv ON ra.product_id = rv.product_id
JOIN (
select vp.id, jsonb_agg(jsonb_build_object('vendor',vp.*)) as vendors
from vendor_partners vp
group by vp.id
) v ON rv.vendor_partner_id = v.id
WHERE ra.product_id = 79
AND a.is_active = true

Linq order by using query expression

Is it possible to do orderby expression using linq query expression based on dynamic string parameter? because the query i have is producing weird SQL query
my linq:
var product = from prod in _context.Products
join cat in _context.Categories on prod.CategoryId equals cat.CategoryId
join sup in _context.Suppliers on prod.SupplierId equals sup.SupplierId
orderby sortParam
select new ProductViewModel
{
ProductName = prod.ProductName,
ProductId = prod.ProductId,
QuantityPerUnit = prod.QuantityPerUnit,
ReorderLevel = prod.ReorderLevel,
UnitsOnOrder = prod.UnitsOnOrder,
UnitPrice = prod.UnitPrice,
UnitsInStock = prod.UnitsInStock,
Discontinued = prod.Discontinued,
Category = cat.CategoryName,
Supplier = sup.CompanyName,
CategoryId = cat.CategoryId,
SupplierId = sup.SupplierId
};
where var sortParam = "prod.ProductName"
The code above produces weird sql where order by sortParam is being converted to (SELECT 1). Full query catched by sql profiler below:
exec sp_executesql N'SELECT [prod].[ProductName], [prod].[ProductID], [prod].[QuantityPerUnit], [prod].[ReorderLevel], [prod].[UnitsOnOrder], [prod].[UnitPrice], [prod].[UnitsInStock], [prod].[Discontinued], [cat].[CategoryName] AS [Category], [sup].[CompanyName] AS [Supplier], [cat].[CategoryID], [sup].[SupplierID]
FROM [Products] AS [prod]
INNER JOIN [Categories] AS [cat] ON [prod].[CategoryID] = [cat].[CategoryID]
INNER JOIN [Suppliers] AS [sup] ON [prod].[SupplierID] = [sup].[SupplierID]
ORDER BY (SELECT 1)
OFFSET #__p_1 ROWS FETCH NEXT #__p_2 ROWS ONLY',N'#__p_1 int,#__p_2 int',#__p_1=0,#__p_2=10
I'm seeing a lot of people doing linq order by using dynamic parameter but all of them use lambda not query expression, please enlighten me
As was already mentioned, you are passing a string value instead of an expression that reflects the column name. There are options for what you want however, see for example here.

Apply join on two result set - Postgres

I have query that gives me the documentid
select documentid from tbldocumentbyclient
where tbldocumentbyclient.isactive = true
and applicationid = '000116'
result:
Another query that give me the following result
SELECT documentcategory,documentcategoryid, string_agg(documentid::text, ',') as documentid
FROM tbldocumentmaster
where accounttype = 1 and usertype= 'INDIVIDUAL'
group by documentcategory,documentcategoryid
order by documentcategoryid;
result :
[![enter image description here][2]][2]
Now,Can someone please suggest me how to get CategoryName that is not associated with any documentid
For Above case my result should be following.
DP Proof - 134 not available in first result
Address Proof Permanent - row 4.. not a single id available in documenid result
Here this are the documentcategory that is not associate with any document id
I think a simple join between your two tables should do the trick. The logic here is if a document category from tbldocumentmaster really has no document IDs which match to anything in the tbldocumentbyclient table then the join should filter it off, leaving behind those categories which do match.
SELECT t1.documentcategory
FROM tbldocumentmaster t1
LEFT JOIN tbldocumentbyclient t2
ON t1.documentid = t2.documentid
WHERE t2.isactive = true AND
t2.applicationid = '000116' AND
t1.accounttype = 1 AND
t1.usertype = 'INDIVIDUAL' AND
t2.documentid IS NULL
try this:
SELECT distinct documentcategory,documentcategoryid
FROM tbldocumentmaster m
LEFT OUTER JOIN tbldocumentbyclient d on d.documentid = m.documentid
where accounttype = 1 and usertype= 'INDIVIDUAL'
and m.documentid is null
and applicationid = '000116'
group by documentcategory,documentcategoryid
order by documentcategoryid;
I have not tested but you can try this query:
SELECT documentcategory,documentcategoryid, string_agg(documentid::text, ',') as documentid
FROM tbldocumentmaster
where accounttype = 1 and usertype= 'INDIVIDUAL' and documentid not in (select documentid from tbldocumentbyclient where tbldocumentbyclient.isactive = true and applicationid = '000116')
group by documentcategory,documentcategoryid
order by documentcategoryid;

How to perform Linq to Entites Left Outer Join

I have read plenty of blog posts and have yet to find a clear and simple example of how to perform a LEFT OUTER JOIN between two tables. The Wikipedia article on joins Join (SQL) provides this simple model:
CREATE TABLE `employee` (
`LastName` varchar(25),
`DepartmentID` int(4),
UNIQUE KEY `LastName` (`LastName`)
);
CREATE TABLE `department` (
`DepartmentID` int(4),
`DepartmentName` varchar(25),
UNIQUE KEY `DepartmentID` (`DepartmentID`)
);
Assume we had a EmployeeSet as an employee container ObjectSet<Employee> EmployeeSet and a DepartmentSet ObjectSet<Department> DepartmentSet. How would you perform the following query using Linq?
SELECT LastName, DepartmentName
FROM employee e
LEFT JOIN department d
ON e.DepartmentID = d.DepartmentID
I would write this, which is far simpler than join and does exactly the same thing:
var q = from e in db.EmployeeSet
select new
{
LastName = e.LastName,
DepartmentName = e.Department.DepartmentName
};
You need to use the DefaultIfEmpty method :
var query =
from e in db.EmployeeSet
join d in db.DepartmentSet on e.DepartmentID equals d.DepartmentID into temp
from d in temp.DefaultIfEmpty()
select new { Employee = e, Department = d };

Linq: the linked objects are null, why?

I have several linked tables (entities). I'm trying to get the entities using the following linq:
ObjectQuery<Location> locations = context.Location;
ObjectQuery<ProductPrice> productPrice = context.ProductPrice;
ObjectQuery<Product> products = context.Product;
IQueryable<ProductPrice> res1 = from pp in productPrice
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select pp;
This query returns 2 records, ProductPrice objects that have linked object Location and Product but they are null and I cannot understand why. If I try to fill them in the linq as below:
res =
from pp in productPrice
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select new ProductPrice
{
ProductPriceId = pp.ProductPriceId,
Product = prod
};
I have the exception "The entity or complex type 'PBExplorerData.ProductPrice' cannot be constructed in a LINQ to Entities query"
Could someone please explain me what happens and what I need to do?
Thanks
The answer to your first question the Product and Location are null because you need to add an Include("") to your query.
IQueryable<ProductPrice> res1 = from pp in
productPrice.Include("Location").Include("Product")
join loc in locations
on pp.Location equals loc
join prod in products
on pp.Product equals prod
where prod.Title.ToLower().IndexOf(Word.ToLower()) > -1
select pp;
The second issue is EF is trying to push down your query and ProductPrice (is not an entity) so it can not. If you want to do this convert it to an anonymous type so just do
select new
{
ProductPriceId = pp.ProductPriceId,
Product = prod
};
And then do
res.ToList().ConvertAll(x=new ProductPrice () {
ProductPriceId = x.ProductPriceId ,
Product = x.Product
});
Or you could do it other ways, by selecting the entity you want, and just populating manual.