I am creating a report generator which allows me to build custom reports by selecting tables and fields which are saved in the database. Each table, field, calculated value, etc. is treated as a separate entity, with no direct connection to any other entity. They are all self-contained.
I have a number of count fields/columns, which I currently have working, using code similar to the following:
sum(case when usasf_teams.division_levelid=7 then 1 else 0 end) as Dance
My problem is that there are quite a few of these columns, and most of the values are zero. This makes it hard to spot the non-zero values, which are what we want to see.
I know I can use the IF statement to return either the number or a space, but I don't want to put the server through the work of doing the same operation twice for every column in every row. I would like to do something like this:
if(sum(case when usasf_teams.division_levelid=7 then 1 else 0 end),
{{use the comparison value}}, ' ') as Dance
This way, the sum/case operation is only done once for each field.
Is this possible?
First, you can simplify your logic to:
sum(usasf_teams.division_levelid = 7) as Dance
Then, I would recommend changing the 0 values to NULL rather than a space:
nullif(sum(usasf_teams.division_levelid = 7), 0) as Dance
If you are going to return a real space, you need to be careful of types. You could do this as;
select (case when sum(usasf_teams.division_levelid = 7) > 0
then cast(sum(usasf_teams.division_levelid = 7) as char)
else ' '
end)
You don't need to worry about doing the sum() twice. The expense in an aggregation is manipulating the data, not (in general) calculating the aggregation functions themselves.
Related
I am working on a time system that require manual input of the coming and going times. (not my system) I am building a dashboard for this system that will show average time on site and more. Because it requires a manually entered coming and going time, mistakes can happen. If someone checks in at 18:00hours but forgets to clock out, the system automatically leaves the clock out time at 0:00:00 hours.
When calculating my averages, if the above occurs, then it calculates the average time spent on site and adds in a -18:00 hours. This obviously breaks the whole calculation. Is there a way to have the query ignore any negatives to avoid this?
SELECT id, TIMEDIFF(`booking_time_out`, `booking_time`) AS 'Time_Spent'
FROM `table_name`
The negative result criteria is a result of the 0:00:00 booking out time so append the exclusion of that row in the where criteria like:
where booking_time_out != '0:00:00'
You seem to want a case expression:
select id,
case when timediff(`booking_time_out`, `booking_time`) < 0
then 0
else timediff(`booking_time_out`, `booking_time`)
end as time_spent
from tablename
Side note: do not surround identifiers with single quotes (as in as 'Time_spent'). In standard SQL, single quotes stand for literal strings. On the other hand, you usually do not need to quote an identifier (unless its name is really badly chosen) - and if you need to, the quoting character of MySQL is backticks.
How do I get the total of the group inside a row item?
I have tried Fields!Sales.Value/SUM(Fields!Sales.Value) but it returns 1 instead of the row_amount/group_total the report returns row_amount/row_amount
PS: Data comes from a SSAS cube. I made picture bellow1 to summarize what I wanna do
You could potentially just compare the values by the ReportItems. That is, you can specify a name for the sales textbox and for the totalsales textbox and do the comparison using those values. The following expression would likely work as intended.
= (ReportItems!SalesTextbox.Value / ReportItems!SalesTotalTextbox.Value) * 100.0
The other thing to consider with this is that if your result is 1, you may be dealing with integer division from your data. Make sure the data being returned is coming in with a double or decimal datatype, not an integer. It may work as you have it currently if you get the datatype corrected.
You also need to handle "divide by Zero' errors. Using an "=IIf (denominator = 0, 0, numerator/denominator) doesn't work since an "IIf" function evaluates both the "then" and the "else" and will still return an error. We use a bit of custom code that I found on SO (I wish I could remember where it came from so I could give credit where it's due).
Public Function HandleDivideByZero(ByVal numerator As Decimal, denominator As Decimal) As Decimal
If denominator = 0 Then
Return 0
Else
Return numerator / denominator
End If
End Function
Is this a legitimate/good way of checking multiple column values in a row (in order to send to the user the appropriate feedback)?
select
(date_expires < now()) as expired,
(date_deleted is not null) as active
from sometable where row='foo';
It seems awfully convenient to me (this way I can make one query and conditionally alert the user to what exactly is wrong with the row they are trying to access), but I actually haven't seen it very much so I'm worried there is a big downside that I'm not seeing. Thanks!
Your method works, it's just going to give back separate columns. If you want one column to hold the result, then it's some case statement fun.
select
case when date_expires < now() then 'Inactive'
else 'active'
end as status
from sometable where row='foo';
That would give you status with inactive/active as it's two values. I just went with else active, you can put in a series of when this condition then 'this value' if you wanted.
I am making a stored procedure for monthly sales. In the stored procedure we have a Discount. This discount can be fetched from three different tables. If the discount is not in id.rabatt, it should fetch from dp.rabatt, if its not there, it should fetch from ds.rabatt. So the first two ones can be empty, while the last one always has a discount..
Im having big trouble designing the WHEN part of the procedure. Please take a look and help me on the way if you have time:
CASE (
when
Isnull(id.rabatt, Isnull(u.rabatt, id.rabatt)) then..
when
Isnull(dp.rabatt, Isnull(x.rabatt, dp.rabatt)) then..
when
Isnull(ds.rabatt, Isnull(y.rabatt, ds.rabatt)) then..
end)
AS 'Discount',
The reason i have to use Isnull is that inside each Discount table, i also have two different discounts, one that lasts forever(2999) and one that have a selected period. Like i show here:
LEFT OUTER JOIN discount AS id
ON id.identifiers = isa.identifiers
AND id.store = BV.name
AND id.from_date <= isa.sales_date
AND id.to_date >= isa.sales_date
AND id.to_date < '2999-01-01'
LEFT OUTER JOIN discount AS u
ON u.identifiers = isa.identifiers
AND u.to_date = '2999-01-01'
The two others tables are designed in similar ways.
You can use the coalesce function in a similar way that you are using the IsNull function. There are some subtle differences between IsNull and Coalesce, but the significant difference that would benefit your code is that you can have multiple parameters without needing to nest it.
Your code: Isnull(id.rabatt, Isnull(u.rabatt, id.rabatt))
Is the same as: Coalesce(id.rabatt, u.rabatt, id.rabatt)
Next... there are 2 general forms for case/when.
Case (Some Condition)
When (Value 1) Then ...
When (Value 2) Then ...
Else (Default Value)
End
Or
Case When (SomeCondition = Value1) Then ...
When (SomeCondition = Value2) Then ...
Else DefaultValue
End
Looking at your code snippet, it appears as though you are using the second form, but you don't have a comparison operator in the when part. I think you want something like this...
CASE When Coalesce(id.rabatt, u.rabatt, id.rabatt) Is Not NULL then..
When Coalesce(dp.rabatt, x.rabatt, id.rabatt) Is Not NULL then..
When Coalesce(ds.rabatt, y.rabatt, id.rabatt) Is Not NULL then..
Else (Put a default value here)
end AS [Discount]
This may have been answered elsewhere, but I can't find it!
I'm combining 2 queries from different sources onto a single query for calculation and reporting purposes. Fields which are not common to both sources show as blank if there is no data, and can't then be used in arithmetic.
I want to set a default of zero where blank, instead of having to knife and fork the query into another table and run an update query over all the blank fields.
There's got to be something simpler! HELP!
Give this a try:
SELECT
nz(value1, 0), nz(value2,0), nz(value3,0)
FROM table1 left outer join table2 on table1.column = table2.column
unless your query resembles what John answered with (a cartesian) then his answer is more appropriate.... (cartesians are dangerous if not used correctly... depending on how big the individual tables are allowed to become you can kill an access application by using them)
You'll either want to use Nz() or iif(), depending on whether that "blank" really is just a blank (empty string) or Null.
So your options are:
SELECT Nz(source1.a + source2.b,0) FROM source1, source2
or:
SELECT iif(source1.a + source2.b <> "", source1.a + source2.b, 0) FROM source1, source2