Is there a way to do this without CASE expression? - postgresql

I would like to avoid so often using CASE expressoin, especially for not so complicated logic like here. Is there a better way?
CASE
WHEN lower(player_status::text) in ( 'active'::text,'live'::text)
THEN true
ELSE false
END
Can I get the same output without CASE?
Thanks!

Actually you don't need the CASE expression.
You can directly select the boolean expression:
SELECT COALESCE(lower(player_status::text), '') IN ('active'::text, 'live'::text)
FROM ...
The function COALESCE() is used to prevent the expression to return NULL in case player_status is NULL.
If player_status is not nullable it can be omitted:
SELECT lower(player_status::text) IN ('active'::text, 'live'::text)
FROM ...

So I gather the end result you are looking for is a list of usernames and user statuses, but for users having the status "active" or "live" you wish to display the boolean true instead of the value actually stored in the database, right? The accepted answer works, but personally I find it a little easier to read using select constants:
SELECT name, true as player_status
FROM players.player_data
WHERE player_status IN ('active', 'live')
This will present only active/live players and their status will be displayed as true. If you need the query to return all players, regardless of status, while still making the text substitution for active players, you can simply union together the above query with its inverse, though I'm not sure this is any less complex or readable than the other two proposed solutions in this thread:
SELECT name, true as player_status
FROM players.player_data
WHERE player_status IN ('active', 'live')
UNION ALL
SELECT name,false
FROM players.player_data
WHERE (player_status is null)
OR (player_status NOT IN ('active', 'live'))
That all said, personally, I'd probably make this substitution at the UI layer, not in the database query, which would make the whole matter moot, though that's more a matter of personal preference than.

Related

How can I achieve IF ALL ELSE, in Decision Table?

Drools 5.4
I have a decision table that sets values in the BlueReport object based on Channel Name attribute. Everything works, except if a Channel name contains an unknown channel for which we don't have mappings, we need to set the values to indicate this condition. The picture below should illustrate this more clearly, I'm sure. Here is what we want:
How can we achieve the "ALL OTHERS" default condition?!
I've evolved my spreadsheet rules to this now:
In this version of DT above, I have left B15 blank, and then I have added a new condition on C15 which checks the auditRule field for presence of string variable "DIV". I don't know if I have the right syntax for it in C9?! The ruleAudit field is update everytime there is a match for Channel Name (F11 - F15). Therefore, absence of DIV rule name, would indicate that there is no match to any of the patterns on B11 - B14. What do you think?!
Add a new condition column again with declaration for blueReport and set this condition
channel_name!=$1 || channel_name!=$2 ||channel_name!=$3 || channel_name!=$4
New Condition's value field must be empty for the first four records except these values like ChannelName1,ChannelName2,ChannelName3,ChannelName4 in "ALL OTHERS" row. Though this isn't the standard solution try this workaround to check
I think the post can help you. It means you should not only declare sequential in the RuleSet, but also declare PRIORITY in RuleTable that the rules will be called according to the value of PRIORITY.

Make an object that can be compared and hashed with variable attributes, in Python

I am working on a package that deals with citations and most of them are of the form
Author, Year, Journal, Volume, Page, DOI
So a a string with series of fields separated by commas.Unfortunately some (~5%) are missing one (or often more than one) of these fields.
To do useful things with them I need to be able to check if two are the same ignoring a field if it is missing. I have an __eq__(self, other) defined that does this with a series of if statements like this:
elif hasattr(self, 'V') and hasattr(other, 'V') and getattr(self, 'V') != getattr(other, 'V'):
return False
The one constant about the citations is that author is present and at least one of year or journal is too.
I feel like there should be a much faster way of doing this, but have not been able to come up with one. Is there a faster way of doing this as that would really help with processing?
Rather than using a long if/elif chain and explicitly returning Fase if a condition finds a mismatch, you can chain together the comparisons directly in a Boolean expression with and:
return (self.author == other.author and
self.year == other.year and
self.journal == other.journal
...)
You can keep using your getattr calls if you want, but I'd suggest moving the logic to fill in None for missing values into the initialization code, rather than needing to repeat it anywhere you check the attributes. That way you'll always have the attributes you expect, ones that don't have meaningful data will simply have None as their value.
Note that the current behavior of your getattr code doesn't quite match the description you give of your desired behavior ("check if two are the same ignoring a field if it is missing"). The current code will return False if an attribute is present in one citation and not in another, even if the rest of the values match up. If you want the behavior to match your description, use something like this:
not (hasattr(self, "year") and (hasattr(other, "year")) or self.year == other.year
Or (if you do year = None in __init__ if there's no year specified):
None in (self.year, other.year) or self.year == other.year

command level parameters in crystal reports

I have a report having 2 parameters carton and location.
Suppose if I didn't gave any value among those then it should give all values.
So created 2 command level parameters.Its showing all values whenever I didnt gave any values in parameters.
But even If I gave some value in either carton or location but still its showing all values.
Please suggest what is the problem
SELECT
crt.carton_no, crtd.part_no, SUM(crtd.quantity) AS quantity,
crtd.barcode, crtd.item_description
, crt.put_away_location AS putAway
FROM
carton crt, carton_details crtd
WHERE
crt.carton_id = crtd.carton_id
AND crt.status = 'N' AND
( crt.carton_no like '{?cartonno}' or '{?cartonno}' like '%' ) and (crt.put_away_location LIKE '{?location}' or '{?location}' like '%')
GROUP BY
crt.carton_no, crtd.carton_id, crtd.part_no
ORDER BY
crt.put_away_location, crt.carton_no
I guess your query is always taking true ignoring or condition... try using Case
where
CASE WHEN {?cartonno} Like ""
THEN
'{?cartonno}' like '%'
ELSE
crt.carton_no like '{?cartonno}'
END
Note: I don't know which database you are using above is just an example of SQL... you can change it as required and use similarly for other parameter in where clause

T-SQL SELECT Statment to Exclude Text Between ( And ) Without Update or Variables

I'm wondering if this is possible, I have a messy set of first name data to work with, and it's shared by other applications so I don't want to run any update statements. But the data will sometime include an AKA such as:
Robert (AKA Bob)
And I am trying to get a clean data where it just says "Robert".
One way I thought of is to use a temp table then CHARINDEX for ( and ) then REPLACE what's between ( and ). This seems like a long winded way to do this.
Is there a smarter way?
EDIT: More examples of the data hell. Sometimes the parenthesis comes in the front or mixed up such as:
(Bill) William
Richard (Dick) Jr.
Untested:
FirstName = case when charindex('(AKA', FirstName) = 0
then FirstName
else substring(FirstName, 1, charindex('(AKA', FirstName)) end
If the noisy string pattern is unpredictable, better to use SQL CLR TVF(table value function), utilize C# code regex. Taking an xml as input parameter, which includes data you need to process, return a table with data processed.
Pieter got the ball rolling for me! Thank you for getting me started on the right track!
SELECT
CASE WHEN FirstName like '%)%'
THEN REPLACE(FirstName,
SUBSTRING(FirstName,CHARINDEX('(',FirstName),CHARINDEX(')',FirstName)-CHARINDEX('(',FirstName)+1),'')
ELSE FirstName END

How can i store the result of a comparison into a variable

I want to print a simple statement
print (1=1), i expect the result to be TRUE or 1 but sql server tell me:
Incorrect syntax near '='.
why is that?
Same will happen for a statement like that
declare #test bit
set #test = (1=1)
in summary how can i "see" what is returned from a comparison without using an IF statement
Update: The reason i'm asking is because i'm trying to debug why the following statement
declare #AgingAmount smallint
set #AgingAmount = 500
select Amount, datediff(day,Batch.SubmitDate,getdate()) as Aging from myreporrt
where datediff(day,Batch.SubmitDate,getdate()) > #AgingAmount
will return all rows even with aging of 300
so i wanted to test if datediff(day,datesubmited,getdate()) > 500 returns true or false but could not find a way how to display the result of this comparison.
Although SQL Server has the concept of aboolean type, and it understands expressions that resolve to a boolean in IF and WHERE clauses, it does not support declaring boolean variables or parameters. The bit data type cannot store the result of a boolean expression directly, even though it looks suspiciously like one.
The nearest you can get to a boolean data type is this:
-- Store the result of a boolean test.
declare #result bit
select #result = case when <boolean expression> then 1 else 0 end
-- Make use of the above result somewhere else.
if #result = 1
...
else
...
To add to the confusion, SQL Server Management Studio treats bit like boolean when displaying results, and ADO.NET maps bit to System.Boolean when passing data back and forth.
Update: To answer your latest question, use the case when ... then 1 else 0 end syntax in the select statement.