How do I change mysql output based on value - mysql

For example, if queue_watch shows a 0, I want the actual mysql output to say No, else say Yes. Changing the scheme is not an option.
SELECT user.user_name, queue.queue_name, queue_access.queue_access,
queue_access.queue_watch
FROM queue_access
INNER JOIN user ON user.user_id = queue_access.user_id
INNER JOIN queue ON queue.queue_id = queue_access.queue_id
WHERE queue_access <> '' OR queue_watch = 1
ORDER BY user_name;
The SQL works for what I need, but I like to know if changing the output using SQL rather than PHP is possible. Also, is it possible to group all the queue_names in one row to each user_name so I don't have to have 153 rows returned.
Thanks

It not an over head. It is better to be done in the query, I feel.
Try this -
SELECT user.user_name, queue.queue_name, queue_access.queue_access,
IF(queue_access.queue_watch = 0, 'No', 'Yes')
FROM queue_access
INNER JOIN user ON user.user_id = queue_access.user_id
INNER JOIN queue ON queue.queue_id = queue_access.queue_id
WHERE queue_access <> '' OR queue_watch = 1
ORDER BY user_name;

You can use the standard CASE expression. There are two slightly different ways to write a CASE expression.
Simple case expression:
SELECT
CASE queue_access.queue_watch
WHEN 0 THEN 'No'
ELSE 'Yes'
END AS your_alias,
...
Searched case expression:
SELECT
CASE WHEN queue_access.queue_watch = 0 THEN 'No' ELSE 'Yes' END AS your_alias,
...
Or you could use the MySQL specific IF construct:
SELECT
IF(queue_access.queue_watch, 'Yes', 'No') AS your_alias,
...
You may want to consider what should happen if your value is something other than 0 or 1.

Related

SQL IF ELSE WITH MULTIPLE SELECT STATEMENT

I want to optimize these SQL queries using if-else but how I should use it? .
if this query result contain 'ALL'
SELECT
bdsubcategory.subcategoryID as ID,
bdsubcategory.subcategoryName as Name
FROM
phonebook.newsms_subscription
INNER JOIN bdsubcategory ON bdsubcategory.subcategoryID = newsms_subscription.subcategoryID
INNER JOIN newsms_client ON newsms_subscription.clientID =newsms_client.clientID
INNER JOIN newsms_person ON newsms_subscription.personID = newsms_person.personID
WHERE
newsms_subscription.isActive = 1 AND
newsms_person.personID = '856'
Then i want to query this
SELECT
bdsubcategory.subcategoryID as ID,
bdsubcategory.subcategoryName as Name
FROM
phonebook.newsms_subscription
INNER JOIN bdsubcategory ON bdsubcategory.subcategoryID = newsms_subscription.subcategoryID
INNER JOIN newsms_person ON newsms_subscription.personID = newsms_person.personID
WHERE
newsms_subscription.isActive = 1
GROUP BY subcategoryName
ORDER BY subcategoryName
otherwise take query1 result .
The problem is that if we do not refactor your project, then you always have to evaluate query1 and see whether it contains All or not. If it does not contain All, then you need to evaluate query2 as well. This can hardly be optimized, let's see a few approaches:
Quickening query1
Since All might be not be the very last evaluated element, adding it to the filter and limiting it is a good idea to quicken query1:
SELECT
COUNT(*)
FROM
phonebook.newsms_subscription
INNER JOIN bdsubcategory ON bdsubcategory.subcategoryID = newsms_subscription.subcategoryID
INNER JOIN newsms_client ON newsms_subscription.clientID =newsms_client.clientID
INNER JOIN newsms_person ON newsms_subscription.personID = newsms_person.personID
WHERE
newsms_subscription.isActive = 1 AND
newsms_person.personID = '856' AND
bdsubcategory.subcategoryName = 'ALL'
LIMIT 0, 1
So, you could create a stored procedure which evaluates query1' (query1' is the quickened version of query1, as seen above) and if there is a result, then we need to execute query1. Otherwise we need to execute query2. This way you still execute two queries, but the first query is optimized.
Refactoring
Note that the second query does not change. You could create a table where you could cache its results, using a periodic job. Then, you could skip the second table to
SELECT ID, Name
FROM MyNewTable;
without the many joins. You would also cache the results of the first query into a table where the items having ALL would be stored and query that table.
One option would be to use a CASE.
Change this:
newsms_person.personID = '856'
To this:
'Y' = CASE WHEN UPPER('856') = 'ALL' THEN 'Y'
WHEN newsms_person.personID = '856' THEN 'Y'
ELSE 'N' END
Alternatively, a stored procedure could be used to first validate whether the personID seems valid, then returns the appropriate data.

MySQL: Get total number of customers and total of each status within a store [duplicate]

I have two tables, one is for news and the other one is for comments and I want to get the count of the comments whose status has been set as approved.
SELECT
ccc_news . *,
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments
FROM
ccc_news
LEFT JOIN
ccc_news_comments
ON ccc_news_comments.news_id = ccc_news.news_id
WHERE
`ccc_news`.`category` = 'news_layer2'
AND `ccc_news`.`status` = 'Active'
GROUP BY
ccc_news.news_id
ORDER BY
ccc_news.set_order ASC
LIMIT 20
But the problem with this query is that the minimum value that is fetched for the comments column is 1 whether there is any comment existent corresponding to that news or not.
Any help would be highly appreciable.
Use sum() in place of count()
Try below:
SELECT
ccc_news . * ,
SUM(if(ccc_news_comments.id = 'approved', 1, 0)) AS comments
FROM
ccc_news
LEFT JOIN
ccc_news_comments
ON
ccc_news_comments.news_id = ccc_news.news_id
WHERE
`ccc_news`.`category` = 'news_layer2'
AND `ccc_news`.`status` = 'Active'
GROUP BY
ccc_news.news_id
ORDER BY
ccc_news.set_order ASC
LIMIT 20
Better still (or shorter anyway):
SUM(ccc_news_comments.id = 'approved')
This works since the Boolean type in MySQL is represented as INT 0 and 1, just like in C. (May not be portable across DB systems though.)
As for COALESCE() as mentioned in other answers, many language APIs automatically convert NULL to '' when fetching the value. For example with PHP's mysqli interface it would be safe to run your query without COALESCE().
This should work:
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, NULL))
count() only check if the value exists or not. 0 is equivalent to an existent value, so it counts one more, while NULL is like a non-existent value, so is not counted.
Replace this line:
count(if(ccc_news_comments.id = 'approved', ccc_news_comments.id, 0)) AS comments
With this one:
coalesce(sum(ccc_news_comments.id = 'approved'), 0) comments
count(ccc_news_comments.id = 'approved' or null)
More concise

Concat reults when using case in statement

I've seen this question arise and seen it answered numerous times but not exactly they way in which I need. I have the following query
SELECT DISTINCT ia.UserName, ia.FirstName, ia.LastName, ia.`Password`,
CASE ipt.Code
WHEN ipt.Code LIKE "%CORP_FILE%" THEN "ROLE_GAAP"
WHEN ipt.Code LIKE "%RR_SUMMARY%" THEN "ROLE_RR"
END
AS "role"
FROM
iCTrunk.Account ia,
iCTrunk.AccountGroup ig,
iCTrunk.asscAccountAccountGroup iaaag,
iCTrunk.asscNodeAccountGroup ianag,
iCTrunk.asscNodeProjectType ianpt,
iCTrunk.ProjectType ipt
WHERE ia.Id = iaaag.AccountId
AND iaaag.AccountGroupId = ianag.AccountGroupId
AND ianag.NodeId = ianpt.NodeId
AND ianpt.ProjectTypeId = ipt.Id
AND ia.UserName = '<some user here>'
There are 2 possible result sets from the query and most users will only return 1. The issue is that if the user is an administrator then both query results will be returned. I am trying to figure out a way to group_concat the "role" field so that I only get a single returned row. Since the row result is being read by an authentication login page it would be much easier to process a single returned result.
Thank you in advance.
Just need to add the group_concat syntax and a group by; and I moved the distinct to be in the group_concat so you only get 0-2 results in the "Role" field.
SELECT ia.UserName, ia.FirstName, ia.LastName, ia.`Password`,
GROUP_CONCAT(DISTINCT CASE ipt.Code
WHEN ipt.Code LIKE "%CORP_FILE%" THEN "ROLE_GAAP"
WHEN ipt.Code LIKE "%RR_SUMMARY%" THEN "ROLE_RR"
END) AS "role"
FROM
iCTrunk.Account ia,
iCTrunk.AccountGroup ig,
iCTrunk.asscAccountAccountGroup iaaag,
iCTrunk.asscNodeAccountGroup ianag,
iCTrunk.asscNodeProjectType ianpt,
iCTrunk.ProjectType ipt
WHERE ia.Id = iaaag.AccountId
AND iaaag.AccountGroupId = ianag.AccountGroupId
AND ianag.NodeId = ianpt.NodeId
AND ianpt.ProjectTypeId = ipt.Id
AND ia.UserName = '<some user here>'
GROUP BY ia.UserName, ia.FirstName, ia.LastName, ia.`Password`
after the "END" in the case statement and before the ')' for group_concat, you could put...
ORDER BY ipt.code ASC SEPARATOR ',' if you want the names in a consistent order with a , separator. just wanted to make sure you understand the group_concat() syntax a bit more.

SELECT ALL in a CASE inside a SELECT

i'm using Pentaho and I was wondering if it's possible to do some query like this :
SELECT Something
FROM Somewhere
WHERE (CASE WHEN condition1 = 0 THEN Option IN (Parameter) ELSE
(Option IN (SELECT Option FROM Somewhere_else)) END);
If you want some precision, i want to select everything if my condition is not respected in my WHERE clause (the thing i want to select in the where is different from the original select).
Don't hesitate to ask me for my approach and of course to answer !
Thank you !
PS: The Parameter is a Pentaho parameter which represents here an array
Just use regular conditions:
SELECT Something
FROM Somewhere
WHERE (condition1 = 0 AND Option IN (Parameter))
OR (condition1 != 0 AND Option IN (SELECT Option FROM Somewhere_else));
You should try following,
SELECT Something
FROM Somewhere
WHERE
1 = case when condition1 = 0 THEN
case when Option IN (Parameter) then 1 else 0 end
else
case when Option IN (SELECT Option FROM Somewhere_else) then 1 else 0 end
end
CASE is irrelevant in your statement, and is pretty much irrelevant in the WHERE clause at all.
Use simple conditions as suggested by #X.L.Ant, or you could do some nasty joining like
SELECT *
FROM table a
INNER JOIN somewhere ON (option = 0 AND a.id = somewhere.id)
INNER JOIN parameter ON (option != 0 AND a.id = parameter.id)
Assuming your parameter is somewhat a table.

Syntax error when creating view

I have the following little bit of MySQL code
CREATE VIEW UserResults AS
SELECT E.No, E. Description
, Count(R.RID WHERE $Username= R.Owner)
, Count(R.RID WHERE $Username= R.Owner AND Status==’Active’ )
FROM ETable AS E, RTABLE as R
ORDER BY E.No)
but MySQL is returning a syntax error that I can't seem to find. Also when I have created this view, how can I make it viewable?
You have an extra ending parenthesis, which should be removed
Views should not have ORDER BY.
The WHERE clause should not be in the middle of the SELECT, you will need to use a CASE.
You are returning a Cartesian product instead of joining your tables together, this may provide more results than you want/expect.
The R.RID in the THEN block of the CASE statements may need to be a 1, not entirely sure what you hoped to get from those COUNT statements you originally had.
I tried to figure out what you were trying to do, and I think this is it:
CREATE VIEW UserResults AS
SELECT E.No, E.Description
, SUM(CASE
WHEN $Username = R.Owner THEN R.RID
ELSE 0
END) AS SumOfOwner
, SUM(CASE
WHEN $Username = R.Owner AND Status = 'Active' THEN R.RID
ELSE 0
END) AS SumOfOwnerAndActive
FROM ETable AS E
INNER JOIN RTABLE as R ON E.No = R.ENo
GROUP BY E.No, E.Description
The Subquery which you create the view from is wrong:
SELECT E.No, E. Description, Count(R.RID WHERE $Username= R.Owner), Count(R.RID WHERE $Username= R.Owner AND Status==’Active’ ) FROM ETable AS E, RTABLE as R ORDER BY E.No)
you can not use where inside a count like:
Count(R.RID WHERE $Username= R.Owner)
Take a look at the Documentation and check the syntax again.
and try to replace the Status == 'Active' with Status = 'Active'
Once you created the view you can read it normally like a table usign the select keyword
As well as other issues identified in other answers, you need to specify the names of the columns in the view with:
CREATE VIEW UserResults(No, Description, UserCount, ActiveCount) AS ...
Also, in classic (standard) SQL, you cannot parameterize a view with a variable; the $Username notation looks like a parameter - and would not be allowed, therefore.