How do I separate the results - mysql

I have the following query on Doctrine QueryBuilder:
$qb = $this->createQueryBuilder('e')
->select('e.id, e.name, e.body, e.teaser, e.slug, e.dateBegin, e.dateEnd, e.dateTbd, v.name AS v_name')
->innerJoin('e.venue', 'v')
->where('v.name LIKE :TBD')
->orWhere('v.name LIKE :TBA')
->orWhere('e.name LIKE :TBD')
->orWhere('e.name LIKE :TBA')
->orWhere('e.name LIKE \'none\'')
->orWhere('e.name LIKE \'n/a\'')
->orWhere('e.teaser LIKE :TBD')
->orWhere('e.body LIKE :TBD')
->orWhere('e.dateTbd=true')
->orWhere('TIME(e.dateBegin) < :earlyMorning AND TIME(e.dateBegin) > :lateNight')
->setParameter('TBA', '%TBA%')
->setParameter('TBD', '%TBD%')
->setParameter('earlyMorning', '06:00:00')
->setParameter('lateNight', '23:00:00');
How I can separate the results by 'where' clause in this query. I need to display every event with criteria which listed in where clause.

I can't see a way of achieving this easily, especially if we are to assume you're using this to retrieve a standard doctrine entity collection, since additional grouping / properties wouldn't really be something you could pass into these.
If you need to group these simply to display them slightly differently as they're output, say, in your markup, I'd consider adding additional methods into your entity's class to allow you detect which 'type' they are based on similar criteria defined in your query, e.g. using standard string matching functions.
Otherwise your options are going to be filtering the collection (ArrayCollections carry a method for doing that easily) or separating it out into multiple queries, which given your approach, I assume you are trying to avoid.

Related

Filter an array passed from query params. NestJS, TypeORM

I’m using NestJS with TypeORM, database is MySQL, and I’d like to filter multiple parameters that can be passed in.
The frontend has a list of products and filters are applied as query params sent to NestJS, filtering works for a single param eg api.example.com?manufacturer=Acer but how would I filter an Array eg api.example.com?manufacturer=Acer,Toshiba,Asus.
I tried quite a few things in TypeORM, currently using the QueryBuilder to build the array with an if statement if the filter exists if so I’m doing something like a where statement.
.andWhere(manufacturer = filterOne, {filterOne: *manufacturers from the query param*})
But yeah just can’t hack something together, tried a couple of things, above is a rough example, did try methods that TypeORM had as an example on filtering arrays but it seemed like it was more for an array of integers only? Regardless, I’m open to any methods that allow for the end result of filtering the example I provided, cheers and thanks again!
You have to use IN to get all data where manufacturer equal the data came from the query, first, you have to convert the query to an array:
var manufacturerParam = filterOne.split(",");
then add it to your query:
.andWhere(manufacturer IN (:filter)", { filter: manufacturerParam })

Get all current joins to a query in yii2 ActiveQuery

Is there a way to get all joined table from a query?
For example:
query = Account::find()->joinWith(['gallery'])->joinWith(['articles'])->etc...
Is there any integrated method in yii2 that will return the above joined tables (or an event on which I could hook to get them manually)?
Solution suggested by #Beowulfenator shows only joins with relations (which added with joinWith() method.
To show all joins you need prepare the query like this:
$query = Account::find()
->join('...', '...')
->joinWith(['gallery', 'articles']); // By the way, you can reduce you code like this
$query->prepare();
This will transform yii\db\ActiveQuery to simple yii\db\Query which doesn't have joinWith property but has join property that shows exactly all joins.
You can var_dump and see it:
var_dump($query->join);
exit();
First element stores type of join, second - table name (note that it can be either string or array depending on used relation), third - on condition.
ActiveQuery class has joinWith public property. It's an array that contains information on all joins. It, among other things, contains joined table names.
More info here.

Business Objects Generating Unexpected Query

I am having problem with BusinessObject Universum and the way it generates queries and consequently yielding the results.
Here is the background: mechanism that is functioning has already been implemented. I was trying to copy the SAME mechanism just to deliver a different field.
Here is the data model: http://tinypic.com/r/ng524g/8
The mechanism that functions is marked with BLUE color. The mechanism that I tried to implement and that is not functioning is marked with RED color.
On business layer I have defined a dimension with aggregate aware function. This function takes first VWF_Party_Collection_A.Collectionstatus_CD column (at the higher level). If a user selects an attribute from contract level, function takes VWF_Contract_Collection_A.Collectionstatus_CD column.
Problem is when I take all attributes from VWD_Kunde_A table and than add the dimension with the mentioned aggregate aware function (ie Collectionstatus_CD), the constructed query from BO side does not make any sense. Here it is:
SELECT
D_ATA_MV_FinanceTreasury.VWF_Party_Collection_A.Collectionstatus_CD,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Namespace_TXT,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Party_KEY,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Legacy_ID
FROM
D_ATA_MV_FinanceTreasury.VWD_Party_A
LEFT JOIN D_ATA_MV_FinanceTreasury.VWF_Party_Collection_A
ON D_ATA_MV_FinanceTreasury.VWD_Party_A.Party_KEY=D_ATA_MV_FinanceTreasury.VWF_Party_Collection_A.Party_KEY,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A
WHERE
(
D_ATA_MV_FinanceTreasury.VWD_Party_A.Party_KEY=D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Party_KEY )
AND
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Legacy_ID = 102241978
Please notice the strange conctruction in the 'FROM' part (comma has been added). Another strange and unexpected construction is in 'WHERE' part:
( D_ATA_MV_FinanceTreasury.VWD_Party_A.Party_KEY=D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Party_KEY )
The mechanism that is functioning is joining joins VWD_Kunde_A with VWF_Contract_Collection_A table and yields the correct result.
Now, I have tried to define a dimension without the mentioned aggregate aware function that contains only VWF_Contract_Collection_A.Collectionstatus_CD attribute. When I run the same query BO yields CORRECT results and it generates the CORRECT (expected) query.
This is the query I am expecting:
SELECT
D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A.Collectionstatus_CD,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Namespace_TXT,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Party_KEY,
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Legacy_ID
FROM
D_ATA_MV_FinanceTreasury.VWD_Kunde_A LEFT JOIN D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A ON D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Namespace_TXT = D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A.Namespace_TXT AND D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Party_KEY = D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A.Party_KEY AND D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Legacy_ID = D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A.Legacy_ID
WHERE
D_ATA_MV_FinanceTreasury.VWD_Kunde_A.Legacy_ID = 102241978
Furthermore, I suspected that it can something to do with contexts. However, I did not find any context for the mechanism that already functions and that I tried to copy. Therefore, I did not implement any context for the mechanisam I am tring to implement.
At this point I am clueless since I tried everything I knew. I would appreciate help.
Thanks!
A.
UPDATE: it seems as aggragate aware function is not functioning... This is how it is defined:
#Aggregate_Aware(D_ATA_MV_FinanceTreasury.VWF_Party_Collection_A.Collectionstatus_CD,D_ATA_MV_FinanceTreasury.VWF_Contract_Collection_A.Collectionstatus_CD)
(I just copied the code from Kreditklasse and adapted it... That makes me even more confused...)
UPDATE_2: it really seems as if aggragate aware is not functioning in my case because I selected all attributes from contract_context and it still jumps to party context. Very confused because THE SAME mechasism is functioning as expected when I select Kreditklasse...
Check the aggregate navigation.
Setting up Aggregate Awareness requires two steps (in addition to correctly defining the joins between the tables, of course):
Define the objects with the Aggregate_Aware function
Set table-object incompatibilities through Actions > Set Aggregate Navigation.
It sounds like the second part is not properly configured: make sure that any objects which require the second table are marked incompatible with the first.

Django conditional count

I am querying the names of all the Tags that I've flagged as "visible":
visible_tags = Tag.objects.filter(visible=True,taggit_taggeditem_items__content_type=ContentType.objects.get_for_model(Action)).order_by('name')
I want to add a field called "action_count" that tells me how many actions are associated with this tag:
visible_tags = Tag.objects.filter(visible=True,taggit_taggeditem_items__content_type=ContentType.objects.get_for_model(Action)).order_by('name').annotate(action_count=Count('action'))
This works except that I want to know not just now many actions are affiliated, but how many actions that are incomplete that are affiliated with this tag.
I tried the following:
visible_tags = Tag.objects.filter(visible=True,taggit_taggeditem_items__content_type=ContentType.objects.get_for_model(Action)).order_by('name').filter(action__complete=False).annotate(action_count=Count('action'))
But this doesn't quite do what I need it to do. How can I annotate the count of actions that are incomplete?
You might get more count than expected. This is because chained .filter that introduce extra inner join, very similar to the question Are chained QuerySet filters equivalent to defining multiple fields in a single filter with the Django ORM?
Thus put the second filter in the first one:
visible_tags = Tag.objects.filter(visible=True, taggit_taggeditem_items__content_type=ContentType.objects.get_for_model(Action),
action__complete=False # Here
).order_by('name').annotate(action_count=Count('action'))
Besides, print queryset.query to know what SQL Django generates for you.

nested sql queries in rails

I have the following query
#initial_matches = Listing.find_by_sql(["SELECT * FROM listings WHERE industry = ?", current_user.industry])
Is there a way I can run another SQL query on the selection from the above query using a each do? I want to run geokit calculations to eliminate certain listings that are outside of a specified distance...
Your question is slightly confusing. Do you want to use each..do (ruby) to do the filtering. Or do you want to use a sql query. Here is how you can let the ruby process do the filtering
refined list = #initial_matches.map { |listing|
listing.out_of_bounds? ? nil : listing
}.comact
If you wanted to use sql you could simply add additional sql (maybe a sub-select) it into your Listing.find_by_sql call.
If you want to do as you say in your comment.
WHERE location1.distance_from(location2, :units=>:miles)
You are mixing ruby (location1.distance_from(location2, :units=>:miles)) and sql (WHERE X > 50). This is difficult, but not impossible.
However, if you have to do the distance calculation in ruby already, why not do the filtering there as well. So in the spirit of my first example.
listing2 = some_location_to_filter_by
#refined_list = #initial_matches.map { |listing|
listing.distance_from(listing2) > 50 ? nil : listing
}.compact
This will iterate over all listings, keeping only those that are further than 50 from some predetermined listing.
EDIT: If this logic is done in the controller you need to assign to #refined_list instead of refined_list since only controller instance variables (as opposed to local ones) are accessible to the view.
In short, no. This is because after the initial query, you are not left with a relational table or view, you are left with an array of activerecord objects. So any processing to be done after the initial query has to be in the format of ruby and activerecord, not sql.