I currently have this query using PIVOT generating a table like this:
USER | DEC | NOV | OCT
---------------------------------
bob | 3 | 5 | 2
jon | 7 | 0 | 1
tim | 4 | 2 | 6
What I would like to do but it looks like a stretch is to ORDER BY the results by the DEC value descending.
This is the query:
with Mth (st, nd) as (
select DATEADD (M, datediff (m, 0,'2012-09-01'), 0),
DATEADD (M, DATEDIFF (m, 0, '2012-09-01') + 1, 0)
union all
select DATEADD (m, 1, st),
DATEADD (m, 1, nd)
from Mth
where nd <= DATEADD (m, datediff (m, 0, getdate()), 0)
)
select *
from
(
select MONTH(Mth.st) Month,
U.USER,
COUNT(S.QRY_ID) Searches
FROM Mth
LEFT JOIN SEARCHES S
on Mth.st <= S.CREATED
and Mth.nd > S.CREATED
LEFT JOIN MEMBERS U
on U.AID = S.AID
GROUP BY YEAR(Mth.st), MONTH(Mth.st), U.HOLDER_LOGIN
) src
pivot
(
sum(searches)
for month in ([12],[11],[10])
) piv
Doing piv ORDER BY piv.Searches gives an error so is it possible to specify the column?
Try this:
with Mth (st, nd) as (
select DATEADD (M, datediff (m, 0,'2012-09-01'), 0),
DATEADD (M, DATEDIFF (m, 0, '2012-09-01') + 1, 0)
union all
select DATEADD (m, 1, st),
DATEADD (m, 1, nd)
from Mth
where nd <= DATEADD (m, datediff (m, 0, getdate()), 0)
), Pivoted
AS
(
select *
from
(
select MONTH(Mth.st) Month,
U.USER,
COUNT(S.QRY_ID) Searches
FROM Mth
LEFT JOIN SEARCHES S
on Mth.st <= S.CREATED
and Mth.nd > S.CREATED
LEFT JOIN MEMBERS U
on U.AID = S.AID
GROUP BY YEAR(Mth.st), MONTH(Mth.st), U.HOLDER_LOGIN
) src
pivot
(
sum(searches)
for month in ([12],[11],[10])
) piv
)
SELECT *
FROM Pivoted
ORDER BY Dec
Related
i need to transform this query result into rows instead of columns. Using Unpivot is possible, but I was not able to do this activity
see the code:
SELECT
cast(IIF(DATEPART(HOUR, [DATA]) <= 4, DATEADD(DAY, -1, [DATA]), [DATA]) as date) as Data,
IIF(DATEPART(HOUR, [DATA]) <= 4, DATEADD(DAY, -1, [DATA]), [DATA]) AS DataHora,
SUM([FraturaContusao]) AS 'FraturaContusao',
SUM([Salpingite]) AS 'Salpingite'
FROM
(
SELECT
[DATA], ROMANEIO,
IIF(( bAbaco.FRATURA_CONTUSAO - COALESCE(LAG(bAbaco.FRATURA_CONTUSAO) OVER (ORDER BY bAbaco.ID), 0)) > 0 , ( bAbaco.FRATURA_CONTUSAO - COALESCE(LAG(bAbaco.FRATURA_CONTUSAO) OVER ( ORDER BY bAbaco.ID), 0)), 0) AS 'FraturaContusao',
IIF(( bAbaco.Salpingite - COALESCE(LAG(bAbaco.Salpingite) OVER (ORDER BY bAbaco.ID), 0)) > 0 , ( bAbaco.Salpingite - COALESCE(LAG(bAbaco.Salpingite) OVER ( ORDER BY bAbaco.ID), 0)), 0) AS 'Salpingite'
FROM
ContProdUIA.ABACO_DIGITAL_L2 bAbaco
) as x
WHERE
CONVERT(varchar, x.[DATA], 23) >= DATEADD(DAY, -16, GETDATE())
GROUP BY
IIF(DATEPART(HOUR, [DATA]) <= 4, DATEADD(DAY, -1, [DATA]), [DATA])
this is the result of the query:
I need the columns 'FraturaContusao' and 'Salpingite' to be transformed with unpviot
something like:
Data| DataHora | Tipo| Qty
2020-06-23 | 2020-06-23 15:54 | FraturaContusao| 15
2020-06-23 | 2020-06-23 15:54 | Salpingite | 20
Perhaps the easiest is to use a CROSS APPLY
Example
Select A.Data
,A.DataHora
,B.Tipo
,B.Qty
From (
-- your orignal query here --
) A
Cross Apply ( values ('FraturaContusao',FraturaContusao)
,('Salpingite' ,Salpingite)
) B(Tipo,Qty)
What would be the SQL to calculate the number of days in each year if I had a start date and the number of days that have lapsed?
For example, the date (ymd) 2013-01-01 and the days lapsed is 1000.
I would like the result to look like this
2013 = 365
2014 = 365
2015 = 270
Can this be written as a function like datediff?
I have tried using a calendar table, but of course, linking to this just gives me 2013 = 1000
My calendar table looks like this.
DATE_ID | DATE | CALENDAR_YEAR | FINANCIAL_YEAR
-----------------------------------------------
20130101 | 2013-01-01 | 2013 | 2013/14
This is what i have tried.
SELECT
D.FISCAL_YEAR, SUM([DAYS]) AS NUMBER_OF_DAYS
FROM [dbo].[FACT] F
LEFT JOIN [dbo].[DIM_DATE] D ON D.DATE_ID = F.DATE_ID
GROUP BY
D.FISCAL_YEAR
The result for this is.
FISCAL_YEAR | NUMBER_OF_DAYS
----------------------------
2013/14 |2820
2014/15 |6635
2015/16 |2409
I would personally build a tally table to do this. Once you build that, you can easly get every date and count the number of days in each year:
DECLARE #YMD date = '20130101',
#Lapsed int = 1000;
--Build a Tally table
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3, N N4), --10,000 should be enough
--Build the dates table
Dates AS(
SELECT DATEADD(DAY, T.I, #YMD) AS CalendarDate
FROM Tally T
WHERE T.I <= #Lapsed - 1)
--And count the days
SELECT DATEPART(YEAR, CalendarDate) AS Year,
COUNT(CalendarDate) AS Days
FROM Dates D
GROUP BY DATEPART(YEAR, CalendarDate);
As a function:
CREATE FUNCTION CountDays (#YMD date, #Lapsed int)
RETURNS table
AS RETURN
--Build a Tally table
WITH N AS(
SELECT N
FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) N(N)),
Tally AS(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 AS I
FROM N N1, N N2, N N3, N N4), --10,000 should be enough
--Build the dates table
Dates AS(
SELECT DATEADD(DAY, T.I, #YMD) AS CalendarDate
FROM Tally T
WHERE T.I <= #Lapsed - 1)
--And count the days
SELECT DATEPART(YEAR, CalendarDate) AS Year,
COUNT(CalendarDate) AS Days
FROM Dates D
GROUP BY DATEPART(YEAR, CalendarDate);
GO
SELECT *
FROM (VALUES('20130101',1000),
('20150501',755))V(YMD, Lapsed)
CROSS APPLY dbo.CountDays(V.YMD,V.Lapsed) CD;
One method is a recursive CTE:
with dates as (
select v.d, 1000 - datediff(day, v.d, dateadd(year, 1, v.d)) as days
from (values (datefromparts(2013, 1, 1))) v(d)
union all
select dateadd(year, 1, d), days - datediff(day, d, dateadd(year, 1, d))
from dates
where days > 0
)
select d,
(case when days > 0 then datediff(day, d, dateadd(year, 1, d))
else datediff(day, d, dateadd(year, 1, d)) + days
end)
from dates;
Here is a db<>fiddle.
Pnum Fdate description
==== ========== ===========
1024 2018-02-17 A
1024 2018-05-17 B
1024 2018-05-17 C
1024 2018-09-17 D
MY table PW have fields looks like this.
--> I want to show the result as
**Month Name Description**
January -
February A
March -
April -
May B
June -
July -
August C
September D
October -
November -
December -
Please help me how to achive this.
Join with a list of month names, there is only twelve of them:
SELECT monthname, description
FROM (VALUES
(1, 'January'),
(2, 'February'),
(3, 'March'),
(4, 'April'),
(5, 'May'),
(6, 'June'),
(7, 'July'),
(8, 'August'),
(9, 'September'),
(10, 'October'),
(11, 'November'),
(12, 'December')
) AS va(monthnumber, monthname)
LEFT JOIN yourdata ON DATEPART(MONTH, fdate) = va.monthnumber
ORDER BY monthnumber
Try this
;WITH CTE(Pnum, Fdate,description)
AS
(
SELect 1024,'2018-02-17','A' union all
SELect 1024,'2018-05-17','B' union all
SELect 1024,'2018-08-17','C' union all
SELect 1024,'2018-09-17','D'
)
SELECT MonthNames,ISNULL([Description],'-') AS [Description]
FROM CTE RIGHT JOIN
(
SELECT DATENAME(MONTH,DATEADD(MONTH,number-datepart(month,GETDATE()),GETDATE())) as MonthNames
FROM MASTER.DBO.spt_values
WHERE TYPE ='P'
AND number BETWEEN 1 AND 12
) dt
ON dt.MonthNames=DATENAME(MONTH,Fdate)
Result
MonthNames Description
--------------------------
January -
February A
March -
April -
May B
June -
July -
August C
September D
October -
November -
December -
You can try below
DEMO
with cte1 as (
select cast('2018-01-01' as date) dt
union all
select dateadd(month, 1, dt)
from cte1
where dateadd(month, 1, dt) < cast('2018-12-31' as date)
)
select DateName(month,dt),coalesce(Description,'-') as Description from cte1 a left join yourtable b
on month(a.dt)=month(b.Fdate)
This solution will allow an index on Fdate to be used (MONTH(column) will force a scan every time).
DECLARE #year int = 2018;
;WITH m AS
(
SELECT m = 1 UNION ALL SELECT m + 1 FROM m WHERE m < 12
),
months(b,e) AS
(
SELECT b = DATEFROMPARTS(#year, m, 1)
FROM m
)
SELECT DATENAME(MONTH, m.b), PW.Description
FROM months AS m
LEFT OUTER JOIN dbo.PW
ON PW.Fdate >= m.b AND PW.Fdate < DATEADD(MONTH, 1, m.b)
ORDER BY m.b;
Try the following query:
SELECT MONTHNAME(fdate), description FROM table
For more reference go through
https://dev.mysql.com/doc/refman/8.0/en/date-and-time-functions.html#function_month
I have a table like this,
mytable
date | value
2018.09.12 | 1
2018.09.11 | 2
2018.09.10 | 3
I need a query to return sum(value) for the last six weeks. Exactly like this.
week# | value
37 | 6
36 | 0
35 | 0
34 | 8
33 | 9
32 | 10
31 | 11
I have a query to return sumvalue for each week.
SELECT Sum(Value) AS Sumvalue, DATEPART(wk, date) AS [weekNo]
FROM mytable
WHERE Date BETWEEN DATEADD(DAY, -42, GETDATE()) AND GETDATE()
GROUP BY DATEPART(wk, date)
But this can't handle zero values for a week.
How can write a pivoted query to obtain the format?
My try;
SELECT *
FROM (
SELECT Value, DATEPART(wk, date) AS [weekNo]
FROM mytable
WHERE Date BETWEEN DATEADD(DAY, -42, GETDATE()) AND GETDATE()
) As sourcetable
PIVOT
(
Sum(Value) for DATEPART(wk, date) IN (SELECT date FROM mytable where date between
DATEADD(DAY, -42, GETDATE()) and GETDATE())
) AS pivotable
I am getting the syntax error near for keyword. How can I put the six weeks in pivot statemet
Found a partial solution!
SELECT *
FROM (
SELECT Value, DATEPART(wk, date) AS [weekNo]
FROM mytable
WHERE Date BETWEEN DATEADD(DAY, -42, GETDATE()) AND GETDATE()
) As sourcetable
PIVOT
(
Sum(Value) for [week] IN ([1], [2], [3], ... ,[54])
) AS pivotable
It is partial since it is kind of hardcoding the for statement and cannot control the unnecessary weeks in the query.
Good morning, I'm trying to draw a dynamic table with some data, this query, draw a table that has a day, his week, and some data that I want to calculate dynamically.
This is my query
use Alfri
;with monthDates
as
(
select DATEADD(month, 0, CONVERT(DATE,'2013-09-09',102)) as d
,DATEPART(week, DATEADD(month, datediff(month, 0, '2013-09-09'),0)) as w,
(
SELECT SUM(
CASE WHEN arrive_yard IS NOT NULL THEN
DATEDIFF(mi, Solicitado, Libre)-DATEDIFF(mi, arrive_yard, leave_yard)
ELSE
DATEDIFF(mi, Solicitado, Libre)
END
) as Tiempo
FROM MovimientoHoras
WHERE CONVERT(DATE, Solicitado, 102) = '2013-10-11'
) as info
union all
select DATEADD(day, 1, d)
,DATEPART(week, DATEADD(day, 1, d))
, info
from monthDates
where d < DATEADD(month, datediff(month, 0, '2013-10-09')+1,-1)
)
SELECT * FROM monthDates
This query draw me a table like this.
d |w |info |
2013-09-09 | 36 | 2780|
2013-09-10 | 37 | 2780|
2013-09-11 | 37 | 2780|
2013-09-12 | 37 | 2780|
2013-09-13 | 37 | 2780|
2013-09-14 | 37 | 2780|
2013-09-15 | 37 | 2780|
2013-09-16 | 37 | 2780|
But the info's column isn't calculling dynamically and this is my dilenma.
The point is that column d is calculated dynamically and that's the value that I want to use in info's column query, something like this WHERE CONVERT(DATE, Solicitado, 102) = d) as info instead of WHERE CONVERT(DATE, Solicitado, 102) = '2013-10-11') as info where D is the date changing in every row, the way that I'm trying it just giving me same data of '2013-10-11'
Something like a While to change a day in that subquery
Thanks
The basic approach is to separate the part that generates dates from the part that calculates the info for that date:
;with monthDates as (
select
cast('20130909' as date) as d,
datepart(week, dateadd(month, datediff(month, 0, '2013-09-09'), 0)) as w
union all
select
dateadd(day, 1, d),
datepart(week, dateadd(day, 1, d))
from
monthDates
where
d < dateadd(month, datediff(month, 0, '2013-10-09') + 1, -1)
)
select
m.d,
m.w,
sum(
datediff(mi, Solicitado, Libre)
- case when arrive_yard is not null then
datediff(mi, arrive_yard, leave_yard)
else 0 end
) info
from
monthDates m
left outer join
MovimientoHoras h
on cast(Solicitado as date) = m.d
group by
m.d,
m.w
Example SQLFiddle