Exception in case statement - psql

How would you throw an exception in a case statement? I believe signal is the correct statement. The case statement is when the word 'corp' is found in the name then have a 1 in the column but I want an exception if the word 'dollar' is in the name
Name Is_comp
Dollar Tree Corp
First Hand Corp 1
Select
when name like 'corp'
then 1
end as is_comp

I think, based on what you are looking for, you just need a fancier CASE statement:
SELECT
CASE
WHEN
name LIKE ANY ('%corp%','%llc%','%inc%') /*list of names with wildcards*/
AND name not like '%Finch%' /*don't match on finch%/
AND name not like ANY ('%Finch%','%Brian%') /*or optionally don't match on any of these name substrings*/
THEN 1
END 'is_comp'
FROM <table>

Related

neo4j case statement in Foreach

whats the most efficient way to write this query. The problem. I have a set of 3500 names of boys and girls who play basketball. I want to assing a relationship to them as to they belong_to toddlers, youth, teenagers based on their age group.
I am unable to do a case statement inside a foreach.
Match(b:BoysandGirls)
UNWIND (b.name) as namelist
FOREACH (fullname in namelist |
MERGE(b1:BoysandGirls {name:fullname})
CASE WHEN b1.age < 6 THEN
MERGE(t1:KidsType {group:"Toddler"}) // this groups already exist
MERGE(b1)-[BELONGS_TO]->(t1)
END
)
// i have more groups like youth and teenager... but not sure
I get an error Invalid input ... expected 1/L.. at CASE statement.
what am i doing wrong ?
FOREACH only permits mutating operations, but CASE is not a mutating operation (and CASE also cannot contain match/mutating operations). Aside from those issues, I think you are also confused about what UNWIND does -- you probably meant COLLECT instead. But I don't think you need to use COLLECT and FOREACH at all (since they basically cancel each other out).
This much simpler query might be all you need:
MATCH (bg:BoysandGirls)
WHERE bg.age < 6
MATCH (t:KidsType {group:"Toddler"})
MERGE (bg)-[:BELONGS_TO]->(t);
It finds all BoysandGirls younger than 6 and ensures that they are related (via the BELONGS_TO relationship type -- note the required preceding colon) to the "Toddler" KidsType.

Order by last name

I am trying to set the default scope for my User model. Each user has one name column. The problem is that I would like to order users by the first letter of their last name. This would be the start of the last word from the name. For example, a users name may be "Kevin John Smith", I would like to order by Smith. I currently have default_scope order('name ASC'), but this sorts by the first letter of the first name. How would I convert this to sort by the first letter of the last name? Thanks!
Try this:
User.select("users.*, SUBSTRING_INDEX(users.name, ' ', -1) AS lastname").limit(10).order('lastname ASC')
SUBSTRING_INDEX is one of the mySQL string functions.
For PostgreSQL split_part should work:
User.select("users.*, split_part(users.name, ' ', 3) AS lastname").limit(10).order('lastname ASC')
I am not sure, though try with -1 too:
User.select("users.*, split_part(users.name, ' ', -1) AS lastname").limit(10).order('lastname ASC')
Because, the latter one will ensure that the last string after split is used which will cover the cases where user has just first name and last name.
Make sure you use unscoped, which returns a scope for this class without taking into account the default_scope.

Find record with LIKE on partial attribute

In my app I have invoice numbers like this:
2014.DEV.0001
2014.DEV.0002
2014.TSZ.0003
The three character code is a company code. When a new invoice number needs to be assigned it should look for the last used invoice number for that specific company code and add one to it.
I know the company code, I use a LIKE to search on a partial invoice number like this:
last = Invoice.where("invoice_nr LIKE ?", "#{DateTime.now.year}.#{company_short}.").last
This results in this SQL query:
SELECT "invoices".* FROM "invoices" WHERE "invoices"."account_id" = 1 AND (invoice_nr LIKE '2014.TSZ.') ORDER BY "invoices"."id" DESC LIMIT 1
But unfortunately it doesn't return any results. Any idea to improve this, as searching with LIKE doesn't seem to be correct?
Try wrapping string with % and use lower to convert the query string and result into downcase to avoid any wrong results due to case, try this
last = Invoice.where("lower(invoice_nr) LIKE lower(?)", "%#{DateTime.now.year}.#{company_short}.%").last
You want % for partial match
last = Invoice.where("invoice_nr LIKE ?", "%#{DateTime.now.year}.#{company_short}.%").last
Since you want to match only the left part you need to add one % at the right part of your string
Invoice.where("invoice_nr LIKE ?", "#{DateTime.now.year}.#{company_short}.%").last

How do I use TADOQuery.Parameters with integer parameter types that have to be put in two or more places in a query?

I have a complex query that contains more than one place where the same primary key value must be substituted. It looks like this:
select Foo.Id,
Foo.BearBaitId,
Foo.LinkType,
Foo.BugId,
Foo.GooNum,
Foo.WorkOrderId,
(case when Goo.ZenID is null or Goo.ZenID=0 then
IsNull(dbo.EmptyToNull(Bar.FanName),dbo.EmptyToNull(Bar.BazName))+' '+Bar.Strength else
'#'+BarZen.Description end) as Description,
Foo.Init,
Foo.DateCreated,
Foo.DateChanged,
Bug.LastName,
Bug.FirstName,
Goo.BarID,
(case when Goo.ZenID is null or Goo.ZenID=0 then
IsNull(dbo.EmptyToNull(Bar.BazName),dbo.EmptyToNull(Bar.FanName))+' '+Bar.Strength else
'#'+BarZen.Description end) as BazName,
GooTracking.Status as GooTrackingStatus
from
Foo
inner join Bug on (Foo.BugId=Bug.Id)
inner join Goo on (Foo.GooNum=Goo.GooNum)
left join Bar on (Bar.Id=Goo.BarID)
left join BarZen on (Goo.ZenID=BarZen.ID)
inner join GooTracking on(Goo.GooNum=GooTracking.GooNum )
where (BearBaitId = :aBaitid)
UNION
select Foo.Id,
Foo.BearBaitId,
Foo.LinkType,
Foo.BugId,
Foo.GooNum,
Foo.WorkOrderId,
Foo.Description,
Foo.Init,
Foo.DateCreated,
Foo.DateChanged,
Bug.LastName,
Bug.FirstName,
0,
NULL,
0
from Foo
inner join Bug on (Foo.BugId=Bug.Id)
where (LinkType=0) and (BearBaitId= :aBaitid )
order by BearBaitId,LinkType desc, GooNum
When I try to use an integer parameter on this non-trivial query, it seems impossible to me. I get this error:
Error
Incorrect syntax near ':'.
The query works fine if I take out the :aBaitid and substitute a literal 1.
Is there something else I can do to this query above? When I test with simple tests like this:
select * from foo where id = :anid
These simple cases work fine. The component is TADOQuery, and it works fine until you add any :parameters to the SQL string.
Update: when I use the following code at runtime, the parameter substitutions are actually done (some glitch in the ADO components is worked around) and a different error surfaces:
adoFooContentQuery.Parameters.FindParam('aBaitId').Value := 1;
adoFooContentQuery.Active := true;
Now the error changes to:
Incorrect syntax near the keyword 'inner''.
Note again, that this error goes away if I simply stop using the parameter substitution feature.
Update2: The accepted answer suggests I have to find two different copies of the parameter with the same name, which bothered me so I reworked the query like this:
DECLARE #aVar int;
SET #aVar = :aBaitid;
SELECT ....(long query here)
Then I used #aVar throughout the script where needed, to avoid the repeated use of :aBaitId. (If the number of times the parameter value is used changes, I don't want to have to find all parameters matching a name, and replace them).
I suppose a helper-function like this would be fine too: SetAllParamsNamed(aQuery:TAdoQuery; aName:String;aValue:Variant)
FindParam only finds one parameter, while you have two with the same name. Delphi dataset adds each parameter as a separate one to its collection of parameters.
It should work if you loop through all parameters, check if the name matches, and set the value of each one that matches, although I normally choose to give each same parameter a follow-up number to distingish between them.

how to find items that aren't part of the alphabet

In my view I have an alphabet based selector, to select manufacturers by the first letter of their name. I got that part working. But I have manufacturers whose name starts with a number, for example 3M, or 3DLabs. In the view I have the character "#" to group all those. What should my query/find method look like to retrieve all names that don't start with an alphabet letter.
You probably want to use a Regular Expression.
What language are you using?
Here is the SQL2005 version:
select *
from myTable
where myField like '[^a-z]%'
I think I got it
SELECT * FROM manufacturers WHERE ( name REGEXP '^[0-9]') ORDER BY name

Resources