Trying to get an overall distinct count of the employees for a range of records which has a group by on it.
I've tried using the "over()" clause but couldn't get that to work. Best to explain using an example so please see my script below and wanted result below.
EDIT:
I should mention I'm hoping for a solution that does not use a sub-query based on my "sales_detail" table below because in my real example, the "sales_detail" table is a very complex sub-query.
Here's the result I want. Column "wanted_result" should be 9:
Sample script:
CREATE TEMPORARY TABLE [sales_detail] (
[employee] varchar(100),[customer] varchar(100),[startdate] varchar(100),[enddate] varchar(100),[saleday] int,[timeframe] varchar(100),[saleqty] numeric(18,4)
);
INSERT INTO [sales_detail]
([employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty])
VALUES
('Wendy','Chris','8/1/2019','8/12/2019','5','Afternoon','1'),
('Wendy','Chris','8/1/2019','8/12/2019','5','Morning','5'),
('Wendy','Chris','8/1/2019','8/12/2019','6','Morning','6'),
('Dexter','Chris','8/1/2019','8/12/2019','2','Mid','2.5'),
('Jennifer','Chris','8/1/2019','8/12/2019','4','Morning','2.75'),
('Lila','Chris','8/1/2019','8/12/2019','2','Morning','3.75'),
('Rita','Chris','8/1/2019','8/12/2019','2','Mid','1'),
('Tony','Chris','8/1/2019','8/12/2019','4','Mid','2'),
('Tony','Chris','8/1/2019','8/12/2019','1','Morning','6'),
('Mike','Chris','8/1/2019','8/12/2019','4','Mid','1.5'),
('Logan','Chris','8/1/2019','8/12/2019','3','Morning','6.25'),
('Blake','Chris','8/1/2019','8/12/2019','4','Afternoon','0.5')
;
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
9 AS [wanted_result]
FROM (
SELECT
[employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty]
FROM
[sales_detail]
) AS [s]
GROUP BY
[timeframe]
;
If I understand correctly, you are simply looking for a COUNT(DISTINCT) for all employees in the table? I believe this query will return the results you are looking for:
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
(SELECT COUNT(DISTINCT [employee]) FROM [sales_detail]) AS [employee_count2],
9 AS [wanted_result]
FROM #sales_detail [s]
GROUP BY
[timeframe]
You can try this below option-
SELECT
[timeframe],
SUM([saleqty]) AS [total_qty],
COUNT(DISTINCT [s].[employee]) AS [employee_count1],
SUM(COUNT(DISTINCT [s].[employee])) OVER() AS [employee_count2],
[wanted_result]
-- select count form sub query
FROM (
SELECT
[employee],[customer],[startdate],[enddate],[saleday],[timeframe],[saleqty],
(select COUNT(DISTINCT [employee]) from [sales_detail]) AS [wanted_result]
--caculate the count with first sub query
FROM [sales_detail]
) AS [s]
GROUP BY
[timeframe],[wanted_result]
Use a trick where you only count each person on the first day they are seen:
select timeframe, sum(saleqty) as total_qty),
count(distinct employee) as employee_count1,
sum( (seqnum = 1)::int ) as employee_count2
9 as wanted_result
from (select sd.*,
row_number() over (partition by employee order by startdate) as seqnum
from sales_detail sd
) sd
group by timeframe;
Note: From the perspective of performance, your complex subquery is only evaluated once.
I have the following table named 'MoviesInStock'
I would like to select to latest movies from the last month.
In this case, the result should be only the movie 'The Mummy' since he is latest one.
I was trying the next query:
SELECT MovieName
FROM MovieInStock
WHERE Month = (SELECT MAX(Month) FROM MovieInStock) AND
(SELECT MovieName FROM MovieInStock WHERE Year = (SELECT MAX(Year) FROM MovieInStock))
But choosing the AND operator was not that smart. I was also trying to create a temporary table using SELECT INTO # for selecting the Max Year and then on the temp table to select the Max Month, but then it become complicated to me.
You are overcomplicating the problem. You can use TOP with ORDER BY.
Because you say "movies":
select top (1) with ties mis.*
from movieinstock mis
order by year desc, month desc
other solution, but better is Gordon Solution
with maxdt as (
select MAX(Month) MaxMonth, MAX(Year) MaxYear FROM MovieInStock
)
SELECT top 1 MovieName
FROM MovieInStock f1
inner join maxdt f2 on f1.Month=f2.MaxMonth and f1.Year=MaxYear
I have a attendance table as below i want group them by time and section,status is null mean that the employee is absent :
Any idea how to generate output like below?
my current code :
SELECT TIME,COUNT(SECTION) AS SECTION,COUNT(STATUS) AS COUNT
FROM attendance_record
GROUP BY TIME,SECTION
ORDER BY TIME
If I understand your question, just use conditional aggregation:
SELECT TIME, SECTION, COUNT(*) as TOTAL,
COUNT(STATUS) AS IN, ( COUNT(*) - COUNT(STATUS) ) as ABSENT
FROM attendance_record
GROUP BY TIME, SECTION
ORDER BY TIME
I have a select query that gets a CarID, month, mileage and CO2 emission.
Now it gives for each month per car the mileage like this:
month 1: 5000
month 2: 5200
...
What I really need is that it takes the current value minus the previous one. I get data between a certain time frame and I already included a mileage point before that time frame. So it would be possible to get the total miles per month, I just don't know how. What I want is this.
pre timeframe: 5000
month 1: 200
month 2: 150
...
How would I do this?
edit: code, I have not yet tried anything as I have no clue how to start to do this.
resultlist as (
SELECT
CarID
, '01/01/2000' as beginmonth
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
totalmileagelist
GROUP BY CarID
UNION
SELECT
CarID
, beginmonth
, MAX(kilometerstand) as Kilometers
, MAX(Co2Emission) as CO2
FROM
resultunionlist
GROUP BY CarID, beginmonth
)
select * from resultlist
order by CarID, beginmonth
Edit2: explanation to the code
In the first part of the result list I grab the latest mileage per car. In the second part, after the union, I grab per month per car the latest mileage.
If you just want to subtract the previous milage, use the lag() function:
select ml.*,
(kilometerstand - lag(kilometerstand) over (partition by carid order by month)
) as diff
from totalmileagelist ml;
lag() is available in SQL Server 2012+. In earlier versions you can use a correlated subquery or outer apply.
(I missed the version because it is in the title and not on a tag.) In SQL Server 2008:
select ml.*,
(ml.mileage - mlprev.mileage) as diff
from totalmileagelist ml outer apply
(select top 1 ml2.*
from totalmileagelist ml2
where ml2.CarId = ml.CarId and
ml2.month < ml.month
order by ml2.month desc
) mlprev;
Try like this:
SELECT id, yourColumnValue,
COALESCE(
(
SELECT TOP 1 yourColumnValue
FROM table_name t
WHERE t.id> tbl.id
ORDER BY
rowInt
), 0) - yourColumnValue AS diff
FROM table_name tbl
ORDER BY
id
or like this using rank()
select rank() OVER (ORDER BY id) as 'RowId', mileage into temptable
from totalmileagelist
select t1.mileage - t2.mileage from temptable t1, temptable t2
where t1.RowId = t2.RowId - 1
drop table temptable
I am able to calculate the percentage count on a particular date in a Microsoft Access 2007 SQL query using:
SELECT Date, Val, (Count(Val) / (SELECT Count(*) From Table HAVING Date=#7/31/2012#) as PercentVal
FROM Table
GROUP BY Date, Val
HAVING Date=#7/31/2012#
However, I would like to make this same calculation over every date using the count totals . For instance, the query:
SELECT Date, Val, Count(*) AS CountVal
FROM Table
GROUP BY Date, Val
finds the counts in every period. I would like to add an additional column with the percent counts. However, I can't seem to figure out how to calculate count percentage in every period without using the above block of text and setting up queries for each individual period.
You can subquery it like this:
SELECT A.ADate, A.Val, COUNT(A.Val) / B.DateCount
FROM Table1 AS A
INNER JOIN (
SELECT C.ADate, COUNT(*) AS DateCount
FROM Table1 C
GROUP BY C.ADate
) AS B ON A.ADate = B.ADate
GROUP BY A.ADate, A.Val, B.DateCount