I've got a set of data that looks something like this (VERY simplified):
productId Qty dateOrdered
--------- --- -----------
1 2 10/10/2008
1 1 11/10/2008
1 2 10/10/2009
2 3 10/12/2009
1 1 10/15/2009
2 2 11/15/2009
Out of this, we're trying to create a query to get something like:
productId Year Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
--------- ---- --- --- --- --- --- --- --- --- --- --- --- ---
1 2008 0 0 0 0 0 0 0 0 0 2 1 0
1 2009 0 0 0 0 0 0 0 0 0 3 0 0
2 2009 0 0 0 0 0 0 0 0 0 3 2 0
The way I'm doing this now, I'm doing 12 selects, one for each month, and putting those in temp tables. I then do a giant join. Everything works, but this guy is dog slow.
select productId, Year(dateOrdered) Year
,isnull(sum(case when month(dateOrdered) = 1 then Qty end), 0) Jan
,isnull(sum(case when month(dateOrdered) = 2 then Qty end), 0) Feb
,isnull(sum(case when month(dateOrdered) = 3 then Qty end), 0) Mar
,isnull(sum(case when month(dateOrdered) = 4 then Qty end), 0) Apr
,isnull(sum(case when month(dateOrdered) = 5 then Qty end), 0) May
,isnull(sum(case when month(dateOrdered) = 6 then Qty end), 0) Jun
,isnull(sum(case when month(dateOrdered) = 7 then Qty end), 0) Jul
,isnull(sum(case when month(dateOrdered) = 8 then Qty end), 0) Aug
,isnull(sum(case when month(dateOrdered) = 9 then Qty end), 0) Sep
,isnull(sum(case when month(dateOrdered) = 10 then Qty end), 0) Oct
,isnull(sum(case when month(dateOrdered) = 11 then Qty end), 0) Nov
,isnull(sum(case when month(dateOrdered) = 12 then Qty end), 0) Dec
from Table1
group by productId, Year(dateOrdered)
SQL Fiddle
SELECT productId, YEAR,
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=1),0) as 'JAN',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=2),0) as 'FEB',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=3),0) as 'MAR',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=4),0) as 'APR',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=5),0) as 'MAY',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=6),0) as 'JUN',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=7),0) as 'JUL',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=8),0) as 'AUG',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=9),0) as 'SEP',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=10),0) as 'OCT',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=11),0) as 'NOV',
ISNULL((SELECT SUM(Qty) FROM Product WHERE productId=X.productId AND YEAR=YEAR(dateOrdered) AND MONTH(dateOrdered)=12),0) as 'DEC'
FROM (
SELECT productId, YEAR(dateOrdered) AS YEAR FROM Product
GROUP BY YEAR(dateOrdered),ProductId) X
For those using Big Query, you can use the following:
select *
from UNNEST(GENERATE_DATE_ARRAY('2015-10-01', '2019-10-01', INTERVAL 1 MONTH))
See https://cloud.google.com/bigquery/docs/reference/standard-sql/functions-and-operators?hl=fr#generate_date_array
You can use either a Union of your queries rather than temp tables or use the pivot option.
Here's a forum discussion on it:
Sql Server Forums - Show the row-wise data as column-wise
This qualifies as a presentation concern.
Presentation and SQL don't always mix well.
Isolating your presentation logic in the application layer will:
save you maintenance time—change your application code, but keep your SQL intact;
enable you to more quickly adapt to ephemeral client requirements;
give you more satisfaction than fiddling with a cross-tab or pivot-table that maddeningly does almost exactly what you want.
Below is an example of how you might do this in Python (you can use the excellent pyodbc module to connect to SQL Server):
from collections import defaultdict
from datetime import date
dd = defaultdict(int)
# input
rows = [(1,2,date(2008,10,10)), (1,1,date(2008,11,10)),
(1,2,date(2009,10,10)), (2,3,date(2009,10,12)),
(1,1,date(2009,10,15)), (2,2,date(2009,11,15))]
for row in rows:
# row[0] == productId
# row[1] == Qty
# row[2] == dateOrdered
# pyodbc enables referring to column names by name
dd[(row[2].year, row[2].month, row[0])] += row[1]
presentation_rows = sorted(set((i[0], i[2]) for i in dd.keys()))
for i in presentation_rows:
print i[1], i[0],
for j in range(0,13):
try:
print dd[i[0], j, i[1]],
except IndexError:
print 0,
print
# output
# 1 2008 0 0 0 0 0 0 0 0 0 0 2 1 0
# 1 2009 0 0 0 0 0 0 0 0 0 0 3 0 0
# 2 2009 0 0 0 0 0 0 0 0 0 0 3 2 0
try this. So this code will select data within certain time range, then convert it to a new column. For example, in my sql code: it selects time range between '2014-10-01' and '2014-10-31' from column 'L_dt', then create a new column called "October". In this way, we can lay out data at different columns originated from one column.
select
sum(case when L_dt between '2014-10-01' and '2014-10-31' then 1 else 0 end) October,
sum(case when L_dt between '2014-11-01' and '2014-11-30' then 1 else 0 end) November,
sum(case when L_dt between '2014-12-01' and '2014-12-31' then 1 else 0 end) December
from Table;
If the input looks like:
L_dt
2014-10-13
2014-12-21
2014-11-22
2014-10-10
Then the output will be
+---------+----------+----------+
| October | November | December |
+---------+----------+----------+
| 2 | 1 | 1 |
+---------+----------+----------+
Related
I have data that gets restated weekly. In the table below, I receive columns Date, Product, Location, Rate, FlagA, and FlagB. FlagC is a computed column which flags the record where FlagA = 1 as a 1 if FlagB has been flagged as 1 in any future records. Similarly, I need to create a computed column called FlagC_Rate which pulls the value in the Rate column for the row where FlagB = 1 (e.g., 0.06 in this case). Any thoughts on what select statement I should write to get that FlagC_Rate value? I copied my code for the FlagC column as reference.
CODE FOR CALCULATING FLAGC column:
Select (SUM(case when FlagB = 1 then 1 else null end) OVER(Partition by product, location))
* (case when FlagA = 1 then 1 else null end) as FlagC FROM Table
ATTEMPT for FLAGC_RATE
Select (SUM(case when FlagB = 1 then 1 else null end) OVER(Partition by product, location))
* (case when FlagA = 1 then 1 else null end) * (case when FlagB = 1 then Rate else null end) as FLAGC_Rate FROM Table
SAMPLE DATA AND EXAMPLE FOR HOW I'M TRYING TO POPULATE FLAGC_RATE
January Data
Date Product Location Rate FlagA FlagB FlagC FlagC_Rate
Jan 2020 WidgetA X 0.05 1 0 0 NULL
February Data (FlagC columns get restated and populated)
Date Product Location Rate FlagA FlagB FlagC FlagC_Rate
Jan 2020 WidgetA X 0.05 1 0 1 0.06
Feb 2020 WidgetA X 0.06 0 1 0 NULL
March Data (Flag C columns are nulls since each product/location pairing will only see one record that has values for FlagC and FlagC_Rate)
Date Product Location Rate FlagA FlagB FlagC FlagC_Rate
Jan 2020 WidgetA X 0.05 1 0 1 0.06
Feb 2020 WidgetA X 0.06 0 1 0 NULL
March 2020 WidgetA X 0.06 0 0 0 NULL
try the following:
Select *
, SUM(case when FlagB = 1 then 1 else null end) OVER(Partition by product, location) * (case when FlagA = 1 then 1 else null end) as FlagC
, max(case when FlagB = 1 then Rate else null end) OVER(Partition by product, location) * (case when FlagA = 1 then 1 else null end) as FLAGC_Rate
from data_table
Please see the db<>fiddle here.
I have a SQL Server table that has Start (1-1-2017) and End (1-1-2022) dates for contracts with invoices being generated each month for current and past months.
I would like to display months as columns even when no invoice has been generated, is that possible with just SQL / Pivot tables or a table with dates as calendar must be created?
I have worked with this code so far.
WITH CTE_MyTable AS
(
SELECT
FORMAT(MIN(StartDate), 'yyyy-MM') AS [MyDate]
FROM
MyTable
UNION ALL
SELECT
FORMAT(MIN(DATEADD(month, 1, StartDate)), 'yyyy-MM') AS [MyDate]
FROM
MyTable
WHERE
FORMAT(DATEADD(month, 1, StartDate),'yyyy-MM') <= (SELECT FORMAT(MAX(EndDate), 'yyyy-MM') AS [MyDate] FROM MyTable)
)
SELECT [MyDate]
FROM CTE_ MyTable
GROUP BY MyDate
OPTION (MAXRECURSION 0);
So let's say your table looked like this (using temp variable so you can just copy/paste/test):
DECLARE #sale TABLE(saledate DATE, saleamt MONEY);
INSERT #sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);
Note that I'm only doing 6 months for simplicity. The following query get the count of sales per month (first query) and the sum of the sales for the second query:
DECLARE #sale TABLE(saledate DATE, saleamt MONEY);
INSERT #sale VALUES ('20170103',500),('20170128',266),('20170303',4002),('20170409',25);
SELECT
[201701] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN 1 END),
[201702] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN 1 END),
[201703] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN 1 END),
[201704] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN 1 END),
[201705] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN 1 END),
[201706] = COUNT(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN 1 END)
FROM #sale t;
SELECT
[201701] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 1 THEN t.saleamt END),0),
[201702] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 2 THEN t.saleamt END),0),
[201703] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 3 THEN t.saleamt END),0),
[201704] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 4 THEN t.saleamt END),0),
[201705] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 5 THEN t.saleamt END),0),
[201706] = ISNULL(SUM(CASE WHEN YEAR(t.saledate)=2017 AND MONTH(t.saledate) = 6 THEN t.saleamt END),0)
FROM #sale t;
These queries return:
201701 201702 201703 201704 201705 201706
----------- ----------- ----------- ----------- ----------- -----------
2 0 1 1 0 0
201701 201702 201703 201704 201705 201706
--------------------- --------------------- --------------------- --------------------- --------------------- ---------------------
766.00 0.00 4002.00 25.00 0.00 0.00
There is a way to pivot columns in SQL- using the Pivot() function (Microsoft Documentation at: https://learn.microsoft.com/en-us/sql/t-sql/queries/from-using-pivot-and-unpivot?view=sql-server-2017)
To display months as columns (1 to 12) the Pivot() function assigns values to (hard-coded) columns. Implemented correctly, there are NULLS where the aggregation doesn't occur due to lack of records. The implied way to replace NULLS with zeroes is by using the COALESCE() function.
The year values of the pivoted data should be grouped and while there is no specific Group By for a pivot, this is implied by how the SourceTable query is written.
In this example code I use the same exact format as the official documentation; with the exception that I additionally group by year and COALESCE NULLs with 0's.
What I am doing is counting the number of records for a given month and year:
SELECT yearval
,COALESCE([1], 0) [Jan]
,COALESCE([2], 0) [Feb]
,COALESCE([3], 0) [Mar]
,COALESCE([4], 0) [Apr]
,COALESCE([5], 0) [May]
,COALESCE([6], 0) [Jun]
,COALESCE([7], 0) [Jul]
,COALESCE([8], 0) [Aug]
,COALESCE([9], 0) [Sep]
,COALESCE([10], 0) [Oct]
,COALESCE([11], 0) [Nov]
,COALESCE([12], 0) [Dec]
FROM
(SELECT YEAR([Your_Date_Column_Here]) AS [yearval]
,MONTH([Your_Date_Column_Here]) AS [monthval]
FROM [Your_Table_Name_Here]) AS SourceTable
PIVOT
(
COUNT(monthval) FOR monthval IN ([1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12])
) AS PivotTable
Would produce this output in my test database:
yearval Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
2015 1952 1122 1678 2364 1125 1308 1414 2103 1031 1340 2506 1015
2016 1123 1413 1568 1421 1278 1252 1048 1290 1251 1571 2647 1253
2017 0 0 0 3 0 1241 2377 2714 6724 1388 1521 1243
2018 2127 2118 2449 2330 2687 3833 3279 883 0 0 0 0
I have a table with the following column, in SQL Server 2012:
ID YEARNBR
-----------
1 2016
2 2015
3 2014
4 2013
1 2015
1 2014
2 2016
I wanted to create a case statement that would check this column YEARNBR:
(case
when yearNBR = 2017 and YearNBR = 2016 and YearNBR = 2015 and yearNBR = 2014
then 1
else 0
end)
If my column YEARNBR would contain the year 2016, 2015, and 2014 and I would be grouping by ID, then I would want another column that would be called: 2014Through2016 that would contain the value 1.
ID 2014Through2016 2015Through2016 2016
--------------------------------------------
1 1 1 1
2 0 1 1
3 0 0 0
4 0 0 0
Any help would be appreciated !
Just use conditional aggregation:
select id,
max(case when yearnbr in (2014, 2015, 2016) then 1 else 0 end) as yr_2014_2016,
max(case when yearnbr = 2016 then 1 else 0 end) as yr_2015
from t
group by id;
create a sameple table:
CREATE TABLE yearz(
id int,
yearnbr int
)
INSERT INTO yearz (id,yearnbr)
VALUES
(1,2016),
(2,2015),
(3,2014),
(4,2013),
(1,2015),
(1,2014),
(2,2016)
using pivot to get your result:
select id, [2014] as '2014through2016', [2015] as '2015through2016', [2016]
from
(
select id, yearnbr
from yearz
) src
pivot
(
count(yearnbr)
for yearnbr in ([2014], [2015], [2016])
) piv;
result:
id 2014through2016 2015through2016 2016
----------- --------------- --------------- -----------
1 1 1 1
2 0 1 1
3 1 0 0
4 0 0 0
Suggestion
You should learn how to use PIVOT and UNPIVOT they are pretty useful. and welcome to StackOverflow. If you find this or any other answer useful please mark it as the solution. That way it would help the community and fellow programmers who run into the same problem as you in the future. Cheers!
select id, sum(yr_2014_2016) as yr_2014_2016, sum(yr_2015_2016) as yr_2015_2016, sum(yr_2016) as yr_2016
from
(
select id
, (case when yearnbr in (2014, 2015, 2016) then 1 else 0 end) as yr_2014_2016
, (case when yearnbr in (2015, 2016) then 1 else 0 end) as yr_2015_2016
, (case when yearnbr = 2016 then 1 else 0 end) as yr_2016
from t;
)
y
group by Id
I am stuck at one query. Actually I want to reduce the number of select I am using. I want to count the number of rows for each scenario.
The description of column of tables are-
Here month is month of year
Name is name of Person
Attention Required is whether any attention is required to them. Here we have conditions-
If attention required is 'N' and isdate(Date)=0 then it comes No Attention required.
If attention required is 'N' and isdate(Date)=1 then it comes Attention Completed
If attention required is 'Y' (then don't need to consider Date column) it comes in Attention Required
Date is simply a date when they require medical attention it can be null or any date
Outsider- IF '0' then it is from the country else it is foreigner. For outsider also, same rules are applied for Attention Required. Just the flag will distinguish between insider and outsider.
Here is the sample table
Month Name Attention Required Y/N Date Outsider
January A N 2015-01-02 0
January B N Null 0
January C Y Null 0
January D Y 2015-01-20 1
February E Y 2015-02-01 1
February F N null 0
February G Y null 0
February H N 2015-02-21 1
February I N null 0
March J Y null 1
March K N 2015-03-08 1
March L N null 0
March M Y null 1
March N N null 1
April O N 2014-04-04 1
April P Y null 0
April Q N 2015-04-10 0
April R Y null 0
April S Y null 1
I want the output in this format-
Month Insider Insider Total Outsider Outsider Total Grand Total
No Attention Required Attention Completed Attention Required No Attention Required Attention Completed Attention Required
January 1 1 1 3 0 0 1 2 4
February 2 0 1 3 0 0 1 2 5
March 1 0 0 1 1 1 2 4 5
April 0 1 2 3 0 1 1 2 5
Grand Total 4 2 4 10 1 3 5 9 19
So I am not able to reduce the no of select. For each column I cannot use a different select query. I am using these query to find the count by month.
For insiders-
select Month, count(Name) as No_Attention_Required
FROM sample where Attention_Required ='N' and isdate(Date)=0
and Outsider='0' group by Month
select Month, count(Name) as Attention_Completed
FROM sample where Attention_Required ='N' and isdate(Date)=1
and Outsider='0' group by Month
select Month, count(Name) as Attention_Required
FROM sample where Attention_Required ='Y'
and Outsider='0' group by Month
select Month, count(Name) as Insider_Total
FROM sample where Outsider='0' group by Month
For Outsiders-
select Month, count(Name) as No_Attention_Required
FROM sample where Attention_Required ='N' and isdate(Date)=0
and Outsider='1' group by Month
select Month, count(Name) as Attention_Completed
FROM sample where Attention_Required ='N' and isdate(Date)=1
and Outsider='1' group by Month
select Month, count(Name) as Attention_Required
FROM sample where Attention_Required ='Y'
and Outsider='1' group by Month
select Month, count(Name) as Outsider_Total
FROM sample where Outsider='1' group by Month
And after that I planned to join them by month.
I need in help reducing the number of select to have this count. Any help will be appreciated. Thanks in advance!
EDITED:
Here I is my sample case statement
select Month,case when Attention_Required='N' and isdate(Date)=0 then count(Name) end as Attention_Not_Needed,
case when Attention_Required='N' and isdate(Date)=1 then count(Name) end as Attention_Completed
FROM sample where Attention_Required='N'
and Outsider='0' group by Month,Attention_Required,Date
You can use CASE to get the numbers in one go, as well as use ROLLUP to get the summaries;
SELECT
Month,
COUNT(CASE WHEN Attention_Required = 'N' AND ISDATE(date) = 0 AND outsider = 0 THEN 1 END) AS I_NAR,
COUNT(CASE WHEN Attention_Required = 'N' AND ISDATE(date) = 1 AND outsider = 0 THEN 1 END) AS I_AC,
COUNT(CASE WHEN Attention_Required = 'Y' AND outsider = 0 THEN 1 END) AS I_AR,
COUNT(CASE WHEN outsider = 0 THEN 1 END) AS I_TOTAL,
COUNT(CASE WHEN Attention_Required = 'N' AND ISDATE(date) = 0 AND outsider = 1 THEN 1 END) AS O_NAR,
COUNT(CASE WHEN Attention_Required = 'N' AND ISDATE(date) = 1 AND outsider = 1 THEN 1 END) AS O_AC,
COUNT(CASE WHEN Attention_Required = 'Y' AND outsider = 1 THEN 1 END) AS O_AR,
COUNT(CASE WHEN outsider = 0 THEN 1 END) AS O_TOTAL,
COUNT(1) AS GRAND_TOTAL
FROM sample
GROUP BY ROLLUP(Month)
...which gives the result;
Month I_NAR I_AC I_AR I_TOTAL O_NAR O_AC O_AR O_TOTAL GRAND_TOTAL
-------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- ----------- -----------
January 1 1 1 3 0 0 1 3 4
February 2 0 1 3 0 1 1 3 5
March 1 0 0 1 1 1 2 1 5
April 0 1 2 3 0 1 1 3 5
NULL 4 2 4 10 1 3 5 10 19
You did not use the CASE statement correctly. Here is how you should have used it:
select Month,
SUM(case when Attention_Required='N' and isdate(Date)=0 then 1 ELSE 0 end) as Attention_Not_Needed
, SUM(case when Attention_Required='N' and isdate(Date)=1 then 1 ELSE 0 end) as Attention_Completed
FROM sample
where Outsider='0'
group by Month
I have a query in MS SQL Server asking for name and some date-related information, depending on two dates, a start- and an enddate.
The problem is, I´m not always getting the same performance. Whenever I request something between the dates;
2010-07-01 00:00:00.000 and
2011-07-21 23:59:59.999
the performance is excellent. I get my result within mseconds. When I request something between these dates, for example,
2011-07-01 00:00:00.000 and
2011-07-21 23:59:59.999
the performance is.. less than good, taking between 20-28 seconds for each query. Do note how the dates giving good performance is more than a year between, while the latter is 20 days.
Is there any particular reason (maybe related to how DATETIME work) for this?
EDIT: The query,
SELECT ENAME,
SUM(CASE DATE WHEN 0 THEN 1 ELSE 0 END) AS U2,
SUM(CASE DATE WHEN 1 THEN 1 ELSE 0 END) AS B_2_4,
SUM(CASE DATE WHEN 2 THEN 1 ELSE 0 END) AS B_4_8,
SUM(CASE DATE WHEN 3 THEN 1 ELSE 0 END) AS B_8_16,
SUM(CASE DATE WHEN 4 THEN 1 ELSE 0 END) AS B_16_24,
SUM(CASE DATE WHEN 5 THEN 1 ELSE 0 END) AS B_24_48,
SUM(CASE DATE WHEN 6 THEN 1 ELSE 0 END) AS O_48,
SUM(CASE DATE WHEN 7 THEN 1 ELSE 0 END) AS status,
AVG(AVG) AS AVG,
SUM(DATE) AS TOTAL
FROM
(SELECT ENAME,
(CASE
WHEN status = 'Öppet' THEN 7
WHEN DATE < 48 THEN
(CASE WHEN DATE BETWEEN 0 AND 2 THEN 0
WHEN DATE BETWEEN 2 AND 4 THEN 1
WHEN DATE BETWEEN 4 AND 8 THEN 2
WHEN DATE BETWEEN 8 AND 16 THEN 3
WHEN DATE BETWEEN 16 AND 24 THEN 4
WHEN DATE BETWEEN 24 AND 48 THEN 5
ELSE - 1 END)
ELSE 6 END) AS DATE,
DATE AS AVG
FROM
(SELECT DATEDIFF(HOUR, cases.date, status.date) AS DATE,
extern.name AS ENAME,
status.status
FROM
cases INNER JOIN
status ON cases.id = status.caseid
AND status.date =
(SELECT MAX(date) AS Expr1
FROM status AS status_1
WHERE (caseid = cases.id)
GROUP BY caseid) INNER JOIN
extern ON cases.owner = extern.id
WHERE (cases.org = 'Expert')
AND (cases.date BETWEEN '2009-01-15 09:48:25.633'
AND '2011-07-21 09:48:25.633'))
AS derivedtbl_1)
AS derivedtbl_2
GROUP BY ENAME
ORDER BY ENAME
(parts of) The tables:
Extern
-ID (->cases.owner)
-name
Cases
-Owner (->Extern.id)
-id (->status.caseid)
-date (case created at this date)
Status
-caseid (->cases.id)
-Status
-Date (can be multiple, MAX(status.date) gives us date when
status was last changed)
I would have thought a statistics issue.
When you are only selecting the most recent dates these may be unrepresented in the statistics yet as the threshold has not yet been reached that would trigger auto updating.
See this blog post for an example.