Pivot With Calendar Table - sql-server-2008

I am trying to pivot this data but I am getting an error of
Msg 102, Level 15, State 1, Line 16
Incorrect syntax near ','.
Highlighting the comma after SUM([Total Count]) but it has to be there, what should I change so my query executes properly?
select *
FROM
(
select a.regionalLocale As [RL],
Count(ID) As [Total Count],
CONVERT(VARCHAR(20), dt.week) AS Week
FROM database14.dataTable a
INNER JOIN calendarDB.masterCalendar dt
ON a.SaleDate = dt.FullDate
WHERE a.SaleDate IS NOT NULL
) src
pivot
(
SUM([Total Count]), [RL]
For Week IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
) piv

You've got a few issues with your query.
One you've got the syntax SUM([Total Count]), [RL] in your PIVOT. You only want to include the column you are aggregating here.
Second, there is no need to use count(id) inside your subquery, let the PIVOT aggregation handle the total. Change your code to:
select [RL],
[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13]
FROM
(
select a.regionalLocale As [RL],
ID,
CONVERT(VARCHAR(20), dt.week) AS Week
FROM database14.dataTable a
INNER JOIN calendarDB.masterCalendar dt
ON a.SaleDate = dt.FullDate
WHERE a.SaleDate IS NOT NULL
) src
pivot
(
COUNT(ID)
For Week IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13])
) piv

Related

MySql - Selecting MAX & MIN and returning the corresponding rows

I trying to get the last 6 months of the min and max of prices in my table and display them as a group by months. My query is not returning the corresponding rows values, such as the date time for when the max price was or min..
I want to select the min & max prices and the date time they both occurred and the rest of the data for that row...
(the reason why i have concat for report_term, as i need to print this with the dataset when displaying results. e.g. February 2018 -> ...., January 2018 -> ...)
SELECT metal_price_id, CONCAT(MONTHNAME(metal_price_datetime), ' ', YEAR(metal_price_datetime)) AS report_term, max(metal_price) as highest_gold_price, metal_price_datetime FROM metal_prices_v2
WHERE metal_id = 1
AND DATEDIFF(NOW(), metal_price_datetime) BETWEEN 0 AND 180
GROUP BY report_term
ORDER BY metal_price_datetime DESC
I have made an example, extract from my DB:
http://sqlfiddle.com/#!9/617bcb2/4/0
My desired result would be to see the min and max prices grouped by month, date of min, date of max.. and all in the last 6 months.
thanks
UPDATE.
The below code works, but it returns back rows from beyond the 180 days specified. I have just checked, and it is because it joining by the price which may be duplicated a number of times during the years.... see: http://sqlfiddle.com/#!9/5f501b/1
You could use twice inner join on the subselect for min and max
select a.metal_price_datetime
, t1.highest_gold_price
, t1.report_term
, t2.lowest_gold_price
,t2.metal_price_datetime
from metal_prices_v2 a
inner join (
SELECT CONCAT(MONTHNAME(metal_price_datetime), ' ', YEAR(metal_price_datetime)) AS report_term
, max(metal_price) as highest_gold_price
from metal_prices_v2
WHERE metal_id = 1
AND DATEDIFF(NOW(), metal_price_datetime) BETWEEN 0 AND 180
GROUP BY report_term
) t1 on t1.highest_gold_price = a.metal_price
inner join (
select a.metal_price_datetime
, t.lowest_gold_price
, t.report_term
from metal_prices_v2 a
inner join (
SELECT CONCAT(MONTHNAME(metal_price_datetime), ' ', YEAR(metal_price_datetime)) AS report_term
, min(metal_price) as lowest_gold_price
from metal_prices_v2
WHERE metal_id = 1
AND DATEDIFF(NOW(), metal_price_datetime) BETWEEN 0 AND 180
GROUP BY report_term
) t on t.lowest_gold_price = a.metal_price
) t2 on t2.report_term = t1.report_term
simplified version of what you should do so you can learn the working process.
You need calculate the min() max() of the periods you need. That is your first brick on this building.
you have tableA, you calculate min() lets call it R1
SELECT group_field, min() as min_value
FROM TableA
GROUP BY group_field
same for max() call it R2
SELECT group_field, max() as max_value
FROM TableA
GROUP BY group_field
Now you need to bring all the data from original fields so you join each result with your original table
We call those T1 and T2:
SELECT tableA.group_field, tableA.value, tableA.date
FROM tableA
JOIN ( ... .. ) as R1
ON tableA.group_field = R1.group_field
AND tableA.value = R1.min_value
SELECT tableA.group_field, tableA.value, tableA.date
FROM tableA
JOIN ( ... .. ) as R2
ON tableA.group_field = R2.group_field
AND tableA.value = R2.max_value
Now we join T1 and T2.
SELECT *
FROM ( .... ) as T1
JOIN ( .... ) as T2
ON t1.group_field = t2.group_field
So the idea is if you can do a brick, you do the next one. Then you also can add filters like last 6 months or something else you need.
In this case the group_field is the CONCAT() value

Incorrect subtotals & Totals in mysql select

I've managed to separate the negatives & positives in the sql select below and I am trying to get the subtotals & totals as indicated in the table pic belom the third column is what the correct results should be.
Below is sql select I've used but its returning the results in column 2 of the above table and its not correct. How can I get the subtotal & total results in column 3
Thanks & Regards
SELECT * FROM
(SELECT
party AS "Account",
sum(debit-credit) AS "Balance"
FROM `tabGL Entry`
WHERE party_type ="Customer" AND MONTH(posting_date) = MONTH(Now()) -1
GROUP BY party WITH ROLLUP
HAVING sum(debit-credit) < 0
UNION ALL
SELECT
party AS "Account",
sum(debit-credit) AS "Balance"
FROM `tabGL Entry`
WHERE party_type ="Customer" AND MONTH(posting_date) = MONTH(Now()) -1
GROUP BY party WITH ROLLUP
HAVING sum(debit-credit) > 0
) rec
UNION ALL
SELECT NULL AS party, sum(dep) AS Balance
FROM (
SELECT SUM(credit-debit) AS dep
FROM `tabGL Entry`
UNION ALL
SELECT SUM(credit-debit) AS nodep
FROM `tabGL Entry`
) AS recb
GROUP BY party WITH ROLLUP
Use this syntax to prevent GROUP BY from being attached incorrectly:
( SELECT ... GROUP BY ... )
UNION ALL
( SELECT ... GROUP BY ... )
Versus
( SELECT ... )
UNION ALL
( SELECT ... )
GROUP BY ...
Where did the word 'Subtotal' come from? I don't see it in the query.
I suspect the inner WITH ROLLUP is tossed. What happens if you remove them?

PIVOT with Multiple Dates inside "IN" clause

I have here some problem on inserting multiple dates inside in clause.
Here is the code that I have seen through the internet research.
;with cte (datelist, maxdate) as
(
select min(arrivaldate) datelist, max(departuredate) maxdate
from BookingsPerPerson
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
)
select c.datelist
into #tempDates
from cte c
select *
from
(
select b.person_id, b.arrivaldate, b.departuredate,
d.datelist,
convert(CHAR(10), datelist, 120) PivotDate
from #tempDates d
left join BookingsPerPerson b
on d.datelist between b.arrivaldate and b.departuredate
) x
pivot
(
count(datelist)
for PivotDate in ([2012-01-01], [2012-01-02], [2012-01-03],
[2012-01-04], [2012-01-05], [2012-01-06] , [2012-01-07])
) p;
Since the code is manually adding the dates inside the IN clause
pivot
(
count(datelist)
for PivotDate in ([2012-01-01], [2012-01-02], [2012-01-03],
[2012-01-04], [2012-01-05], [2012-01-06] , [2012-01-07])
) p;
Can I just use the date which is extract/split by this code
;with cte (datelist, maxdate) as
(
select min(arrivaldate) datelist, max(departuredate) maxdate
from BookingsPerPerson
union all
select dateadd(dd, 1, datelist), maxdate
from cte
where datelist < maxdate
)
select c.datelist
into #tempDates
from cte c
And use the SELECT statement on the "IN" clause inside the pivot statement?
like this?
pivot
(
count(datelist)
for PivotDate in (select c.datelist from #tempDates)
) p;
I tried this but it gives me an error?
Is there any way that I can add multiple dates from
a temporary table and include it inside the IN clause?
YOU CAN TRY IT HERE : http://sqlfiddle.com/#!3/8857c/9
Yes there is a way. you place first the concatenated dates in one variable..
for example:
DECLARE #dateArray AS VARCHAR(500)
SELECT #dateArray = '02/01/2014,02/02/2014,02/03/2014,02/04/2014'
then create a dynamic sql query:
set #query = 'SELECT * FROM TABLE
PIVOT (count(datelist) PivotDate in (' + #dateArray + '))
hope it helped you in a way. :)

postgresql to mssql query conversion

can any one help me to convert the following query into mssql which is working on postgresql now
query is to take the updated datetime of the report in the asc order of the date
select
count(*) as count,
TO_CHAR(RH.updated_datetime,'dd-mm-YYYY') as date,
SUM(
extract (
epoch from (
RH.updated_datetime - PRI.procedure_performed_datetime
)
)
)/count(*) as average_reporting_tat
from
report R,
report_history RH,
study S,
procedure_runtime_information PRI,
priorities PP,
patient P,
procedure PR
where
RH.report_fk=R.pk and RH.pk IN (
select pk from (
select * from report_history where report_fk=r.pk order by revision desc limit 1
) as result
where old_status_fk IN (21, 27)
) AND R.study_fk = S.pk
AND S.procedure_runtime_fk = PRI.pk
AND PRI.procedure_fk = PR.pk
AND S.priority_fk = PP.pk
AND PRI.patient_fk = P.pk
AND RH.updated_datetime >= '2013-05-01'
AND RH.updated_datetime <= '2013-05-12'
group by date
If I read your query properly, your problem is that you need to list everything in the group by clause that is in your column list which is not part of an aggregate. So your group by needs to be:
GROUP BY RH.updated_datetime
If this doesn't fix it, please post the error message you are getting.

Doctrine subquery within subquery

I'm trying to convert a raw mysql query to use doctrine.
The table is full of rows of statistics, and my query is checking to see how far from the average the stat gain has deviated from the average increase each day.
The SQL version works exactly how I'd expect it to act. Converting to Doctrine gives me an error.
Here's the original:
SELECT
l.*,
DAY(l.created_at) as day,
MONTH(l.created_at) as month,
YEAR(l.created_at) as year,
(
MAX(l.infamyrenown) -
MIN(l.infamyrenown) -
(
SELECT AVG(infamydifference) as avginf FROM
(
SELECT (
MAX(inf.infamyrenown) -
MIN(inf.infamyrenown)
) as infamydifference
FROM lotro_record inf
GROUP BY DAY(inf.created_at)
) as p1
)
) as infamy_deviance
FROM
lotro_record l
GROUP BY
year,month,day
And here's the broken Doctrine query:
Doctrine_Core::getTable("LotroRecord")
->createQuery("l")
->select("l.*")
->addSelect("DAY(created_at)")
->addSelect("MONTH(created_at)")
->addSelect("YEAR(created_at)")
->addSelect("(
MAX(l.infamyrenown) -
MIN(l.infamyrenown) -
(
select AVG(infamydifference) as avginf FROM (
SELECT (
MAX(inf.infamyrenown) -
MIN(inf.infamyrenown)
) as infamydifference
FROM LotroRecord inf
GROUP BY DAY(inf.created_at)
) as p1
)
) as infamy_deviance")
->where("lotro_character_id = {$this->getId()}")
->groupBy("DAY(created_at)");
Which generates this SQL:
SELECT l.id AS l__id,
l.infamyrenown AS l__infamyrenown,
l.kills AS l__kills,
l.killing_blows AS l__killing_blows,
l.kills_above_rating AS l__kills_above_rating,
l.kills_below_rating AS l__kills_below_rating,
l.deaths AS l__deaths,
l.lotro_character_id AS l__lotro_character_id,
l.created_at AS l__created_at,
l.updated_at AS l__updated_at,
DAY(l.created_at) AS l__0,
MONTH(l.created_at) AS l__1,
YEAR(l.created_at) AS l__2,
( Max(l.infamyrenown) - Min(l.infamyrenown) - (SELECT
Avg(infamydifference) AS avginf
FROM
(SELECT ( Max(l2.infamyrenown) - Min(l2.infamyrenown) ) AS l__0
FROM lotro_record l2
GROUP BY DAY(l2.created_at)) AS p1) ) AS l__3
FROM lotro_record l
WHERE ( l.lotro_character_id = 1 )
GROUP BY DAY(l.created_at)
The error is:
Unknown column 'infamydifference' in 'field list'
Any ideas?
I think it wants you to call it inf.infamydifference instead of just infamydifference in the DQL query you're written:
select AVG(inf.infamydifference) as avginf