I've got a polymorphic table that needs to be ordered, but the column to use for ordering depends on the type field of the table. Something like this:
ORDER BY CASE WHEN type=FOO THEN (table.last_name, table.first_name) ELSE table.name END
However, this doesn't work, can anybody point me in the right direction, I'm trying to say (in psuedocode)
IF type is FOO sort by last_name, first_name ASC OTHERWISE sort by name ASC
Could be you need a case for each column
ORDER BY CASE WHEN type=FOO THEN (table.last_name) ELSE table.name END,
CASE WHEN type=FOO THEN (table.first_name) ELSE null END
You need to specify it with two fields:
ORDER BY
CASE WHEN type=FOO THEN table.last_name ELSE table.name END,
CASE WHEN type=FOO THEN table.first_name ELSE '' END
Related
I have the following MYSQL query which creates table as select statement but having a case statment to change field formats to numbered fields to compare:
CREATE TABLE wm.bochg
AS
SELECT
wca.bochg.BochgID,
wca.bochg.SecID,
wca.bochg.OldOutValue,
wca.bochg.NewOutValue,
case when NewOutValue+0.0 >= OldOutValue+0.0 then NewOutValue ELSE '' END AS test2
from wca.bochg
WHERE
wca.bochg.SecID in (select secid from client.pfisin where accid = 416)
AND (wca.bochg.BochgID is null or wca.bochg.BochgID =
(select subbochg.BochgID from wca.bochg as subbochg
where subbochg.secid=bochg.secid
AND subbochg.Actflag <> 'D'
AND subbochg.NewOutValue+0.0 >= subbochg.OldOutValue+0.0
order by subbochg.BochgID desc limit 1)
or wca.bochg.BochgID is NULL);
However I am getting warnings when this is created saying:
'Truncated incorrect DOUBLE value: '' '
This is due to my case statment and the and clause within my subquery. Is there a way to cater for this issue and get rid of the warning message above going forward? Thanks
You are mixing datatypes in the case statement. Use something else than a string '' for the ELSE part (NULL, 0 or anything that suits your purpose).
I have a table like below
From this table, I want to get the counts of SearchParams, which I tried like this:
But I want all the data which is matching the pattern "TVE-xxxx" should be combined as "TVE" and the count.
Please help.
Use a CASE statement to determine the value on which you group by:
select
case when searchParam like 'TVE-%' then 'TVE' else searchParam end groupParam,
count(*) counter
from careinsight.testtable
group by groupParam
To filter data with pattern "TVE-xxx" , use below query
select name,count(name)
from tblName
where name REGEXP '^TVE\-[a-zA-Z]{3}$'
group by name
If you have known differences in pattern, you can use CASE/WHEN to summarize your output as below. This case you have to know the list of value may come for one group like 'Account' and you need to put them in the list of IN for the CASE statement.
SELECT
CASE
WHEN searchParam IN ('AccountSVNC','AccountSVNC') THEN 'Account'
WHEN searchParam IN ('TVE-ABC','TVE-CDE','TVE-MFG') THEN 'TVE'
ELSE searchParam
END searchParam,
COUNT(searchParam)
FROM your_table
GROUP BY
CASE
WHEN searchParam IN ('AccountSVNC','AccountSVNC') THEN 'Account'
WHEN searchParam IN ('TVE-ABC','TVE-CDE','TVE-MFG') THEN 'TVE'
ELSE searchParam
END
I have a stored procedure that must return a table after filtering rows based on inputs. Two of the inputs are sort_column and sort_dir. The query must ORDER BY sort_column in the sort_dir direction(ASC or DESC).
I have tried the following queries but in vain. The queries below have been simplified to only contain the relevant clauses. The other filters work correctly with no issues.
SELECT * FROM table ORDER BY sort_column sort_dir
SELECT * FROM table ORDER BY CASE sort_column
WHEN 'col1' THEN col1_name
WHEN 'col2' THEN col2_name END
CASE sort_dir WHEN 'asc' THEN ASC
ELSE DESC END
I concatenated the 2 inputs to 1 in the format _ and tried this:
SELECT * FROM table ORDER BY CASE sort_input
WHEN 'col1_asc' THEN col1_name ASC
WHEN 'col1_desc' THEN col1_name DESC
WHEN 'col2_asc' THEN col2_name ASC
WHEN 'col2_desc' THEN col2_name DESC END
I always get error #1064. It is different in each of the above cases but always points to the 'CASE' part. This is the error for option number 2 mentioned above
##1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHEN 'col1' THEN col1_name END CASE 'asc' WHEN 'desc' THEN DESC ELSE ' at line 4
The problem doesn't seem to be the column name. It is the sort direction that isn't working. If I try each of the above options without the 'ASC' and 'DESC' parts, there is no problem.
Am I doing anything wrong here?
Is there a better way to go about this apart from CASE?
MySQL version: 5.6
The best approach is multiple cases:
ORDER BY (CASE WHEN sort_input = 'col1_asc' THEN col1_name END) ASC,
(CASE WHEN sort_input = 'col1_desc' THEN col1_name END) DESC,
(CASE WHEN sort_input = 'col2_asc' THEN col2_name END) ASC,
(CASE WHEN sort_input = 'col2_desc' THEN col2_name END) DESC,
This may seem verbose. But, remember that CASE is an expression that returns a single value. Hence you cannot include ASC and DESC as part of the THEN.
Also important is the issue of data types. The SQL compiler decides on a single type for CASE expression. This can cause unexpected issues when the columns have different types.
The simplest solution is just to use multiple CASE expressions.
When an SQL query returns null, I'm wondering if it's possible to have it return a specific string like "Unknown" instead of null.
I'm currently doing this on the JavaScript side and was wondering if there's a faster way to do this on the server.
Example (I realize the following syntax doesn't exist):
SELECT Customers.Email (RETURN "Unknown" IF NULL)
I imagine it's possible with a CASE? But filling up my query with CASE statements will slow this whole action down rather than speed it up.
You can use coalesce:
SELECT COALESCE(email, 'Unknown')
FROM customers
In MySQL you can use IFNULL
SELECT IFNULL(Customers.Email, 'Unknown') AS Email
While COALESCE is the best solution, there is also CASE
This can be handy if you have to deal with either nulls or empty strings.
SELECT CASE Customers.Email
WHEN NULL THEN 'Unknown'
WHEN '' THEN 'Unknown'
ELSE Customers.Email
END AS Email
FROM Customers;
SELECT CASE
WHEN Customers.Email IS NULL THEN 'Unknown'
WHEN TRIM(Customers.Email) = '' THEN 'Unknown'
ELSE Customers.Email
END AS Email
FROM Customers;
I'm working in a procedure that returns a huge select where I wan't define how it is order.
I wan't choose one of three fields and if it will be ascending or descending, if none of the three options was define, it returns by default the first field in descending
this way
ORDER BY
CASE option1
WHEN 0 THEN
CASE option2
WHEN 0 THEN firstField DESC
WHEN 1 THEN firstField ASC
END
WHEN 1 THEN
CASE option2
WHEN 0 THEN secondField DESC
WHEN 1 THEN secondField ASC
END
WHEN 2 THEN
CASE option2
WHEN 0 THEN thirdField DESC
WHEN 1 THEN thirdField ASC
END
ELSE
firstField DESC
END
END;
Of course, this didn't work... mysql acuses errors in words 'DESC' and 'ASC', how can I make this works??
In order to do this, you have to move the DESC/ASC to outside the case as they come after the expression.
You should also separate the fields. In a CASE statement if the fields have different datatypes, they will be converted into one that fits all (usually VARCHAR) and this can mess up the ordering.
You could do something like:
ORDER BY CASE WHEN option1=0 AND option2=0 THEN firstField END DESC,
CASE WHEN option1=0 AND option2=1 THEN firstField END ASC,
CASE WHEN option1=1 AND option2=0 THEN secondField END DESC,
CASE WHEN option1=1 AND option2=1 THEN secondField END ASC,
CASE WHEN option1=2 AND option2=0 THEN thirdField END DESC,
CASE WHEN option1=2 AND option2=1 THEN thirdField END ASC,
firstField DESC
Each case will return NULL for all rows when not applicable and thus have the same value. In fact the first case is unnecessary as it will be caught by the default, but I have included it for clarity. This may result in a hugely expensive ordering process however!
I think I'd much rather dynamically build the SQL and I'd use an array of allowed ordering values to keep it secure.