Tableau question
I am new to Tableau. I have a field name [Fruit description] and I am trying to exclude a lot of values using key words.
For example, I was to exclude all values that have the phrase [very red] or [juicy] etc.
I have tried multiple syntaxes using the IF Contains([field], [substring])=true ... I am doing something very wrong..
Here is what I have done:
If CONTAINS([fruit_description],"Very red")=true then "exclude"
ELSEIF [fruit_description], "juicy") =true then "exclude"
ELSEIF CONTAINS([fruit_description],"yummy")=true then "exclude"
ELSEIF CONTAINS([fruit_description],"very tasteful")=true then "exclude"
else "keep"
END
I also tried saying =true then 0 else 1
But none of these work out.
I get syntax errors..
Any help? :)
Thanks
You don't have to say "= true". That's redundant.
Its simpler and more readable to treat boolean expressions as first-class datatypes, just as you would treat integers or strings. You can then just define a boolean valued calculated field named, say [Tasty?] as
CONTAINS([fruit_description],"Very red") OR
CONTAINS([fruit_description], "juicy") OR
CONTAINS([fruit_description],"yummy") OR
CONTAINS([fruit_description],"very tasteful")
and then you can use [Tasty?] on any shelf or calculated field, including the Filter shelf. My personal convention is to put a ? at the end of the names of boolean valued fields, as it makes the meaning of True or False obvious for that field. You can also edit the aliases for you field so that the label you display is even more self apparent - such as using the aliases Tasty and Yucky to display in place of True and False for the field [Tasty?]
Finally, if you are doing a lot of string comparisons like this on large data, you might want to look for more efficient approaches, such as using regular expressions or precomputing the calculation - either with Tableau Prep Builder or by creating an extract.
If this is a direct copy of your calculated field though, you are missing a piece on you second row:
ELSEIF [fruit_description], "juicy") =true then "exclude"
should be
ELSEIF CONTAINS([fruit_description], "juicy") =true then "exclude"
Related
I'm working on a student survey project. The model that stores the questions is something like:
ID Question Type
1 is good teacher? Choice
2 What do you like about Open-answer
the teacher?
Then in the choice type questions the student will choose an option (e.g.: fully agree) and this will store a numerical code (e.g. 5). But in the open-answer questions , the student will write text.
what kind of field should store these answers in the answers model? maybe TextField?
You ur choices as text if you want to use same column to open text... so instead of set 1,2,3,4 you can write a fixed text when user select the options, so this make your data more readeble
ANSWER = (
("Yes", "Yes"),
("No", "No"),
("Neutral", "Neutral"),
)
Or make 2 more columns... one to set type of question (select or text) and the other to store the options (that way you can setup as foreign key and instead of use static values this can be loaded from one model)
ID Question Type Answer-Text AnswerID
1 is good teacher? Choice null 1
2 What do you like about Open-answer "The way he swag" null
the teacher?
Or mix everything with String... but you will have some troubles getting this integer ids... will throw some erros when you try to get it as integer int("1") Will work but int("The way he swag") will raise a error
Using a TextField would probably be a bad idea since you're mixing int with string type objects which is definitely not recommended.
One thing you could do is consider this as two different fields. One Choicefield and one TextField. That way the user can choose an empty value (empty string '') when he wants to use the open-answer. You can then compute empty strings as being nothing later on.
What is a proper way to associate an AggregateCall that is part of a HAVING expression with a corresponding field in a RelRecordType for the LogicalAggregate? If the AggregateCall is not part of the SELECT clause, the LogicalAggregate's RelRecordType still has it, but the AggregateCall's name attribute is set to NULL and RelRecordType.getField(AggregateCall.getName()) can't be used in this case. If the AggregateCall is a part of the final output, its name is set and RelRecordType.getField(AggregateCall.getName()) returns the right field.
Use field ordinals rather than names.
In the world of Calcite RelNodes and RexNodes, field names are not that important; they exist mainly to help you understand the purpose of fields when debugging. Names of AggregateCalls are even less important; they exist so that Aggregate can give reasonable names to its fields, and if they don't exist, that's fine.
If your SELECT has N fields (numbered 0 .. N-1) and a HAVING clause, you will likely add the HAVING predicate as field N, apply a Filter relational operator, then apply a Project so that only fields 0 .. N-1 are returned. I'm pretty sure that this is what SqlToRelConverter does already.
With the following Django model:
class Item(models.Model):
name = CharField(max_len=256)
description = TextField()
I need to formulate a filter method that takes a list of n words (word_list) and returns the queryset of Items where each word in word_list can be found, either in the name or the description.
To do this with a single field is straightforward enough. Using the reduce technique described here (this could also be done with a for loop), this looks like:
q = reduce(operator.and_, (Q(description__contains=word) for word in word_list))
Item.objects.filter(q)
I want to do the same thing but take into account that each word can appear either in the name or the description. I basically want to query the concatenation of the two fields, for each word. Can this be done?
I have read that there is a concatenation operator in Postgresql, || but I am not sure if this can be utilized somehow in django to achieve this end.
As a last resort, I can create a third column that contains the combination of the two fields and maintain it via post_save signal handlers and/or save method overrides, but I'm wondering whether I can do this on the fly without maintaining this type of "search index" type of column.
The most straightforward way would be to use Q to do an OR:
lookups = [Q(name__contains=word) | Q(description__contains=word)
for word in words]
Item.objects.filter(*lookups) # the same as and'ing them together
I can't speak to the performance of this solution as compared to your other two options (raw SQL concatenation or denormalization), but it's definitely simpler.
Given a model with both Boolean and TextField fields, I want to do a query that finds records that match some criteria AND have more than "n" words in the TextField. Is this possible? e..g.:
class Item(models.Model):
...
notes = models.TextField(blank=True,)
has_media = models.BooleanField(default=False)
completed = models.BooleanField(default=False)
...
This is easy:
items = Item.objects.filter(completed=True,has_media=True)
but how can I filter for a subset of those records where the "notes" field has more than, say, 25 words?
Try this:
Item.objects.extra(where=["LENGTH(notes) - LENGTH(REPLACE(notes, ' ', ''))+1 > %s"], params=[25])
This code uses Django's extra queryset method to add a custom WHERE clause. The calculation in the WHERE clause basically counts the occurances of the "space" character, assuming that all words are prefixed by exactly one space character. Adding one to the result accounts for the first word.
Of course, this calculation is only an approximation to the real word count, so if it has to be precise, I'd do the word count in Python.
I dont know what SQL need to be run in order for the DB to do the work, which is really what we want, but you can monkey-patch it.
Make an extra fields named wordcount or something, then extend the save method and make it count all the words in notes before saving the model.
The it is trivial to loop over and there is still no chance that this denormalization of data will break since the save method is always run on save.
But there might be a better way, but if all else fails, this is what I would do.
I have some codes like this:
cats = Category.objects.filter(is_featured=True)
for cat in cats:
entries = Entry.objects.filter(score>=10, category=cat).order_by("-pub_date")[:10]
But, the results just show the last item of cats and also have problems with where ">=" in filter. Help me solve these problems. Thanks so much!
You may want to start by reading the django docs on this subject. However, just to get you started, the filter() method is just like any other method, in that it only takes arguments and keyword args, not expressions. So, you can't say foo <= bar, just foo=bar. Django gets around this limitation by allowing keyword names to indicate the relationship to the value you pass in. In your case, you would want to use:
Entry.objects.filter(score__gte=10)
The __gte appended to the field name indicates the comparison to be performed (score >= 10).
Your not appending to entries on each iteration of the for loop, therefore you only get the results of the last category. Try this:
entries = Entry.objects.filter(score__gte=10, category__is_featured=True).order_by("-pub_date")[:10]