I'm writing a query to get gross profit percentage "GP%" of a certain product to put it in a C# grid view by product by year. I Want the query result to be dynamic that in some years this product was n't sold so the result will be (profit/sales)=(0/0) it will be null. this null isn't accepted by C#.
The query is
SELECT
FORMAT((SELECT ((ISNULL(SUM([Profit]), NULL)) / ISNULL(SUM([Sales]), NULL))
FROM [dbo].[Sales]
WHERE [ProdHeir01_2] = 'Batteries'
AND [Sales_Year] = 2015
AND [Month_Number] BETWEEN 1 AND 8, 'P') AS [Percentage]
This query results in 'Null'. How can I insert a condition to transfer null to a string value. so the query to be dynamic :).
Thanks a lot in advance......
Regards
Here is on technique you may find helpful:
select 0 / CASE WHEN IsNull([Sales],0) = 0 THEN 1 ELSE [Sales] END
Hady, here you go.
--CTE(Common Table Expression) with your query
WITH preselect AS
(
SELECT
FORMAT(
(SELECT ISNULL(SUM([Profit]), NULL) / ISNULL(SUM([Sales]), NULL)
FROM [dbo].[Sales]
WHERE [ProdHeir01_2] = 'Batteries'
AND [Sales_Year] = 2015
AND [Month_Number] BETWEEN 1 AND 8
)
,'P'
) AS [Percentage])
--Case statement that will return Null as string when Null and the percentage
--when it isn't null
SELECT CASE WHEN [Percentage] IS NULL THEN 'Null' ELSE [Percentage] END AS [Percentage]
FROM preselect
Related
I'm trying to run a somewhat complex sql statement using the 'group_concat' function for statistics.
When I run the sql statement using navicat, the correct result is returned.But when I use mybatis debug this sql in idea, it returns null value.
I use HashMapHashMap<String,Long> to receive the result set executed by mybatis,
I guess the result set returned by mybatis executing sql is wrongly encapsulated.
But I tried for a long time and couldn't find a solution.
I can't post pictures here,I display the results in a table.
cha
hege
lianghao
youxiu
1
1
2
1
Receive declaration at the mapper layer
HashMap<String, Long> getOption(#Param("column") String column);
Here is the sql code:
<select id="getOption" resultType="java.util.HashMap">
SELECT GROUP_CONCAT(form.cha SEPARATOR '') cha,
GROUP_CONCAT(form.hege SEPARATOR '') hege,
GROUP_CONCAT(form.lianghao SEPARATOR '') lianghao,
GROUP_CONCAT(form.youxiu SEPARATOR '') youxiu
FROM (
SELECT
( CASE WHEN #{column} = '0' THEN count(*) ELSE NULL END) AS 'cha',
( CASE WHEN #{column} = '1' THEN count(*) ELSE NULL END ) AS 'hege',
( CASE WHEN #{column} = '2' THEN count(*) ELSE NULL END ) AS 'lianghao',
( CASE WHEN #{column} = '3' THEN count(*) ELSE NULL END ) AS 'youxiu'
FROM corp_feedback_student
GROUP BY #{column}
) form
</select>
Thanks everyone for helping me!!
Hello I have this query that i am trying to execute and i keep getting this error "Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.", Kindly help please.
DECLARE #NUMCOUNT BIT
Select #NUMCOUNT = (SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C') ) THEN 1 else 0 END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
)
IF #NUMCOUNT = '1'
begin
UPDATE R5REQUISITIONS
SET R5REQUISITIONS.REQ_STATUS = 'CP'
end
Ok, it sounds like what you actually want to do is update R5REQUISITIONS when there is no RQL_STATUS = 'C' in R5REQUISLINES, since you said you want to count the records where the RQL_STATUS is A and where it's A or C, and then do the update if the counts are the same.. You can greatly simplify this task with the following query:
UPDATE r5
SET r5.REQ_STATUS = 'CP'
FROM R5REQUISITIONS r5
WHERE NOT EXISTS (SELECT 1 FROM R5REQUISLINES r5q WHERE r5q.RQL_REQ = r5.REQ_CODE AND r5q.RQL_STATUS = 'C')
Your 'SELECT CASE' is returning more than 1 record, so it can't be assigned to #NUMBER. Either fix the sub-query to only return the record your looking for or hack it to return only 1 with a 'LIMIT 1' qualification.
I don't know what your data looks like so I can't tell you why your case subquery returns more records than you think it should.
Try running this and see what it returns, that will probably tell you wall you need to know:
SELECT
CASE WHEN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ('A')
) IN
(SELECT COUNT(R5REQUISLINES.RQL_REQ)
WHERE R5REQUISLINES.RQL_STATUS IN ( 'A','C')
)
THEN 1
ELSE 0
END AS NUMCOUNT1
FROM R5REQUISLINES JOIN
R5REQUISITIONS ON R5REQUISLINES.RQL_REQ = R5REQUISITIONS.REQ_CODE
GROUP BY R5REQUISLINES.RQL_REQ, R5REQUISITIONS.REQ_CODE,R5REQUISLINES.RQL_STATUS
If there is more than 1 row returned, that's where your problem is.
I have a table in MySQL where in a record a field (Default: None) does not have any value.
I'm using a stored procedure to select values from this table and I when this field has no value I should get the value N/A.
I tried the following code but I get the field with no value.
SELECT md.coding_id,
md.patient_id,
md.implant_date,
(case
when md.device_and_implant_description = ''
then 'N/A'
when md.device_and_implant_description !=0
then md.device_and_implant_description
end) as device_and_implant_description
FROM medical_devices_mapping as md
WHERE md.patient_id = p_id
The p_id value is given by the user.
This is the result:
This is the structure of my table:
Please use NUll as well as "".
If you want to use NULL or '' only then before storing data, make sure that you are storing null or empty string then accordingly use condition.
Use REGEXP condition instead of ''
SELECT md.coding_id, md.patient_id, md.implant_date,
CASE WHEN md.device_and_implant_description REGEXP '^[A-Za-z0-9]+$'
THEN md.device_and_implant_description
ELSE 'N/A'
END AS device_and_implant_description,
md.device_and_implant_description
FROM medical_devices_mapping md
WHERE md.patient_id = p_id
Maybe you should invert your logic
case when trim(md.device_and_implant_description) is not null then md.device_and_implant_description
else 'N/A'
end
I found the solution using COALESCE().
The proposed solution is the following:
SELECT md.coding_id,
md.patient_id,
md.implant_date,
(CASE when COALESCE(md.device_and_implant_description, '') !=''
then md.device_and_implant_description
when COALESCE(md.device_and_implant_description, '') =''
then 'N/A'
end) as device_and_implant_description
FROM medical_devices_mapping as md
WHERE md.patient_id = p_id
Parameter Values
I am trying to display all the records with any status. When the user select 'AllLogs' from the dropdwon in report.
But when I run the report it is excluding the records with blank
status.
How can i pull the records with any status(blank,NULL,Approved,etc) ?
Label: Status
Value: %
I have also enabled NULL and Blank values in the parameter properties.
This is my where clause.
( ( l.Status LIKE '%' + #status + '%' ) OR
( l.Status LIKE #status ) OR
( LTRIM(RTRIM(l.Status))='') OR
( l.status IS NULL ) )
The most surefire way to include all records is to simply not filter in your where, which can be achieved with a short-circuiting case statement:
where case when #status = '%' -- This can be any value, such as 'All'
then 1
else case when l.Status = #status
then 1
else 0
end
end = 1
Whilst this is a little verbose, it has the added benefit of not actually running the comparison if your All option is selected, which will improve query performance.
I have a table that, due to the third party system we are using, sometimes has duplicate data. Since the model uses an EAV method there's no way to filter this the "right" way, so I am aggregating the data into a View - I know this is a data collection problem but it's easier for me to fix it on the display end than go through this system and potentially break existing data and forms. I need to check one of two fields to see if one or both are entered, but only pick one (otherwise the name displays twice like this: "John,John" instead of just "John"). Here's my code for the relevant part:
group_concat(
(
case when (`s`.`fieldid` = 2) then `s`.`data`
else
case when (`s`.`fieldid` = 35) then `s`.`data`
else NULL end
end
) separator ','),_utf8'') as first_name
If both fieldid 2 and fieldid 35 are entered, I would expect this to just return the value from fieldid = 2 and not the value from fieldid = 35, since the Else clause shouldn't execute when the original case when is true. However it's grabbing that, and then still executing the case when inside of the else clause?
How can I fix this code to give me either fieldid = 2 OR fieldid = 35, but avoid globbing them both together which results in the name being duplicated?
EDIT
Here is the table structure:
table: subscribers_data
subscriberid (int) fieldid (int) data (text)
It uses an E-A-V structure so a sample record might be:
subscriberid fieldid data
1 2 John
1 3 Smith
1 35 John
1 36 Smith
with fieldid 2 and 35 being the custom field "First Name" (defined in a separate table) and fieldid 3 and 36 being "Last Name".
Here is the full view that I'm using:
select `ls`.`subscriberid` AS `id`,
left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) AS `user_id`,
ifnull(group_concat((
case when (`s`.`fieldid` = 2) then `s`.`data`
when (`s`.`fieldid` = 35) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `first_name`,
ifnull(group_concat((
case when (`s`.`fieldid` = 3) then `s`.`data`
when (`s`.`fieldid` = 36) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `last_name`,
ifnull(`ls`.`emailaddress`,_utf8'') AS `email_address`,
ifnull(group_concat((
case when (`s`.`fieldid` = 81) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `mobile_phone`,
ifnull(group_concat((
case when (`s`.`fieldid` = 100) then `s`.`data`
else NULL end) separator ','),_utf8'') AS `sms_only`
from ((`list_subscribers` `ls`
join `lists` `l` on((`ls`.`listid` = `l`.`listid`)))
left join `subscribers_data` `s` on((`ls`.`subscriberid` = `s`.`subscriberid`)))
where (left(`l`.`name`,(locate(_utf8'_',`l`.`name`) - 1)) regexp _utf8'[[:digit:]]+')
group by `ls`.`subscriberid`,`l`.`name`,`ls`.`emailaddress`
The view is being used as the Model for a Ruby on Rails application, so I'm using some creative hacking to fake out a "user_id" that Rails expects (we name the field list.name in the Lists table using a numeric ID that our front-end Rails app generates when we add a new user, so I'm extracting just this number to make the view look like a Rails-convention database table)
I am not a mysql guy, but in a sql server case statement, you could do it without the first 'else'
case
when fieldid = 2 then data
when fieldid = 35 then data
else null
end
Also, you seem to be returning the same 'data' field in both cases
Anything inside group_concat() doesn't have a way to see the context in which it's running. So, you have have two rows in a single group, one with fieldid=2 and second with fieldid=35, it will do the following:
processing row with fieldid=2...
s.fieldid = 2 is true, return s.data
processing row with fieldid=35...
s.fieldid = 2 is false, try the else part
s.fieldid = 35 is true, return s.data
This explains why is "John" returned multiple times. The only way to fix it is to run a different query outside of group_concat().
EDIT:
Ih you really have to do it this way, use something like this instead:
SELECT ...
min(CASE WHEN s.fieldid IN (2,35) THEN s.data ELSE NULL END) AS first_name
...
Alternatively you can do group_concat(DISTINCT ...) if the two values can't be different (otherwise you would get e.g. "John,Johny"). Why do you have two values for first_name/last_name though?