MySQL return 2 decimal places - mysql

I have a complicated query that returns a percentage but I need to have it return only 2 decimal places. I have searched the forums and trues truncate, round, cast, decimal, and a few others I am sure I am missing. I am at a complete loss as to where to go from here. The query is below. Any help would be greatly appreciated.
Code
SELECT branch, SUM( monthly_total / (
SELECT SUM(hour1)
FROM `door_count`
WHERE `numeric_month` <= MONTH( CURRENT_DATE( ) )
AND fy = 2013
AND numeric_month <> '0'
AND branch = 'Main St.'
) *100
)
FROM door_count
WHERE fy = 2014
AND branch = 'Main St.';

Use the ROUND() function:
SELECT branch, ROUND(SUM( monthly_total / (
SELECT SUM(hour1)
FROM `door_count`
WHERE `numeric_month` <= MONTH( CURRENT_DATE( ) )
AND fy = 2013
AND numeric_month <> '0'
AND branch = 'Main St.'
) *100
), 2)
FROM door_count
WHERE fy = 2014
AND branch = 'Main St.';

Related

SSRS expression to calculate total based on daily counts that have conditions

In a totals row (location is row group, date is the column group), I'm not sure how to calculate a total based on the below expression that I've been using to calculate "overcapacity" daily totals. I'm trying to total up the daily overcap counts.
The below expression works fine when grouped under the "date" column grouping. So each day in the range picked by the user displays with an "overcapacity" count (if the visitscounts > 7, then the result is visitscounts - 7, otherwise it is 0).
But I'm not sure how to total up the resultant overcapacity counts (I can total up visitcounts fine). The issue is that it takes the FULL daily count and THEN applies the -7, instead of just summing all the previously calculated daily counts (if the daily account exceeds 7, then it subtracts 7 from the full daily count, to come up with an "overcapacity" count).
=IIF(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0)) > 7,
SUM(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0))-7),
0)
ADDITIONAL INFORMATION
Dataset Query:
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
ORDER BY L.Location, D.[date]
OverCap New Column Testing
Dataset Query with Added OverCap Column:
SELECT
x.Location
, x.[date]
, x.VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
ORDER BY x.Location, x.[date]
Full Report Layout with OverCap added
Grouped by Location (row) and [date] (column), with a totals row outside row group for combined location.
report layout
Current Resultset with OverCap Column
CurrentResultSet
NOTES:
Result for LOC3-4 is 129 (see CurrentResultSet) if I use:
OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
Result for LOC3-4 is 34 if I use:
OverCap = IIF(Location = 'LOC3' OR Location = 'LOC4', VisitsCount,0)
Result for LOC3-4 is 24 if I use:
OverCap = IIF((Location = 'LOC3' OR Location = 'LOC4') AND VisitsCount > 7, VisitsCount,0)
Expressions Used Successfully for GROUPED locations:
DailyVisitorCount (used for both DailyVisitorCount and TotalVisitorCount).
=Sum(Fields!VisitsCount.Value)
DailyOverCapacityCount (used for both DailyOverCapacityCount and TotalOverCapacityCount):
=SWITCH(
Fields!Location.Value = "LOC1" AND Fields!VisitsCount.Value > 24, SUM(Fields!VisitsCount.Value - 24),
Fields!Location.Value = "LOC2" AND Fields!VisitsCount.Value > 16, SUM(Fields!VisitsCount.Value - 16),
Fields!Location.Value = "LOC3" AND Fields!VisitsCount.Value > 7, SUM(Fields!VisitsCount.Value - 7),
Fields!Location.Value = "LOC4" AND Fields!VisitsCount.Value > 7, SUM(Fields!VisitsCount.Value - 7),
Fields!Location.Value = "LOC5" AND Fields!VisitsCount.Value > 11, SUM(Fields!VisitsCount.Value - 11),
True, 0)
Averages were calculated by using the above expressions but adding to the end:
/CountDistinct(Fields!date.Value)
Expressions Used for combined location (outside grouped location row)
DailyVisitorCount (used successfully for both DailyVisitorCount and TotalVisitorCount).
=IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4", Sum(Fields!VisitsCount.Value), 0)
TotalOverCapCount (used successfully with DAILY TotalOverCapCount, but not the Total TotalOverCapCount
=IIF(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0)) > 7,
SUM(SUM(IIF(Fields!Location.Value = "LOC3" OR Fields!Location.Value = "LOC4",Fields!VisitsCount.Value,0))-7),
0)
Expressions still needed:
Total TotalOverCapCount (adds up daily totals for the duration)
Average TotalOverCapCount (average of daily totals for the duration)
As the expression you are trying to sum requires two scoped expression parts, it's actually difficult to then sum these.
What you need to do is
=SUM(
SUM(Fields!.MyField.Value, "ColumnGroup")
, "RowGroup")
This is probably not possible in your scenario. I abandoned the approach quickly and just updated the dataset query to return the data I needed instead
So the dataset query looked like this (using you sample data)
DECLARE #t TABLE([Location] varchar(10), [Date] Date, [VisitsCount] int)
INSERT INTO #t VALUES
('LOC1', '2022-10-31', 18), ('LOC1', '2022-11-01', 19),
('LOC1', '2022-11-02', 19), ('LOC2', '2022-10-31', 34),
('LOC2', '2022-11-01', 30), ('LOC2', '2022-11-02', 35),
('LOC3', '2022-10-31', 8), ('LOC3', '2022-11-01', 8),
('LOC3', '2022-11-02', 8), ('LOC4', '2022-10-31', 5),
('LOC4', '2022-11-01', 5), ('LOC4', '2022-11-02', 7),
('LOC5', '2022-10-31', 11), ('LOC5', '2022-11-01', 11),
('LOC5', '2022-11-02', 11)
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM #t
As you can see, I added an OverCap column. Now all we need to do is sum that in the report.
The report design looks like this..
and the final report looks like this...
Obviously you might need to adapt this to suit whatever grouping you have going but I think it's probably a much simpler approach.
Edit after update by OP
You can wrap your original query in a SELECT and then move the order clause of of the sub query. That should give you the same results.
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
ORDER BY [Location], [date]
If you want to just get LOC3+4 at the end of the table
Then you can do this in SQL. All I've done here is taken the existing query, dumped the results to a temp table , then returned the results plus an extra row that only contains LOC3 and LOC4 data.
Note: I added a GroupOrder column so you can sort on this in the report to make sure the combined row appears at the end.
SELECT
[Location], [Date], VisitsCount
, OverCap = IIF(VisitsCount-7 <0 ,0, VisitsCount-7)
INTO #t
FROM (
SELECT
L.Location
, D.[date]
, COUNT(DISTINCT CAST(V.VisitID AS VARCHAR(10))+V.Location+V.[Room-Bed]) AS VisitsCount
FROM dbo.DateTable(#StartDate, #EndDate) AS D
CROSS JOIN (
SELECT DISTINCT Location FROM dbo.vHIMOverFlowBedReport2)
AS L LEFT JOIN dbo.vHIMOverFlowBedReport2 AS V ON D.[date] BETWEEN
V.EffectiveDate AND ISNULL(V.ServiceEndDate, #EndDate) AND V.Location = L.Location
WHERE V.EffectiveDate IS NULL OR
(V.EffectiveDate <= #EndDate OR
V.ServiceEndDate >= #StartDate OR
V.ServiceEndDate IS NULL)
GROUP BY
L.Location
, D.[date]
) x
SELECT
GroupOrder = 1
, [Location], [Date], VisitsCount, OverCap
FROM #t
UNION ALL
SELECT
GroupOrder = 2
, [Location] = 'LOC3+4', MIN([Date]), SUM(VisitsCount), SUM(OverCap)
FROM #t
WHERE [Location] IN ('LOC3', 'LOC4')
GROUP BY YEAR([Date]), MONTH([Date])

complex query - look back on same table data to output results in mysql (VERY slow query)

I'm trying to optimize a query, which as the db is growing, its performance is severely lacking.
Background: we are trying to find a list of users who have taken a course and their credential is now due to be renewed (or has not renewed). In searching the query we have to have a look into the registration table (which is the same table that holds all their registration history) and find records where they have not renewed. (Each time the client takes a course they have a registration record added.) The query I'm wanting to optimize looks to see if they've (client) taken the same course type on a date/time after the last class (of same type) they took. If there is no record it should result row(s) that they didn't renew their course. it sounds easy, but, as you know, when you're in the heat of writing a query it gets very complex--and even more so once the db has grown to be so large that it takes almost 5-6 minutes to find the data. So, I'm asking for help on how I can optimize the efforts of my predecessor, below.
Here is the query, thus far (don't laugh, it wasn't started by me--I took over the project).
I have no clue where to begin with optimizing this MySQL. I think it needs to have select statements within the JOINS, but I'm at your mercy to direct me as to where to start! (I"m not a db guy, but offered to take a look and see where we can fix this).
Thanks a million for reading.
Lee
SELECT
r.GUID AS `A/C #`,
concat( a.AttendeeLastName, ', ', a.AttendeeFirstName ) AS Full Name (Last, First),
r.CourseExpirationDateFull AS `Exp Date`,
mtype_master_abbrev AS Course,
a.EmailName AS Email,
r.EventID,
r.EventTypeMasterID,
m.type_master_name,
IF( ( r.CourseExpirationDateFull < curdate( ) ), 'Expired', 'Valid' ) AS Status,
e.StartDateTime,
( to_days( curdate( ) ) - to_days( r.ExpNoticeSent ) ) AS Last Notice,
r.AttendeeID,
a.AttendeeCredentials,
r.RegistrationID,
r.RenewedExternalYYYY,
r.ExpNoticeSent,
q.RenewedRegID,
rs.reg_status_name AS `Reg Status`,
( to_days( r.CourseExpirationDateFull ) - to_days( curdate( ) ) ) AS Days2Exp,
a.flgReturnEmail,
a.flgSendEmail,
r.reg_type_ID,
a._usr_flg_do_not_call,
a.flgPrintLetter
e.EventTypeMasterID AS MasterID,
c.Last: yy-mm-dd - by - topic AS LastComm,
r.reg_renewal_status_id
FROM
vjgzuqrr_wtsql.registration r LEFT JOIN vjgzuqrr_wtsql.events ON ( r.EventID = events.EventID ) LEFT JOIN
vjgzuqrr_wtsql.attendees a ON a.ID = r.GUID LEFT JOIN
vjgzuqrr_wtsql.tbl_crs_type_master m ON r.EventTypeMasterID = m.ID_crs_type_master LEFT JOIN
vjgzuqrr_wtsql.qryrenreg q ON r.RegistrationID = q.OrigRegID LEFT JOIN
vjgzuqrr_wtsql.tbl_reg_status rs ON rs.ID_reg_status = r.RegistrationStatus LEFT JOIN
vjgzuqrr_wtsql.v_last_contact c ON c.registrationid = r.RegistrationID
WHERE
r.Role = 1
AND r.reg_type_ID IN ( 1, 2 )
AND r.CompletionStatus IN ( 9, 8 )
AND r.r IN ( 1, 14, 9 )
AND ( r.EventTypeMasterID IS NOT NULL OR r.EventTypeMasterID = 17 )
AND r.flgDelete = 0
AND r.flgTest = 0
AND e.flgDelete = 0
AND e.flgTestCourse = 0
AND e.flgDelete = 0
AND a.flgTest = 0
AND isnull( q.RenewedRegID )
AND a.flgReturnEmail = 0
AND m.type_master_abbrev NOT IN ( 'EKGPHARM', 'IVCERT', 'sem', 'fam&friends', 'cccc' )
Edit to include Explain:
Sorry im a bit slow, mysql,
This does not speed anything up ( i think, but it may help a bit), but it should help in reading it in a non-mindbreaking way. (hopefully this will also help others look at it.)
SELECT
r.GUID AS `A/C #`,
concat( a.AttendeeLastName, ', ', a.AttendeeFirstName ) AS Full Name (Last, First),
r.CourseExpirationDateFull AS `Exp Date`,
mtype_master_abbrev AS Course,
a.EmailName AS Email,
r.EventID,
r.EventTypeMasterID,
m.type_master_name,
IF( ( r.CourseExpirationDateFull < curdate( ) ), 'Expired', 'Valid' ) AS Status,
e.StartDateTime,
( to_days( curdate( ) ) - to_days( r.ExpNoticeSent ) ) AS Last Notice,
r.AttendeeID,
a.AttendeeCredentials,
r.RegistrationID,
r.RenewedExternalYYYY,
r.ExpNoticeSent,
q.RenewedRegID,
rs.reg_status_name AS `Reg Status`,
( to_days( r.CourseExpirationDateFull ) - to_days( curdate( ) ) ) AS Days2Exp,
a.flgReturnEmail,
a.flgSendEmail,
r.reg_type_ID,
a._usr_flg_do_not_call,
a.flgPrintLetter
e.EventTypeMasterID AS MasterID,
c.Last: yy-mm-dd - by - topic AS LastComm,
r.reg_renewal_status_id
FROM
vjgzuqrr_wtsql.registration r LEFT JOIN
vjgzuqrr_wtsql.events e ON r.EventID = e.EventID LEFT JOIN
vjgzuqrr_wtsql.attendees a ON a.ID = r.GUID LEFT JOIN
vjgzuqrr_wtsql.tbl_crs_type_master m ON r.EventTypeMasterID = m.ID_crs_type_master LEFT JOIN
vjgzuqrr_wtsql.qryrenreg q ON r.RegistrationID = q.OrigRegID LEFT JOIN
vjgzuqrr_wtsql.tbl_reg_status rs ON rs.ID_reg_status = r.RegistrationStatus LEFT JOIN
vjgzuqrr_wtsql.v_last_contact c ON c.registrationid = r.RegistrationID
WHERE
r.Role = 1
AND r.reg_type_ID IN ( 1, 2 )
AND r.CompletionStatus IN ( 9, 8 )
AND r.r IN ( 1, 14, 9 )
AND ( r.EventTypeMasterID IS NOT NULL OR r.EventTypeMasterID = 17 )
AND r.flgDelete = 0
AND r.flgTest = 0
AND e.flgDelete = 0
AND e.flgTestCourse = 0
AND e.flgDelete = 0
AND a.flgTest = 0
AND isnull( q.RenewedRegID )
AND a.flgReturnEmail = 0
AND m.type_master_abbrev NOT IN ( 'EKGPHARM', 'IVCERT', 'sem', 'fam&friends', 'cccc' )

MySQL equivalent in MSSQL to assigning a variable and using it

I tried finding the answer, but maybe I am too new to MSSQL, I come from MySQL, so this is my question super simplified to go straight to the point:
Imagine we have a table "Things"
Thingie | Value
--------+-------
Thing1 | 10
Thing1 | 15
Thing1 | 16
In MySQL I could do something like this in a query:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things
Which would return
Thingie | Value | HalfValue | HalfofHalf
--------+-------+-----------+------------
Thing1 | 10 | 5.00 | 2.50
Thing1 | 15 | 7.50 | 3.75
Thing1 | 16 | 8.00 | 4.00
Looks pretty simple, the actual one is a tad more complicated.
My problem is, in MSSQL I can't assign, and use a variable on the same SELECT. And I can't find anything similar to this functionality on this simple level.
Any solutions?
Edit, this is the select that contains all those nasty operations:
SELECT
fvh.DocEntry,
MAX( fvs.SeriesName ) AS "Serie",
MAX( fvh.DocNum - 1000000 ) AS "Número",
MAX( fvh.DocDate ) AS "Fecha",
MAX( fvh.U_FacNit ) AS "NIT",
MAX( fvh.U_FacNom ) AS "Nombre",
MAX( IIF( ISNULL( fvh.Address, '' ) = '', fvh.Address2, fvh.Address ) ) AS "Dirección",
SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) AS "Total",
IIF( MAX( fvh.CANCELED ) = 'Y' OR ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) = 0 ),
'Anulada',
IIF( SUM( fvd.GTotal ) > SUM( ISNULL( ncd.GTotal, 0 ) ) AND ( SUM( ISNULL( ncd.GTotal, 0 ) ) > 0 ),
'Devuelta',
'Emitida' )
) AS "Estado",
ROUND( ( ( SUM( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ), 4 ) AS "IVA",
ROUND( SUM( IIF( fvd.U_TipoA = 'BB',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Bien",
ROUND( SUM( IIF( fvd.U_TipoA = 'S',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "Servicio",
ROUND( SUM( IIF( fvd.U_TipoA = 'N',
( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) - ( ( ( fvd.GTotal - ISNULL( ncd.GTotal, 0 ) ) / 1.12 ) * 0.12 ),
0 ) ), 4) AS "No Aplica",
COUNT(fvd.LineNum) AS "Lineas", SUM(fvd.GTotal) AS "FCTotal",
SUM(ISNULL( ncd.GTotal, 0 )) AS "NCTotal"
/* Facturas */
FROM OINV AS fvh
LEFT JOIN NNM1 AS fvs ON fvs.Series = fvh.Series
LEFT JOIN INV1 as fvd ON fvd.DocEntry = fvh.DocEntry
/* Notas de Credito */
LEFT JOIN RIN1 AS ncd ON ncd.BaseEntry = fvh.DocEntry AND ncd.LineNum = fvd.LineNum
WHERE fvh.DocDate BETWEEN ? AND ? /*AND fvh.DocEntry = 1108*/
GROUP BY fvh.DocEntry
Thank you all for your time. I will dismantle my query and re-do it taking into consideration all of your input. Gracias, totales.
You think you can do this in MySQL:
SET #halfvalue := 0;
SELECT Thingie, Value,
(#halfvalue := Value / 2) AS HalfValue,
(#halfvalue / 2) AS HalfOfHalf
FROM Things;
But you are wrong. Why? MySQL -- as with every other database -- does not guarantee the order of evaluation of expression in a SELECT. The documentation even warns about this:
In the following statement, you might think that MySQL will evaluate #a first and then do an assignment second:
SELECT #a, #a:=#a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
In both databases, you can use a subquery. In the most recent versions of MySQL (and just about any other database), you can also use a CTE:
SELECT Thingie, Value, HalfValue,
(HalfValue / 2) AS HalfOfHalf
FROM (SELECT t.*, (Value / 2) AS HalfValue
FROM Things t
) t;
The answer is simple: you can't do that in MSSQL, because when you try it you'll get:
Msg 141, Level 15, State 1, Line 3
A SELECT statement that assigns a value to a variable must not be combined with data-retrieval operations.
which you most probably experienced.
The most simple workaround would be:
SELECT Thingie, Value, Value/2, Value/4 from Things
Other method:
select Thingie, Value, HalfValue, HalfValue / 2 from (
SELECT Thingie, Value, Value / 2 HalfValue from Things
) a
No, that doesn't work in SQL. The parameter value is not set until the query completes. You can do it in two steps:
DECLARE #halfvalue FLOAT = 0;
SELECT #halfvalue = ([Value] / 2)
FROM Things ;
SELECT Thingie
, [Value]
, HalfValue = [Value]/2
, HalfAgainValue = #halfvalue / 2
FROM Things ;

SSRS Predicament with expressions

I have an SSRS dataset that looks like this:
The dataset rows are generated independent of each other using UNION ALL.
I need to display these rows in my report as is, but I need to add an additional row that will calculate Total Won / Total Lost, so the result should look like this:
This is just sample as I have more columns (1 per month) and the whole thing is broken down by product, so if I have 10 different products, I will have 10 different tablix tables.
Basically I need to somehow create an expression that will only calculate values in 2 rows of the tablix out of 3 (based on the value of the Status column) and take into consideration that some values can be zeroes.
Here's the query (I simplified it a bit for better understanding):
select * from
(
select 'Created' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
) created
pivot
(
count(created.opportunityid)
for created.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivCreated
union all
select * from
(
select 'Won' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where regionidname = 'Americas Region'
and fo.actualclosedate >= dateadd(year, -1, getdate())
and regionalfeeincome >= 250000
and fo.jna is not null
) won
pivot
(
count(won.opportunityid)
for won.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivWon
union all
select * from
(
select 'Lost' as 'State', fo.groupidname, fo.businessidname ' Business', fo.opportunityid
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.actualclosedate >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.sys_phasename <> 'Pre-Bid'
) lost
pivot
(
count(lost.opportunityid)
for lost.groupidname in ([Boston], [Chicago], [Colombia], [Group D.C.], [Houston], [Los Angeles], [New York], [San Francisco], [Seattle], [Toronto])
) pivLost
TIA
-TS.
I can't fully test this as I don't have time to build sample data but it should work...
If you use this as your report's dataset query then you should be able to add a simple matrix with a row group by State and a column group by City
/*
You can optimise this a bit but I've kept it fairly procedural so it's easier to follow
*/
-- First do your 3 basic queries but this time we don't pivot and we dump the results into temp tables
-- I've also removed columns that don't appear to be used based on your sample output and remaned a column to City to make it easier to read
select 'Total Created' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Created
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
select 'Total Won' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Won
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.jna is not null
select 'Total Lost' as 'State', fo.groupidname as City, COUNT(*) AS Cnt
INTO #Lost
from FilteredOpportunity fo
where fo.regionidname = 'Americas Region'
and fo.createdon >= dateadd(year, -1, getdate())
and fo.regionalfeeincome >= 250000
and fo.sys_phasename <> 'Pre-Bid'
-- Now we calculate your Ratio
SELECT
'Win Ratio' as 'State'
, coalesce(w.City, l.City) as City -- use coalesce in case 1 side of join is null
, CASE WHEN ISNULL(l.cnt,0) = 0 THEN 0 ELSE w.Cnt/l.Cnt END as Cnt -- if lost is null or 0 return 0 else calc ratio
into #Ratio
FROM #Won w
full join #Lost l on w.City = l.City
-- finaly, get the results and add a sort to help the report row sorting.
SELECT 1 as Sort, * FROM #Created
UNION SELECT 2, * FROM #Won
UNION SELECT 3, * FROM #Lost
UNION SELECT 4, * FROM #Ratio

Calculating weekdays on Sql script

Can anyone help me about this sql case:
I want to add case if the calculation day of my script is in the weekdays Monday to Friday, what should I add to my script?
SELECT *
FROM
(SELECT a.cid,
a.SUBMIT_DATE,
a.REQ_BY,
a.MITRA,
a.COSTUMER_TYPE,
a.COSTUMER_NAME,
a.ADDRESS,
a.DESC,
a.CREATED_DATE,
a.TICKET_STATUS,
CASE
WHEN datediff(CURDATE(), A.SUBMIT_DATE) > 3 THEN 'OVER_SLA'
ELSE 'CLEAR'
END AS 'STATUS_SOLVE'
FROM complaint a
LEFT JOIN handling b ON a.cid = b.cid)a
WHERE a.STATUS_SOLVE ='OVER_SLA'
AND a.ticket_status='INPROGRESS'
if date in integer form :
SELECT DATENAME( dw, DATEFROMPARTS( #Year, #Month, #Day ) )
for string :
SELECT DATENAME( dw, CONVERT( date, CONCAT( #Day, '/' , #Month, '/', #Year ), 103 ) )