using inner join criteria language - hibernate-criteria

Have two tables : Rating and Books. Rating table has foreign key to the Books table.
These tables are mapped this way :
Books :
HasMany(x => x.RatingList).Cascade.All().Inverse();
and the Rating table :
References(x => x.Books).Column("BookId").Cascade.All();
Have this :
var bks = session.CreateCriteria("Books", "b");
using this restriction for selecting books
bks.Add(Restrictions.Eq("CategoryId",id));
here is the problem, how to join Rating table ??
bks.CreateAlias("b.Rating", "c");
bks.List();
return PartialView("/Views/Home/_Books.cshtml", bks);
The final result i need is to select all Books but also Rating for them. In the Rating table has many ratings for one book. Book rating should be given as average of ratings.
Some help ?

A criteria lets to retrieve a list of a specific class, in your case List<Book>. So, you are asking hibernate to retrieve a book list, not a list of books and ratings.
Of course, you can access ratings for every book into the resulting list. If it doesn't work, maybe a LazyInitialitationException happens. In this case you will have to apply OSIVF, extends session lifetime, or whatever.
Criteria lets you join entities to filter query results. If you create an alias for ratings, it is because you want to filter results with an ratings attributes, but it won't include ratings into the resulting list.

Related

PowerBI: Ranking of songs based on number of votes

I do have a table songs with several fields; among them: songs[title]), with songs titles, obviously, and songs[votes], with the number of votes every song has received.
I'd like to create a measure using RANKX() in order to add it to a new table (a PowerBI widget, I mean, not a table from my data model) with those both fields (songs[title]) and songs[votes]) so it tells me the rank position of every song based on the number of votes it has.
I have tried:
songs_ranking = RANKX(ALL(songs), MAX(songs[votes]))
However, all songs end up ranked #1, as if ALL() were not able to remove row context for each song:
Any hint? Thanks in advance.
_rank:=RANKX(ALL('fact'),CALCULATE(MAX('fact'[Vote])),,ASC,Dense)

Doctrine 2 How to do a Sum from a Join but Group by 2 columns

I am using Symfony and Doctrine Querybuilder to return a list of Orders with a count of all Products in each Order. That means I have a 1:n Relationship between Orders and OrderProducts the OrderProducts table stores the OrderID, and the quantity of each product. If I do a groupBy o.orderId then I get the correct Sum, but then I do not get the data for all the orderProducts belonging to the orderId so if there are 2 different Products in the orderproducts table then I get qty:2 but only the data for 1 product, so I need to group by oi.orderProductId but obviously as soon I add the second groupBy oi.orderProductId then the TotalCount is showing me the sum for each individual record. I am fully aware that this is the correct behaviour, but I just can not get my head around it if there is a way to achieve what I am trying to do. I assume I have to somehow use a subselect, but I am not sure if this is even possible to achieve. My 2 tables and my attemped so far
tbl order
orderId
dateCreated
tblorderProducts
orderProductid
orderId
qty
return $this->createQueryBuilder('o')
->select(array(
'o AS orderData',
'oi',
'sum(oi.qty)AS noOfItems'))
->join('o.orderItems', 'oi')
->groupBy('o.orderId')
->groupBy('oi.orderProductId')
->getQuery()
->execute();
I hope somebody can give me a hint how I could achieve it. Thank you very much in advance.
The groupBy() method always replaces the current group by clause. Use addGroupBy() method instead.

One to Many relationship real life example

I am trying to design the schema. I am confused about should I use one-to-many or many-to-one relationships.
My use case is somewhat like customers ordering the food.
There are 2 customers and 5 food items
Customers: [John, Alice]
Food: [Rice, Noodle, Chicken, Beacon, Ice-cream]
Use case: One Customer can order many items, but if first customer orders that item, it can not be ordered by other.
Example:
John orders -> Rice, Noodle, Chicken
Alice orders -> Beacon, Ice-cream
**This is valid, both customers ordered unique food.**
Example:
John orders -> Rice, Noodle, Chicken
Alice orders -> Beacon, Ice-cream, Chicken
**This is invalid, because Chicken is being ordered twice. John Already ordered chicken so Alice can not order it.**
Note: I am trying to this in mongodb documents and trying to establish relationship using Django models.
One way to handle this would be to create a junction table CustomerFood which looks something like this:
CREATE TABLE CustomerFood (
Customer varchar(255) NOT NULL,
Food varchar(255) NOT NULL,
PRIMARY KEY(Customer, Food)
);
The above table definition alone would only ensure that each customer can be related to each food at most once. To enforce the additional restriction that a given food can be associated with only one customer, we can add a unique constraint on the Food column:
ALTER TABLE CustomerFood ADD CONSTRAINT food_unique UNIQUE (Food);
Using Django templates:
You could use many to many in django (less code bit more complex to understand) OR create "table in the
middle approch" (more manual approach that needs more model code).
Django many to many documentation
Secondly you should use Validators to
ensure your logic that one person can only order one dish, and the
dishes will sell out, this is more programming logic and can be part
of a validator. Django validators documentation

Django - show sums of a table of records

I have a table which has a list of invoices and their details:
class Invoice(models.Model):
invoiceNum = models.CharField(etc...)
invoiceDate = models.DateField(etc...)
customerID = models.ForeignKey(etc...)
isPaid = models.CharField(etc...)
The Invoice records do not hold the actual invoice total. Instead, an invoice's total is made up of several Invoice_Line_Item records, held in another table:
class Invoice_Line_Item(models.Model):
invNum = models.ForeignKey(Invoice)
itemName = models.CharField(etc...)
itemPrice = models.DecimalField(etc...)
I have a webapp that shows all the invoices in a big HTML table, along with all the details of that invoice on the table's tr row. Details such as, Invoice Date, Invoice Number, Customer ID, all come from that Invoice table. There are hundreds of invoices to display in this HTML table.
What I would like to do is also show each invoice's total value - which is the sum of all the line items. However, I can't think of a simple way to acomplish this since the invoice details and the line items that make up the invoice's total are in two different tables.
One way I thought is to pass the entire Invoice_Line_Item querySet into the HTML template, then for each invoice displayed in a table tr, I could iterate over the entire Invoice_Line_Item querySet, adding up all the line items that match the current invoice. This, however, seems hugely inefficient.
Any better ideas on how to do this?
Thanks!
One word: Aggregation
Invoice_Line_Item.objects.filter(invNum=invoice).aggregate(Sum('itemPrice'))
https://docs.djangoproject.com/en/dev/topics/db/aggregation/
Another way is to store the total in Invoice and update it whenever you change a related Invoice_Line_Item
One more word: annotate.
from django.models import Sum
Invoice.objects.filter( .. ).annotate( InvTotal=Sum( 'invoice_line_number__itemPrice' ) )
InvTolal becomes a new attribute of Invoice object, you can use it in template the same way as invoiceNum or invoiceDate.
With this approach you do not have to pass any additional data structures to your template, only a QuerySet of Invoices.
Please note:
Argument of Sum is a string, which is a concatenation of the name of related model converted to lowercase, than double '_', and than the name of a field in related model.

Filter for elements using exists through a reverse foreign key relationship

A relevant image of my model is here: http://i.stack.imgur.com/xzsVU.png
I need to make a queryset that contains all cats who have an associated person with a role of "owner" and a name of "bob".
The sql for this would be shown below.
select * from cat where exists
(select 1 from person inner join role where
person.name="bob" and role.name="owner");
This problem can be solved in two sql queries with the following django filters.
people = Person.objects.filter(name="bob", role__name="owner")
ids = [p.id for p in people]
cats = Cat.objects.filter(id__in=ids)
My actual setup is more complex than this and is dealing with a large dataset. Is there a way to do this with one query? If it is impossible, what is the efficient alternative?
I'm pretty sure this is your query:
cats = Cat.objects.filter(person__name='bob', person__role__name='owner')
read here about look ups spanning relationships