Keep max date in column when pivoting - sql

I have this data that i want to pivot. It all goes well as long as i don't include the datewhat differs on some rows. I would like to keep the highest date for each set of idAnalyseItem.
My query looks like this for the moment, and i struggle with how the date part of it fits in.
WITH Analyser AS (
SELECT ElementItems.idAnalyseItem as Analyse, ESymbol as Symbol, EIValue as Verdi
FROM ElementItems
)
SELECT * FROM Analyser
PIVOT(
MAX(Verdi) FOR Symbol IN ([Justert],[Produkt Type],[Start Time],[Stopp Time],[Dunger],[Våtvekt],[Vann],[Fe-tot],[Fe-Mag],[Svovel],[P],[SiO2],[MnO],[Al2O3],[CaO],[1,19],[0,841],[0,425],[0,212],[0,125],[0,106],[0,075],[0,063],[0,045],[0,02])
) AS PivotTable
ORDER BY Analyse DESC
This is my dataset. Microsoft SQL Server 2008.

You can change your query like following, to get the MAX(EIDateTime) for all the rows belongs to a idAnalyseItem
;WITH Analyser AS (
SELECT ElementItems.idAnalyseItem as Analyse, ESymbol as Symbol, EIValue as Verdi, MAX(EIDateTime) OVER(PARTITION BY ElementItems.idAnalyseItem) EIDateTime
FROM ElementItems
)
SELECT * FROM Analyser
PIVOT(
MAX(Verdi) FOR Symbol IN ([Justert],[Produkt Type],[Start Time],[Stopp Time],[Dunger],[Våtvekt],[Vann],[Fe-tot],[Fe-Mag],[Svovel],[P],[SiO2],[MnO],[Al2O3],[CaO],[1,19],[0,841],[0,425],[0,212],[0,125],[0,106],[0,075],[0,063],[0,045],[0,02])
) AS PivotTable
ORDER BY Analyse DESC
Same thing can be done using GROUP BY like following.
;WITH Analyser AS (
SELECT ElementItems.idAnalyseItem as Analyse, ESymbol as Symbol, EIValue as Verdi, MAX(EIDateTime) as EIDateTime
FROM ElementItems
GROUP BY idAnalyseItem,ESymbol,EIValue
)
SELECT * FROM Analyser
PIVOT(
MAX(Verdi) FOR Symbol IN ([Justert],[Produkt Type],[Start Time],[Stopp Time],[Dunger],[Våtvekt],[Vann],[Fe-tot],[Fe-Mag],[Svovel],[P],[SiO2],[MnO],[Al2O3],[CaO],[1,19],[0,841],[0,425],[0,212],[0,125],[0,106],[0,075],[0,063],[0,045],[0,02])
) AS PivotTable
ORDER BY Analyse DESC

Related

Self join SQL is taking too much time to execute

Below SQL is taking too much time to execute.Dont know where is am doing wrong but yes getting proper result.can i further simplify this sql.
This is oracle db and jmc_job_step table contains huge records.
select *
from
jmc_job_run_id jobrunid0_
inner join
jmc_job_step jobsteps1_
on jobrunid0_.id=jobsteps1_.job_run_id
where
(
jobsteps1_.creation_date in (
select
min(jobstep2_.creation_date)
from
jmc_job_step jobstep2_
where
jobrunid0_.id=jobstep2_.job_run_id
group by
jobstep2_.job_run_id ,
jobstep2_.job_step_no
)
)
or jobsteps1_.job_step_progress_value in (
select
max(jobstep3_.job_step_progress_value)
from
jmc_job_step jobstep3_
where
jobrunid0_.id=jobstep3_.job_run_id
group by
jobstep3_.job_run_id ,
jobstep3_.job_step_no
)
)
order by
jobrunid0_.job_start_time desc
This is useless; it says "I don't care what those columns contain", but - yet - you give the database engine to check those values anyway.
(
upper(jobrunid0_.tenant_id) like '%'|| null
)
and (
upper(jobrunid0_.job_run_id) like '%'||null||'%'
)

Only include employees currently working for company

Thanks to the input I've received earlier on this site, I use the below code to summarize how many months of experience our employees have in a specific market.
The issue however is that the end-result shows the summarized data for all employees, even if they no longer work for our company. What I actually would like, is the same output, but then only for those employees who are still present in the youngest date (SNAPSHOT_DATE).
I managed to get to a solution where I manually update the snapshot every month, but I'd rather go for an automated solution where the code itself determines what the youngest snapshot is.
Many thanks for your support :)
SELECT EMPLOYEE_ID,
ISNULL([Developing & Emerging],0) AS [Experience - D&E],
ISNULL([Developed],0) AS [Experience - D]
FROM
(
SELECT EMPLOYEE_ID,MARKET_TYPE_DESC,COUNT(SNAPSHOT_DATE) T
FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL]
WHERE ALLC_SER_NUM = '1'
GROUP BY EMPLOYEE_ID,MARKET_TYPE_DESC
)P
PIVOT(
SUM(T)
FOR MARKET_TYPE_DESC IN ([Developing & Emerging],[Developed])
)PVT
It sounds like you are trying to reduce your query down to only return results where [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL].SNAPSHOT_DATE == the latest snapshot date.
There are multiple ways you can achieve this, but probably the simplest and most easily readable would be something like the following:
DECLARE #SnapshotDate DATETIME
SELECT #SnapshotDate = MIN(SNAPSHOT_DATE ) FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL]
And then use a CTE to reduce the included list of employees to only those which have a record which matches this snapshot date, by joining the CTE in your main query:
;WITH CTE AS
(
SELECT EMPLOYEE_ID
FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL]
WHERE SNAPSHOT_DATE = #SnapshotDate
)
SELECT EMPLOYEE_ID,
ISNULL([Developing & Emerging],0) AS [Experience - D&E],
ISNULL([Developed],0) AS [Experience - D]
FROM
(
SELECT ED.EMPLOYEE_ID,ED.MARKET_TYPE_DESC,COUNT(ED.SNAPSHOT_DATE) T
FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] ED
JOIN CTE C ON C.EMPLOYEE_ID = ED.EMPLOYEE_ID
WHERE ED.ALLC_SER_NUM = '1'
GROUP BY ED.EMPLOYEE_ID,ED.MARKET_TYPE_DESC
)P
PIVOT(
SUM(T)
FOR MARKET_TYPE_DESC IN ([Developing & Emerging],[Developed])
)PVT
Thanks, #James S! Much appreciated :)
Perhaps a stupid question, but should I just create one query combining both your inputs? Looking like the one below?
DECLARE #SnapshotDate DATETIME
SELECT #SnapshotDate = MIN(SNAPSHOT_DATE ) FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL]
WITH CTE AS
(
SELECT EMPLOYEE_ID
FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL]
WHERE SNAPSHOT_DATE = #SnapshotDate
)
SELECT EMPLOYEE_ID,
ISNULL([Developing & Emerging],0) AS [Experience - D&E],
ISNULL([Developed],0) AS [Experience - D]
FROM
(
SELECT EMPLOYEE_ID,MARKET_TYPE_DESC,COUNT(SNAPSHOT_DATE) T
FROM [db_name].[AGL_V_HRA_FE_R].[VW_HRA_EMPLOYEE_DETAIL] ED
JOIN CTE C ON C.EMPLOYEE_ID = ED.EMPLOYEE_ID
WHERE ALLC_SER_NUM = '1'
AND SNAPSHOT_DATE = #SnapshotDate
GROUP BY EMPLOYEE_ID,MARKET_TYPE_DESC
)P
PIVOT(
SUM(T)
FOR MARKET_TYPE_DESC IN ([Developing & Emerging],[Developed])
)PVT
I tried this, but it seems that doesn't work as it gives the following reply:
Incorrect syntax near 'CTE'. If this is intended to be a common table expression, you need to explicitly terminate the previous statement with a semi-colon.```

Transform and PIVOT Microsoft Access - SQL Server

I am trying to convert an Microsoft Access query into SQL Server.
In Access, the SQL is...
TRANSFORM Count(Time_Difference.sc) AS CountOfsc
SELECT Time_Difference.sc
FROM Time_Difference
WHERE (((Time_Difference.Week)>=44 And (Time_Difference.Week)<=48))
GROUP BY Time_Difference.sc
PIVOT Time_Difference.spc;
I tried to convert to SQL...
SELECT *
FROM
(
SELECT (Time_Difference.sc AS CountOfsc,
Time_Difference.sc,spc
FROM Time_Difference
WHERE (((Time_Difference.Week)>=44 And (Time_Difference.Week)<=48))
GROUP BY Time_Difference.sc
)T
PIVOT
(
COUNT(CountOfsc)
FOR Time_Difference.spc IN (A,B,C,D,E)
)P
Does anyone know what I am doing wrong?
Without seeing any example data, I would guess you are looking for something like this:
select [O1_supplier],A,B,C,D,E
from (
select
[O1_supplier]
, spc
, sc
from Time_Difference
where Time_Difference.Week>=44
and Time_Difference.Week<=48
) as T
pivot (count(sc) for Time_Difference.spc in (A,B,C,D,E))P

Why would the query show data from the wrong month?

I have a query:
;with date_cte as(
SELECT r.starburst_dept_name,r.monthly_past_date as PrevDate,x.monthly_past_date as CurrDate,r.starburst_dept_average - x.starburst_dept_average as Average
FROM
(
SELECT *,ROW_NUMBER() OVER(PARTITION BY starburst_dept_name ORDER BY monthly_past_date) AS rowid
FROM intranet.dbo.cse_reports_month
) r
JOIN
(
SELECT *,ROW_NUMBER() OVER(PARTITION BY starburst_dept_name ORDER BY monthly_past_date) AS rowid
FROM intranet.dbo.cse_reports_month
Where month(monthly_past_date) > month(DATEADD(m,-2,monthly_past_date))
) x
ON r.starburst_dept_name = x.starburst_dept_name AND r.rowid = x.rowid+1
Where r.starburst_dept_name is NOT NULL
)
Select *
From date_cte
Order by Average DESC
So doing some testing, I have alter some columns data, to see why it gives me certain information. I don't know why when I run the query it gives my a date column that should not be there from "january" (row 4) like the picture below:
The database has more data that has the same exact date '2014-01-25 00:00:00.000', so I'm not sure why it would only get that row and compare the average?
I did before I run the query alter the column in that row and change the date? But I'm not sure if that would have something to do with it.
UPDATE:
I have added the sqlfinddle,
What I would like to get it subtract the average
from last_month - last 2 month ago.
It Was actually working until I made a change and alter the data.
I made the changes to test a certain situation, which obviously lead
to learning that there are flaws to the query.
Based on your SQL Fiddle, this eliminates joins from prior than month-2 from showing up.
SELECT
thismonth.starburst_dept_name
,lastmonth.monthtly_past_date [PrevDate]
,thismonth.monthtly_past_date [CurrDate]
,thismonth.starburst_dept_average - lastmonth.starburst_dept_average as Average
FROM dbo.cse_reports thismonth
inner join dbo.cse_reports lastmonth on
thismonth.starburst_dept_name = lastmonth.starburst_dept_name
AND month(DATEADD(MONTH,-1,thismonth.monthtly_past_date))=month(lastmonth.monthtly_past_date)
WHERE MONTH(thismonth.monthtly_past_date)=month(DATEADD(MONTH,-1,GETDATE()))
Order by thismonth.starburst_dept_average - lastmonth.starburst_dept_average DESC

Access 2010 Crosstab Query Expression--in One Query

I would like to add this expression:
([2013]/[2012]-1) AS [Change%]
As a field to the crosstab query below:
TRANSFORM
Sum(Data.Spending)
SELECT
Data.Category
FROM
Data
WHERE
(((Data.Year)="2012" Or (Data.Year)="2013"))
GROUP BY
Data.Category
PIVOT
Data.Year;
This is solved through using another table in this thread: Access 2007 Crosstab Query Expression
But for my purposes I need to have everything together in one query.
This is because I am writing SQL in another program, http://www.ljzsoft.com/ppt-report.htm, which uses the query to directly access an Access database.
As you have probably discovered, Access won't let us use a Crosstab query as a subquery. If we try to do
SELECT ...
FROM
(
TRANSFORM
we get "Syntax error in FROM clause". One workaround is to do all of the aggregations, create the derived (calculated) values, UNION them together, and then "crosstab" that. In your case:
TRANSFORM Sum(ColValue) AS SumOfColValue
SELECT Category
FROM
(
SELECT Category, [Year] AS ColHead, Sum(Spending) AS ColValue
FROM Data
WHERE [Year] IN ("2012", "2013")
GROUP BY Category, [Year]
UNION ALL
SELECT
curr.Category,
"Change%" AS ColHead,
(curr.SumOfSpending/prev.SumOfSpending-1) AS ColValue
FROM
(
SELECT Category, [Year], Sum(Spending) AS SumOfSpending
FROM Data
WHERE [Year] IN ("2012", "2013")
GROUP BY Category, [Year]
) AS curr
INNER JOIN
(
SELECT Category, [Year], Sum(Spending) AS SumOfSpending
FROM Data
WHERE [Year] IN ("2012", "2013")
GROUP BY Category, [Year]
) AS prev
ON prev.Category = curr.Category
AND CLng(prev.[Year]) = (CLng(curr.[Year]) - 1)
)
GROUP BY Category
PIVOT ColHead
which, for my sample data, returns
Category 2012 2013 Change%
--------- ---- ---- -----------------
Category1 123 345 1.80487804878049
Category2 234 456 0.948717948717949
If that is too nasty for your liking then you might want to investigate whether your reporting tool supports calculated report fields (e.g., in Crystal Reports I believe they are called "Formula Fields").