Suppose I have the following very simple data warehouse:
section application;
car:
LOAD * INLINE
[
CAR,USER
GETZ,George
];
person:
LOAD * INLINE
[
USER
George
Maria
];
As you can see, USER George has a CAR GETZ, while USER Maria has no car.
Is it possible to set the section access up, using reduction field=CAR, so that
a user can only see Maria, who has a null value on CAR?
I have read COUNTLESS posts. Many say to put an empty string- that doesn't work. I have also seen multiple "Answers" having sample qvds attached - and most of them use a single table with an empty string value to make the test, which then seems to work with the empty string value at section access. Of course, this is not the case I'm interested, as the empty string value is still different than a missing/nulul value
Because section access works via associations in Qlik it wouldn't be possible with your current data model. Maria doesn't have a null car - she has no car association (which will show as a null if you put USER and CAR in a table but it's a subtle difference). If structured your data a little differently you could potentially make it work with a blank... something like
car:
LOAD * INLINE
[
CAR,USER
GETZ,George
];
outer join(car):
LOAD * INLINE
[
USER
George
Maria
];
You might need to populate the null values with blank afterwards...
car2:
NOCONCATENATE LOAD
if(isnull(CAR),'',CAR) as CAR,
USER
Resident car;
drop table car;
If it's not possible to join the two tables then you could add blank entries to your car table?
car:
LOAD
*,
USER as USER2
INLINE
[
CAR,USER
GETZ,George
];
person:
LOAD * INLINE
[
USER
George
Maria
];
concatenate(car)
LOAD
USER,
'' as CAR
RESIDENT person
WHERE NOT EXISTS (USER2,USER);
There are also options with some kind of combined key or applymaps potentially, but hopefully one of the above is helpful enough...
Related
I want to get competition.name from a list of submissions.
In my setup, competitions and teams share a M2M relationship (with an associated competition-team object. Each competition-team pair can submit any number of submissions. I now have a dashboard page which I am trying to create a table of all submissions by the team accompanied by the respective competition's name. The output should look like:
| Submission Name | Submission Date etc. | Competition Name |
| Sub01 | 2020-12-30 2000 | Competition01 |
I have trouble retrieving the competition name from the submissions. Here are my models:
class Competition(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=30)
class CompetitionTeam(models.Model):
competition_id = models.ForeignKey('Competition', on_delete=models.CASCADE, to_field='id', db_column='competition_id')
team_id = models.ForeignKey('Team', on_delete=models.CASCADE, to_field='id', null=True, db_column='team_id')
class CompetitionSubmission(models.Model):
competitionteam_id = models.ForeignKey(CompetitionTeam, on_delete=models.CASCADE, db_column='competitionteam_id')
I wish to annotate a set of submissions with their respective competition names. I tried with:
submissions.annotate(competition_name=Subquery(Competition.objects.filter(id=Subquery(CompetitionTeam.objects.get(id=OuterRef('competitionteam_id')).competition_id)).values('name')))
"ValueError: This queryset contains a reference to an outer query and may only be used in a subquery."
I also tested with the following command:
CompetitionSubmission.objects.prefetch_related('competitionteam_id__competition_id')
It runs but the command seems to do nothing. I will update this post with other methods I try.
Thank you.
EDIT
submissions.annotate(competition_name=Subquery(Competition.objects.filter(id=Subquery(CompetitionTeam.objects.filter(id=OuterRef(OuterRef('competitionteam_id_id'))).values('competition_id'))).values('name')))
Seems to work correctly.
You can traverse ForeignKeys directly using double underscores.
CompetitionSubmission.objects.values(
'competitionteam_id',
'competitionteam_id__competition_id',
'competitionteam_id__competition_id__name',
'competitionteam_id__team_id',
'competitionteam_id__team_id__name',
)
This will only produce a single database query. Django ORM takes care of everything.
P.S. I would avoid using '_id' in field names as Django model fields are supposed to be referring to related objects themselves. Django automatically adds extra attributes with '_id' that contains the related object's id. Please see https://docs.djangoproject.com/en/3.1/ref/models/fields/#database-representation
I'm developing an API in Rails in which exists users and messages tables. Also users have a gender (gender_id), belong to a country (country_id) and also have a civil status (civil_status_id) and the messages are created by admins.
So up to here I have this model.
Now I have to develop the following requirement
An admin should be able to create a message targeted to users depending on its attributes (country, gender or civil status). Also, the admin should be able to declare a message as a global message, in this case "all" users should receive it, but exceptions should also be allowed. For example, in the case where an admin want to send a message to users from all countries, except people from Russia and China.
The thing is I'm no Rails/SQL expert, but I want to make this efficiently so that if tomorrow the app has ten thousand or a hundred thousand users the server responds quickly.
So I was thinking the following
First create 3 many-to-many relationships (countries_messages, genders_messages and civil_statuses_messages). The record of these tables represent the relations between the messages and the countries, civil_statuses and genders.
Then create a form where an admin can create a message, where by means of several select boxes, he should be able to choose the attributes of the users to whom he wants to reach. The form for creating a message should also have a checkbox to determine if the message is global, if its marked then I would consider that the selected countries, genders and civil statuses would be the categories that the administrator wants to exclude, i.e. if an admin want to send a message to all the people in the system except for people who are from Canada he should mark the global option and select the country Canada in the select box (obviously this would be stated in the view).
Now up to here I have this model.
In what I do have doubts is which way is more efficient to return the messages that corresponds to a user.
Method 1
When an admin specifies that a message is global, except for those from country with id 3 then I could add to countries_messages records like (country_id: 1, message_id: 2), (country_id: 2, message_id: 2), (country_id: 4, message_id: 2), ..., etc. i.e. forming a relation with every country except the country with id 2.
Then retriveng the messages that the current user should read like the following:
global_messages = Message.where(global: true).ids
country_messages = current_user.country.messages.ids
gender_messages = current_user.gender.messages.ids
civil_status_messages = current_user.current_status.messages.ids
#messages = Message.find(global_messages + country_messages + gender_messages + civil_status_messages)
Method 2
Other way could be forming a relation of that message with the excluded country, i.e. if I make a message exclusively for people from country with id 2 then I should add the record (country_id: 2, message_id: 2) in countries_messages, but in the contrary case if I made a message to every country except the country with id 2 then I should also add the record (country_id: 2, message_id: 2) to countries_messages.
In this case I can know if a message is excluded for males and people from Argentina, for example, if the message is global AND it's associated with the country and gender record that represents Argentina and males.
Then the retriveng of the messages that the current user should read would be like this:
global_messages = Message.where(global: true).ids
country_messages = current_user.country.messages
gender_messages = current_user.gender.messages
civil_status_messages = current_user.current_status.messages
excluded_country_messages_ids = country_messages.where(global: true).ids
excluded_gender_messages_ids = gender_messages.where(global: true).ids
excluded_civil_status_messages_ids = civil_status_messages.where(global: true).ids
#messages = Message.find(global_messages + country_messages + gender_messages + civil_status_messages - excluded_country_messages_ids - excluded_gender_messages_ids - excluded_civil_status_messages_ids)
There could be more ways to do the same, so I want to receive recommendations or if you see that I could make improvements to do the same then tell me. If there is something you do not understand ask.
Depending on your database choice, you may want to consider storing the message "attributes" (country, gender, ...) in a jsonb column on your messages table. It could also include a user_ids attribute to simplify things. The queries might look a little funny, but you can move a lot into scopes to clear things up in your code and even add indexes to speed things up.
Here is a great article on using jsonb with indexes in Rails with postgresql.
Another alternative you could do is make a UserMessage join table with a polymorphic reference that could associate the different attributes to a message and user:
class UserMessage < ApplicationRecord
belongs_to :user
belongs_to :message
belongs_to :messageable_type # e.g. "Country"
belongs_to :messageable_id # e.g. some Country id
end
I have a user table that consists of these columns:
| id | username | password | email | pants_size_id | shirt_size_id |
pants_size_id and shirt_size_id are filled with foreign tables id keys where I store a list of sizes for pants and shirts in different country specific measures, example of pants_size table:
| id | UK_sizing | US_sizing | IT_sizing |
a single user will have only one pants and shirt size so the user table is filled with the ID of the corresponding rows in the size tables.
what kind of relationship does this imply between the user model and the pants and shirt sizing models?
Also how can I retrieve the data inside the foreign table column (example IT_sizing) when returning auth user return \Auth::user(); instead of the numeric size_id ?
In other words how can I retrieve say '32' (a pants size) instead of the pants_size_id (let's say '1').
Cato has the right answer, I can't exactly respond to it because of my rep but the logic in your other answer doesn't make sense from a relational standpoint.
Users don't belong to a size, instead, Users have a size.
To me it sounds like you mixed up the foreign and local key assignment it should be User->hasOne(pants_size).
In your model it would be the following, the explicitness of the keys isn't great, but if you have some weird thing laravel can't figure out this should work.
public function pants_size(){
return $this->hasOne('App\Pants_size','id','pants_size_id');
}
public function shirt_size(){
return $this->hasOne('App\Shirt_size','id','shirt_size_id');
}
To answer the other question of how to find the size (32), since you're dealing with three different measurements you have to have a where clause on the specific measurement the 32 represents, and get the id. If you specifically wanted the users you would call the eloquent query as so:
\Auth::User()->pants_size()->(..whatever measurement you want..)
Create a function establishing a hasOne relationship for both pants_size and shirt_size in the user model. Be sure to set the foreign key and local key correctly if you don't want Laravel to assume default keys (see here for details).
Once the functions are created, you will be able to obtain data about the user's size information like so: App\Model\User::find(123)->pants_size->UK_sizing. (This example is for a user with ID of 123).
this is how I made it work:
in USER model:
public function pants_size(){
return $this->belongsTo('App\Pants_size');
}
public function shirt_size(){
return $this->belongsTo('App\Shirt_size');
}
In Pants_size and Shirt_size Models:
public function user(){
return $this->hasMany('App\User');
}
That last one works also with hasOne.
The code I use to retrieve the data is:
public function index()
{
echo $user = User::find($id);
echo $pants = User::find($id)->pants_size->it_sizing;
echo $shirt = User::find($id)->shirt_size->it_sizing;
}
Hello Folks,
I am working on customizing some functionality on the Force.com platform. I have a question for you; I am not too sure if this is possible!
What I have? : 2 custom objects - abc and pqr. Abc is the junction object between the Standard object Account and pqr i.e. Account is the parent of abc and then Pqr is the parent of abc. I am retrieving everything through these objects into a List of type Account (i.e. from Account object).
What I need? : I can access the abc object in Apex i.e. the First child of Account. Is there a possibility to access the fields of pqr through account?
What I have tried : Accessing the object through relationship name - Account.abc_r[0].pqr_r[0].FIELDNAME
But it hasnt worked. Could some salesforce/apex developer help me with this?
You should be able to get the information you need using a subquery. The real question here is how your query is setup. Your query will need to access all levels of the data model for it to be available. If you are relying on data returned in a trigger or standard controller then I would recommend requiring the account object to get access to the additional information.
So I would expect to see something along the lines of:
List<Account> accounts = [SELECT Id, Name, (SELECT Id, pqr__r.Id, pqr__r.Name FROM abc__r) FROM Account];
for (Account acct : accounts) {
string someValue = acct.abc__r[0].pqr__r.Name;
}
Keep in mind though that as a best practice you shouldn't access the child records the way I did above because if there are no ABC records that object will be null so as a best practice you will want to test for that ahead of time. Same goes for PQR object data.
The answer to this question is the following:
List<Account> accounts = [SELECT Id, Name, (SELECT Id, pqr__r.Id, pqr__r.Name FROM abc__r) FROM Account];
for (Account acct : accounts) {
for(Abc__c abc : acct.abc__r)
{
String someValue = abc.pqr__r.Name;
}
}
Note: Here, abc_r is the relationship of object Abc_c with Account. Please comment on this if you have any questions.
Simple model:
class hat
embedded_in :owner
field :color
end
class owner
embedds_one :hat
referenced_in :house
field :name
end
class house
references_one :owner
field :number
end
So simply puts, we have collection of houses that are associated to an owner, and the owner can have a colored hat.
I can simply sort the house by their number:
House.all.order_by( [[ :number, :asc ]])
But what I want is ordering the house, by the name of their owner, ideally I would like to write:
House.all.order_by( [[ :'owner.name', :asc ]])
But it does not work...
And even further I would like to be able to sort the houses by the color of the owner's hat
House.all.order_by( [[ :'owner.hat.color', :asc ]])
Any idea how I can achieve this without rewriting everything if possible :)
Thanks
ALex
Dot notation is possible only for embedded documents, but you have 2 collections - houses and owners.
In one of the Owner records in MongoDB you have only field house_id, in one of the House records you dont have any connection to Owner model.
So the only way is to fetch all Houses and then to sort achieved collection using Enumerable#sort.
ways to do this would be:
- embed the owner name as string in the house doc.
The house object would have both a owner_id (so that you can fetch full owner doc) and an extra field with just the owner name as string.
You only need to change the name when changing the owner_id and that can be done in 1 update so it is consistent.
Using this it will be a very efficient query since it doesnt need to look across collections and docs for reads.
Downside is a bit more mem used.
have the owner object reference the house, since the owner "owns".
Then you can query owner sorted by name, then fetch the reference house documents that you will get in the correct order.
This has the downside of doing many individual queries.
one extreme solution is to embed all those docs: hat inside owner, owner inside house.
best,
AG