Total Count of each - sql

I have a problem with my SQL Server query.
My query must display the total number of each category. Not the total amount of all categories.
SELECT [CATEGORY],
(SELECT COUNT(*)
FROM [Group_New_DB].[dbo].[INCIDENTSM1]
WHERE ([OPEN_TIME] >= #StartDate and [OPEN_TIME] < #EndDate + 1) ) AS OpenedCount,
(SELECT COUNT(*)
FROM [Group_New_DB].[dbo].[INCIDENTSM1]
WHERE ([CLOSE_TIME] >= #StartDate and [CLOSE_TIME] < #EndDate + 1)) AS ClosedCount
FROM [Group_New_DB].[dbo].[INCIDENTSM1]
GROUP BY CATEGORY
ORDER BY CATEGORY
The report consists of a table with 3 columns: Category, Registered, Closed.
1 column is the category name.
2 column is how many categories have been registered.
3 column -> how many columns were closed.
But result
The result that turned out as a result does not look right.

I don't quite understand what is the difference between total number vs total amount as the question doesn't provide any context.
Although, if you are trying to get OpenedCount and ClosedCount as you have named the columns, I suggest you try below:
SELECT
CATEGORY,
SUM(CASE WHEN (OPEN_TIME >= #start_date AND OPEN_TIME < #end_date+1)
THEN 1
ELSE 0
END) AS OPENED_COUNT,
SUM(CASE WHEN (CLOSED_TIME >= #start_date AND CLOSED_TIME < #end_date+1)
THEN 1
ELSE 0
END) AS CLOSED_COUNT
FROM
[Group_New_DB].[dbo].[INCIDENTSM1]
GROUP BY
CATEGORY
ORDER BY
CATEGORY
IMO, This is also a better way as it doesn't include multiple sub-queries.
Correction: changed COUNT to SUM as suggested by TriV - Thanks!

Try this instead -
SELECT [CATEGORY],
COUNT(CASE WHEN [OPEN_TIME] >= #StartDate and [OPEN_TIME] < #EndDate + 1 THEN 1 ELSE NULL END) AS OpenedCount,
COUNT(CASE WHEN [CLOSE_TIME] >= #StartDate and [CLOSE_TIME] < #EndDate + 1 THEN 1 ELSE NULL END) AS ClosedCount
FROM [Group_New_DB].[dbo].[INCIDENTSM1] GROUP BY
CATEGORY ORDER BY CATEGORY

Related

How to return count in 2 columns?

I have this query. It should return Count for both AWARDED (1) and NOT AWARDED(0) works from works table.
Select Count(w.WorkID)as Total, w.IsAwarded, org.OrganizationName
From Works w
Inner Join MC_MemberShip.Membership.Organization org
ON org.OrganizationID= w.Organization_ID
where Convert(varchar(11), w.OpeningDate) >= Convert(varchar(11), #FromDate)
and Convert(varchar(11), w.OpeningDate) < DATEADD(day, 1, Convert(varchar(11), #ToDate))
and w.IsActive=1 and
ISNULL(w.IsAwarded,0)= 0 and w.Organization_ID= case when #OrgID= -1 then w.Organization_ID else #OrgID end
group by org.OrganizationName, w.IsAwarded
Now this query returns Total count for NOT AWARDED i.e. 0 only but i want to return count for AWARDED too in same query.
Organization TotalAwardedWorks TotalNotAwardedWorks
Town 1 1 2
Town 2 44 33
Your query should look something like this:
select org.OrganizationName,
Count(*) as Total,
sum(case when w.IsAwarded = 0 or w.IsAwarded is null then 1 else 0 end) as TotalNotAward,
sum(case when w.IsAwarded = 1 then 0 else 1 end) as TotalAward
from Works w Inner Join
MC_MemberShip.Membership.Organization org
on org.OrganizationID = w.Organization_ID
where w.OpeningDate >= #FromDate and
w.OpeningDate < dateadd(day, 1, #ToDate) and
w.IsActive = 1 and
(w.Organization_ID = #OrgId or #OrgID= -1)
group by org.OrganizationName;
Notes:
Do not convert dates to strings to perform comparisons. That is just perverse.
Generally, the use of case in the where clause is discouraged. The logic is more clearly represented using or.
You can get what you want by using case to put conditions in the aggregation functions.

SQL: Create Multiple Selects Based One Date

I've been searching for help on this but I can't seem to find the solution. What I have is:
Table called Details_Orders.
Columns: CustomerName, InvoiceDate, SaleAmount and SaleCost.
What I want to do is select a date ('1-1-2015') and display the Customer Name, the Date ('1-1-2015'), the sum of SaleAmount for that Date, and the Sum of the SaleCost. And here's the part I'm having problems with, I want the next columns to display the previous months SaleAmount and SaleCost, then the previous YEARS SaleAmount and SaleCost.
I'm having trouble figuring out how to code the Previous Time Periods Select statements. Any help on this would be greatly appreciated.
Select
CustomerName,
InvoiceDate,
Sum(SaleAmount),
Sum(SaleCost),
*PREVIOUS MONTH Sum(SalesAmount) DATEADD(MONTH,-1,'1-1'2015'),
PREVIOUS MONTH Sum(SalesCost) DATEADD(MONTH,-1,'1-1'2015'),
PREVIOUS YEAR Sum(SalesAmount) DATEADD(YEAR,-1,'1-1'2015'),
PREVIOUS YEAR Sum(SalesCost) DATEADD(YEAR,-1,'1-1'2015')*
From Details_Orders
WHERE InvoiceDate='1-1-2015'
Basic
You want to use conditional aggregation, and also need a group by. It is a bit unclear what the exact definitions of previous month and year are. Here is one interpretation:
Select CustomerName,
Sum(case when InvoiceDate = thedate then SaleAmount else 0 end),
Sum(case when InvoiceDate = thedate then SaleCost else 0 end),
Sum(case when year(InvoiceDate)*12 + month(InvoiceDate) =
year(thedate)*12 + month(thedate) - 1
then SaleAmount else 0
end),
Sum(case when year(InvoiceDate)*12 + month(InvoiceDate) =
year(thedate)*12 + month(thedate) - 1
then SaleCost else 0
end),
Sum(case when InvoiceDate < thedate and
InvoiceDate >= dateadd(year, -1, thedate
then SaleAmount else 0
end),
Sum(case when InvoiceDate < thedate and
InvoiceDate >= dateadd(year, -1, thedate
then SaleCost else 0
end)
From (select cast('2015-01-01' as date) as thedate
) params cross join
Details_Orders o
group by CustomerName;

SQL Columns Subquery with different criteria

Lets say a have two tables, [Products] and [Quantiy].
I need to select a join in both in order to built a table with total Quantity per product.
I know who to do this in a vanilla join. My problem is that i need 3 columns one [PreviewTotal] where I should have this total quantity since ever till yesterday no matter sign of quantity other [TodaytotalPos] with quantity for today and positive and other [TodaytotalNeg] only today and negative.
result like:
[Products] [PreviewTotal] [TodaytotalPos] [TodaytotalNeg]
AAPL 20,000 500 -700
MCD 15,000 NULL -300
BAC -30,000 2,000 NULL
Sample of structure:
Producst:
[id] [name]
1 AAPL
2 MCD
3 BAC
Quantity:
[date] [Id_Product] [Quantity]
12/16 1 500
12/16 2 -300
12/17 1 1,000
12/18 3 5,500
12/18 1 -2,000
Based on the rules you specify, I think you are just looking for conditional aggregation. Your query would look something like this:
select p.name,
sum(case when [date] < cast(getdate() as date) then quantity end) as PreviewTotal,
sum(case when [date] = cast(getdate() as date) and quantity > 0
then quantity end) as TodayTotalPos,
sum(case when [date] = cast(getdate() as date) and
quantity < 0 then quantity end) as TodayTotNeg
from products p join
quantity q
on q.id_product = p.id
group by p.name
order by p.name;
However, your desired results don't match the input data, based on these rules.
In SQL Server you can use CASE to select a field value if a condition is true or false. I assume your [Products] table contains at least ProductId and ProductName, and your [Quantity] table contains at least ProductId, Qty, and SoldDate.
-- get the time of midnight, the start of today:
DECLARE Today datetime;
SELECT DATEADD(DAY, DATEDIFF(DAY, '19000101', GETDATE()), '19000101') INTO Today
-- get the totals
SELECT Products.ProductName,
SUM(
CASE
WHEN Quantity.SoldDate >= Today THEN Quantity.Qty
ELSE 0
END) AS PreviewTotal,
SUM(
CASE
WHEN Quantity.Qty> 0 AND Quantity.SoldDate >= Today) THEN Quantity.Qty
ELSE 0
END) AS TodaytotalPos,
SUM(
CASE
WHEN Quantity.Qty< 0 AND Quantity.SoldDate >= Today THEN Quantity.Qty
ELSE 0
END) AS TodaytotalNeg
FROM Products JOIN Quantity on Products.ProductId = Quantity.ProductId
GROUP BY ProductName

SQL Query: Including Two Sums based on different criteria from the same table

I currently have the following sql query
SELECT [Date], DATENAME(dw,[Date]) AS Day, SUM(Units) AS TotalUnits
FROM tblTimesheetEntries
WHERE UserID = 'PJW'
AND Date >= '2013-01-01'
GROUP BY [Date]
ORDER BY [Date] DESC;
Which returns the Total [Units] for a given user and date.
However I would like to produce two separate Total Units based on a new criteria i.e. whether or not the [Units] where 'Chargeable or Not'. There is a field in tblTimeSheets called Chargeable which is a boolean (true for chargeable, false for not). How do I incorporate this to show two Sums one for each type of Units?
You can use a CASE with the SUM() to calculate the separate totals:
SELECT [Date],
DATENAME(dw,[Date]) AS Day,
sum(case when Chargeable = 1 then Units else 0 end) ChargeableTotal,
sum(case when Chargeable = 0 then Units else 0 end) NotChargeableTotal,
sum(Units) AS TotalUnits
FROM tblTimesheetEntries
WHERE UserID = 'PJW'
AND Date >= '2013-01-01'
GROUP BY [Date]
ORDER BY [Date] DESC;

multi-select sql query with date range

I have this query where I get totals of different stats from an employee roster table.
SELECT A.rempid AS EmpId,
E.flname,
A.rdo_total,
B.grave_total,
C.sundays,
D.holidays
FROM (SELECT rempid,
Count(rshiftid)AS RDO_Total
FROM rtmp1
WHERE rshiftid = 2
GROUP BY rempid
HAVING Count(rshiftid) > 0) A,
(SELECT rempid,
Count(rshiftid)AS Grave_Total
FROM rtmp1
WHERE rshiftid = 6
GROUP BY rempid
HAVING Count(rshiftid) > 0)B,
(SELECT rempid,
Count(rshiftid) AS Sundays
FROM rtmp1
WHERE Datepart(dw, rdate) = 1
AND rshiftid > 2
GROUP BY rempid
HAVING Count(rshiftid) > 0)C,
(SELECT rempid,
Count(rshiftid) AS Holidays
FROM rtmp1
WHERE rdate IN (SELECT pubhdt
FROM pubhol)
AND rshiftid > 2
GROUP BY rempid
HAVING Count(rshiftid) > 0)D,
(SELECT empid,
[fname] + ' ' + [sname] AS flName
FROM remp1)E
WHERE A.rempid = B.rempid
AND A.rempid = E.empid
AND A.rempid = C.rempid
AND A.rempid = D.rempid
ORDER BY A.rempid
I would like to add a date range into it, so that I can query the database within 2 dates. The rTmp1 table has a column called rDate. I was wondering what the best way to do this. I could add it to a stored procedure and add variable to each select query. Or is there a better way to run the query within a date range.
i think just add an additional where clause item similar to:
AND ( rDate > somedate AND rDate < someotherdate )
Adding the date range to each query is the most direct solution.
Making it a stored procedure is something that can always be done with a query, but has nothing to do with this specific case.
If the number of records resulting from narrowing down your table to the specified date range is substantially less than the entire table, it might be an option to insert these records into a temporary table or a table variable and run your existing query on that table/resultset.
Though I do not have any data to test, you might consider the following query as it is more easy to read and might perform better. But you have to check the results for yourself and maybe do some adjustments.
DECLARE #startDate date = '12/01/2012'
DECLARE #endDate date = DATEADD(MONTH, 1, #startDate)
SELECT
[e].[empid],
[e].[fname] + ' ' + [e].[sname] AS [flName],
SUM(CASE WHEN [t].[rshiftid] = 2 THEN 1 ELSE 0 END) AS [RDO_Total],
SUM(CASE WHEN [t].[rshiftid] = 6 THEN 1 ELSE 0 END) AS [Grave_Total],
SUM(CASE WHEN [t].[rshiftid] > 2 AND DATEPART(dw, [t].[rdate]) = 1 THEN 1 ELSE 0 END) AS [Sundays],
SUM(CASE WHEN [t].[rshiftid] > 2 AND [h].[pubhdt] IS NOT NULL THEN 1 ELSE 0 END) AS [Holidays]
FROM [remp1] [e]
INNER JOIN [rtmp1] [t] ON [e].[empid] = [t].[rempid]
LEFT JOIN [pubhol] [h] ON [t].[rdate] = [h].[pubhdt]
WHERE [t].[rdate] BETWEEN #startDate AND #endDate
GROUP BY
[e].[empid],
[e].[fname],
[e].[sname]
ORDER BY [empid] ASC