Sum the MDX Query - sum

I got a MDX Query working which gets me the measure of some countries, on a date range.
But if I set the Date range to more then 1 day, i get every countries value for every day (in the range).
But I want to sum the measures for every country accross the date range.
Thanks in advance. Didnt find a excisting thread ;)
The Query (some parts are crossed-out due to intern data), marked as '???':
WITH
SET [*NATIVE_CJ_SET] AS
'FILTER(
NONEMPTYCROSSJOIN(
[*BASE_MEMBERS__Site.Site Hierarchy_]
,NONEMPTYCROSSJOIN(
[*BASE_MEMBERS__Time.GA Date Hierarchy_]
,[*BASE_MEMBERS__Country.Country Hierarchy_]
)
)
, NOT ISEMPTY ([Measures].[???])
)'
SET [*BASE_MEMBERS__Country.Country Hierarchy_] AS
'{
[Country.Country Hierarchy].[Austria]
,[Country.Country Hierarchy].[Germany]
,[Country.Country Hierarchy].[India]
,[Country.Country Hierarchy].[Switzerland]
,[Country.Country Hierarchy].[United States]
}'
SET [*NATIVE_MEMBERS__Site.Site Hierarchy_] AS
'GENERATE(
[*NATIVE_CJ_SET]
,{[Site.Site Hierarchy].CURRENTMEMBER}
)'
SET [*SORTED_COL_AXIS] AS
'ORDER(
[*CJ_COL_AXIS]
,[Site.Site Hierarchy].CURRENTMEMBER.ORDERKEY,BASC
)'
SET [*BASE_MEMBERS__Measures_] AS
'{[Measures].[???]}'
SET [*BASE_MEMBERS__Site.Site Hierarchy_] AS
'{[Site.Site Hierarchy].[???]}'
SET [*BASE_MEMBERS__Time.GA Date Hierarchy_] AS
'{
[Time.GA Date Hierarchy].[2016].[8].[1]
: [Time.GA Date Hierarchy].[2016].[8].[11]
}'
SET [*CJ_ROW_AXIS] AS
'GENERATE(
[*NATIVE_CJ_SET]
, {([Time.GA Date Hierarchy].CURRENTMEMBER
,[Country.Country Hierarchy].CURRENTMEMBER)}
)'
SET [*SORTED_ROW_AXIS] AS
'ORDER(
[*CJ_ROW_AXIS]
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Year]).ORDERKEY
,BASC
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Month]).ORDERKEY
,BASC
,[Time.GA Date Hierarchy].CURRENTMEMBER.ORDERKEY
,BASC
,[Measures].[*SORTED_MEASURE]
,BASC)'
SET [*CJ_COL_AXIS] AS
'GENERATE(
[*NATIVE_CJ_SET]
, {([Site.Site Hierarchy].CURRENTMEMBER)}
)'
MEMBER [Measures].[*SORTED_MEASURE] AS '([Measures].[???],[Site.Site Hierarchy].[*TOTAL_MEMBER_SEL~SUM])', SOLVE_ORDER=400
MEMBER [Site.Site Hierarchy].[*TOTAL_MEMBER_SEL~SUM] AS 'SUM([*NATIVE_MEMBERS__Site.Site Hierarchy_])', SOLVE_ORDER=98
SELECT
CROSSJOIN([*SORTED_COL_AXIS],[*BASE_MEMBERS__Measures_]) ON COLUMNS
,[*SORTED_ROW_AXIS] ON ROWS
FROM [???]
This is the Output:
http://image.prntscr.com/image/ab236e90880a4d8b969fdd182a05ccdb.png
But I want it like that:
Germany 901
Austria 67
etc.

I've reformatted your code to try make it a little more readable - this part of your code does not look correct:
SET [*SORTED_ROW_AXIS] AS
'ORDER(
[*CJ_ROW_AXIS]
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Year]).ORDERKEY
,BASC
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Month]).ORDERKEY
,BASC
,[Time.GA Date Hierarchy].CURRENTMEMBER.ORDERKEY
,BASC
,[Measures].[*SORTED_MEASURE]
,BASC)'
Attempting to simplify your whole script I've got the following - I'll come back to this as it won't solve your problem but I just want to try to understand what is going on:
WITH
SET [*NATIVE_CJ_SET] AS
NONEMPTY(
[Site.Site Hierarchy].[???]
* [Time.GA Date Hierarchy].[2016].[8].[1] : [Time.GA Date Hierarchy].[2016].[8].[11]
* {
[Country.Country Hierarchy].[Austria]
,[Country.Country Hierarchy].[Germany]
,[Country.Country Hierarchy].[India]
,[Country.Country Hierarchy].[Switzerland]
,[Country.Country Hierarchy].[United States]
}
,[Measures].[???])
)
SET [*CJ_COL_AXIS] AS
GENERATE(
[*NATIVE_CJ_SET]
,{([Site.Site Hierarchy].CURRENTMEMBER)}
)
SET [*NATIVE_MEMBERS__Site.Site Hierarchy_] AS
GENERATE(
[*NATIVE_CJ_SET]
,{[Site.Site Hierarchy].CURRENTMEMBER}
)
SET [*SORTED_COL_AXIS] AS
ORDER(
[*CJ_COL_AXIS]
,[Site.Site Hierarchy].CURRENTMEMBER.ORDERKEY
,BASC
)
SET [*CJ_ROW_AXIS] AS
GENERATE(
[*NATIVE_CJ_SET]
,(
[Time.GA Date Hierarchy].CURRENTMEMBER
,[Country.Country Hierarchy].CURRENTMEMBER
)
)
MEMBER [Site.Site Hierarchy].[*TOTAL_MEMBER_SEL~SUM] AS
SUM(
[*NATIVE_MEMBERS__Site.Site Hierarchy_]
)
, SOLVE_ORDER=98
MEMBER [Measures].[*SORTED_MEASURE] AS
(
[Measures].[???]
,[Site.Site Hierarchy].[*TOTAL_MEMBER_SEL~SUM]
)
, SOLVE_ORDER=400
SET [*SORTED_ROW_AXIS] AS
ORDER(
[*CJ_ROW_AXIS]
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Year]).ORDERKEY
,BASC
,ANCESTOR(
[Time.GA Date Hierarchy].CURRENTMEMBER
, [Time.GA Date Hierarchy].[Month]).ORDERKEY
,BASC
,[Time.GA Date Hierarchy].CURRENTMEMBER.ORDERKEY
,BASC
,[Measures].[*SORTED_MEASURE]
,BASC)
SELECT
[*SORTED_COL_AXIS] * [Measures].[???] ON 0
,[*SORTED_ROW_AXIS] ON 1
FROM [???];

Ok, I figured it out.
Wrote my own MDX which is much better:
SELECT CrossJoin([Site.Site Hierarchy].[???], {[Measures].[???]}) ON COLUMNS,
Order({[Country.Country Hierarchy].[Austria],[Country.Country Hierarchy].[Germany],[Country.Country Hierarchy].[India],[Country.Country Hierarchy].[Switzerland],[Country.Country Hierarchy].[United States]}, Measures.[sessions], BASC) ON ROWS
FROM [???]
WHERE {[Time.GA Date Hierarchy].[2016].[8].[1] : [Time.GA Date Hierarchy].[2016].[8].[17]}
But the Order does not work correctly. Whats the Problem?
Result: http://www2.pic-upload.de/img/31482391/Screenshot_1.png

Related

SQL- Grouping and counting # of days w/o overlapping days

I am trying to group a total count of days within a month that a patient had a catheter line inserted. The data is broken down into stints so is not contiguous throughout the month. I also do not to count overlapping days between the stints. See screenshot and query below.
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = '2/1/2022'
SET #end_date = '2/28/2022';
CREATE TABLE mytable(
Patient_ID INTEGER NOT NULL PRIMARY KEY
,startdate DATE NOT NULL
,enddate DATE NOT NULL
,Type_of_Line VARCHAR(4) NOT NULL
,Insertion_Date DATE NOT NULL
,Removal_Date DATE
,_of_Cath_Days INTEGER NOT NULL
);
INSERT INTO mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-01-16','2022-02-11','Port','2021-08-03 00:00:00.000',NULL,11);
INSERT INTO mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-11','2022-02-15','Port','2021-08-03 00:00:00.000',NULL,5);
INSERT INTO mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-15','2022-02-24','Port','2021-08-03 00:00:00.000',NULL,10);
INSERT INTO mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-24','2022-03-23','Port','2021-08-03 00:00:00.000',NULL,5);
WITH stat
AS (SELECT pt.ptkey,
ptid,
ptptinfusionstatus.startdate,
ptptinfusionstatus.enddate
FROM pt
LEFT JOIN ptptinfusionstatus
ON ptptinfusionstatus.ptkey = pt.ptkey
LEFT JOIN ptinfusionstatus
ON ptinfusionstatus.ptinfusionstatuskey =
ptptinfusionstatus.ptinfusionstatuskey
WHERE ptptinfusionstatus.ptinfusionstatuskey IN ( 1, 5 )),
access1
AS (SELECT d.NAME,
d.pharmacyeventandoutcometypedetailkey,
T.pharmacyeventandoutcometypekey
FROM pharmacyeventandoutcometypedetail d WITH (nolock)
LEFT JOIN pharmacyeventandoutcometype t WITH (nolock)
ON t.pharmacyeventandoutcometypekey =
d.pharmacyeventandoutcometypekey
LEFT JOIN pharmacyeventandoutcomelist l WITH (nolock)
ON l.pharmacyeventandoutcomelistkey =
t.pharmacyeventandoutcomelistkey
WHERE l.pharmacyeventandoutcomelistkey = 2),
access2
AS (SELECT stat.ptkey,
stat.ptid,
stat.startdate,
stat.enddate,
Isnull(devicetype.NAME, '') [Access Device_Type],
ppad.insertiondate [Access Device_Insertion Date],
ppad.removaldate [Access Device_Removal Date]
FROM stat WITH (nolock)
JOIN pharmacyptaccessdevice ppad WITH(nolock)
ON ppad.ptkey = stat.ptkey
LEFT JOIN access1 devicetype WITH (nolock)
ON devicetype.pharmacyeventandoutcometypedetailkey =
ppad.accessdevicetypekey
AND devicetype.pharmacyeventandoutcometypekey = 4)
--***MAIN QUERY***
SELECT access2.[ptid] AS 'Patient ID',
access2.startdate,
access2.enddate,
access2.[access device_type] AS 'Type of Line',
access2.[access device_insertion date] AS 'Insertion Date',
access2.[access device_removal date] AS 'Removal Date',
Datediff(d, CASE WHEN [access device_insertion date] >= #start_date AND
[access device_insertion date] >=access2.startdate THEN
access2.[access device_insertion date] WHEN access2.startdate >=
access2.[access device_insertion date] AND
access2.startdate >= #start_date THEN access2.startdate ELSE #start_date
END,
CASE WHEN #end_date <= Isnull(access2.enddate, #end_date) AND #end_date
<= Isnull(access2.[access device_removal date], #end_date) THEN #end_date
WHEN access2.enddate IS NOT NULL AND access2.enddate < #end_date AND
access2.enddate <= Isnull(access2.[access device_removal date],
access2.enddate) THEN access2.enddate ELSE
access2.[access device_removal date] END) + 1 AS '# of Cath Days'
FROM access2
WHERE access2.startdate <= #end_date
AND ( access2.enddate >= #start_date
OR access2.enddate IS NULL )
AND access2.[access device_insertion date] <= #end_date
AND ( access2.[access device_removal date] >= #start_date
OR access2.[access device_removal date] IS NULL )
AND access2.ptid = '10247'
I tried grouping by patient and adding a sum of days at the patient group level in SQL Reporting Services, but could not get around the overlapping days so the counts are all wrong.
Based on the data provided, below is an example code that will group based on patientId and if start date equals end date then it will subtract 1 from number of days.
DECLARE #start_date DATETIME
DECLARE #end_date DATETIME
SET #start_date = '2/1/2022'
SET #end_date = '2/28/2022';
declare #mytable table(
Patient_ID INTEGER NOT NULL -- PRIMARY KEY
,startdate DATE NOT NULL
,enddate DATE NOT NULL
,Type_of_Line VARCHAR(4) NOT NULL
,Insertion_Date DATE NOT NULL
,Removal_Date DATE
,_of_Cath_Days INTEGER NOT NULL
);
INSERT INTO #mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-01-16','2022-02-11','Port','2021-08-03 00:00:00.000',NULL,11);
INSERT INTO #mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-11','2022-02-15','Port','2021-08-03 00:00:00.000',NULL,5);
INSERT INTO #mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-15','2022-02-24','Port','2021-08-03 00:00:00.000',NULL,10);
INSERT INTO #mytable(Patient_ID,startdate,enddate,Type_of_Line,Insertion_Date,Removal_Date,_of_Cath_Days) VALUES (10247,'2022-02-24','2022-03-23','Port','2021-08-03 00:00:00.000',NULL,5);
select
Patient_ID
, startdate
, enddate
, Type_of_Line
, Insertion_Date
, Removal_Date
, LAG([enddate]) OVER (ORDER BY [startdate]) as compareenddate
from #mytable
select Patient_ID
, min(startdate) as startdate
, max(enddate) as enddate
, max(Type_of_Line) as Type_of_Line
, min(Insertion_Date) as Insertion_Date
, max(Removal_Date) as Removal_Date
, sum(iif(startdate = isnull(compareenddate, '1900-01-01'), _of_Cath_Days - 1, _of_Cath_Days) )
from
(
select
Patient_ID
, startdate
, enddate
, Type_of_Line
, Insertion_Date
, Removal_Date
, _of_Cath_Days
, LAG([enddate]) OVER (ORDER BY [startdate]) as compareenddate
from #mytable
) x
group by Patient_ID
Query result

MDX : ParallelPeriod and leap year

I have data for several years.
I have a problem with February this year when I try to get last year.
I think it's because 2020 is a leap year. But I have no clue how to solve this. I tried a lot of things.
My request is like that :
IIF
(
Iserror
(
Sum
(
YTD
(
ParallelPeriod
(
[Date Facture].[Mensuel].[Année]
,1
,StrToMember
("[Date Facture].[Mensuel].[Date].&["
+
Tail
(
(EXISTING
Descendants
(
[Date Facture].[Mensuel].CurrentMember,
,leaves
))
).Item(0).Member_Key
+ "]"
)
)
)
,[Measures].[Quantité Facturée AEC]
)
)
,null
,Sum
(
YTD
(
ParallelPeriod
(
[Date Facture].[Mensuel].[Année]
,1
,StrToMember
("[Date Facture].[Mensuel].[Date].&["
+
Tail
(
(EXISTING
Descendants
(
[Date Facture].[Mensuel].CurrentMember,
,leaves
))
).Item(0).Member_Key
+ "]"
)
)
)
,[Measures].[Quantité Facturée AEC]
)
)
What can I do to solve this?
Can you not just simplify to use the CURRENTMEMBER function?
IIF
(
Iserror
(
Sum
(
YTD
(
ParallelPeriod
(
[Date Facture].[Mensuel].[Année]
,1
,[Date Facture].[Mensuel].CURRENTMEMBER
)
)
,[Measures].[Quantité Facturée AEC]
)
)
,null
,Sum
(
YTD
(
ParallelPeriod
(
[Date Facture].[Mensuel].[Année]
,1
,[Date Facture].[Mensuel].CURRENTMEMBER
)
)
,[Measures].[Quantité Facturée AEC]
)
)

Pivot query will only return data from the 'FromDate' and not between two dates

I have a query as follows:
DECLARE #_DateFrom DATETIME
DECLARE #_DateTo DATETIME
DECLARE #_SerialNumber NVARCHAR(MAX)
SET #_DateFrom = '2018-10-20 00:00:00'
SET #_DateTo = '2018-10-21 00:00:00'
SET #_SerialNumber = '2209'
SELECT [Serial],
[Channel],
[ReadingDate],
[00:15],[00:30],[00:45],[01:00],[01:15],[01:30],[01:45],[02:00],[02:15],[02:30],[02:45],[03:00],
[03:15],[03:30],[03:45],[04:00],[04:15],[04:30],[04:45],[05:00],[05:15],[05:30],[05:45],[06:00],
[06:15],[06:30],[06:45],[07:00],[07:15],[07:30],[07:45],[08:00],[08:15],[08:30],[08:45],[09:00],
[09:15],[09:30],[09:45],[10:00],[10:15],[10:30],[10:45],[11:00],[11:15],[11:30],[11:45],[12:00],
[12:15],[12:30],[12:45],[13:00],[13:15],[13:30],[13:45],[14:00],[14:15],[14:30],[14:45],[15:00],
[15:15],[15:30],[15:45],[16:00],[16:15],[16:30],[16:45],[17:00],[17:15],[17:30],[17:45],[18:00],
[18:15],[18:30],[18:45],[19:00],[19:15],[19:30],[19:45],[20:00],[20:15],[20:30],[20:45],[21:00],
[21:15],[21:30],[21:45],[22:00],[22:15],[22:30],[22:45],[23:00],[23:15],[23:30],[23:45],[00:00]
FROM(
SELECT
SerialNumber AS [Serial],
ChannelName AS [Channel],
(CASE WHEN
CAST(ReadingDate AS DATE) > CAST(#_DateFrom AS DATE)
THEN CAST(#_DateFrom AS DATE)
ELSE CAST(ReadingDate AS DATE)
END) AS [ReadingDate],
CAST(ReadingDate AS TIME) AS [ReadingTime],
ChannelValue AS [Value]
FROM [UriData]
WHERE ReadingDate BETWEEN #_DateFrom AND #_DateTo
AND SerialNumber = #_SerialNumber
AND ChannelName IN (SELECT ChannelName FROM [Staging].[ActiveChannels])
) AS [Raw]
PIVOT
(
MAX( [Value] ) FOR [ReadingTime] IN( [00:15],[00:30],[00:45],[01:00],[01:15],[01:30],[01:45],[02:00],
[02:15],[02:30],[02:45],[03:00],[03:15],[03:30],[03:45],[04:00],
[04:15],[04:30],[04:45],[05:00],[05:15],[05:30],[05:45],[06:00],
[06:15],[06:30],[06:45],[07:00],[07:15],[07:30],[07:45],[08:00],
[08:15],[08:30],[08:45],[09:00],[09:15],[09:30],[09:45],[10:00],
[10:15],[10:30],[10:45],[11:00],[11:15],[11:30],[11:45],[12:00],
[12:15],[12:30],[12:45],[13:00],[13:15],[13:30],[13:45],[14:00],
[14:15],[14:30],[14:45],[15:00],[15:15],[15:30],[15:45],[16:00],
[16:15],[16:30],[16:45],[17:00],[17:15],[17:30],[17:45],[18:00],
[18:15],[18:30],[18:45],[19:00],[19:15],[19:30],[19:45],[20:00],
[20:15],[20:30],[20:45],[21:00],[21:15],[21:30],[21:45],[22:00],
[22:15],[22:30],[22:45],[23:00],[23:15],[23:30],[23:45],[00:00])
) AS pvt
ORDER BY ReadingDate DESC, Channel, [Serial]
The query only returns data for the #_DateFrom variable and will not return any other data beyond that i.e between two dates, so the above query will only return data for '2018-10-20 00:00:00'. I have tried adding it on SQL Fiddle but the site doesn't seem to be working again. I have a feeling it is the case statement that is causing it, but I am struggling to rectify it.
So I have a Dropbox link that has the query, the data used and the expected output https://www.dropbox.com/sh/odtn35jo6sjhqde/AAChn5Fw7OgrCIyI70XiJ-msa?dl=0
Based on this logic:
(CASE WHEN
CAST(ReadingDate AS DATE) > CAST(#_DateFrom AS DATE)
THEN CAST(#_DateFrom AS DATE)
ELSE CAST(ReadingDate AS DATE)
END) AS [ReadingDate],
If ReadingDate is ever larger than #_DateFrom, then it is set to #_DateFrom. That would seem to be the culprit.
I'm gussing that ReadingDate is a DATETIME column. if true. Then, your issue is in this line :
SET #_DateFrom = '2018-10-20 00:00:00'
SET #_DateTo = '2018-10-21 00:00:00'
you're starting from the beginning of 2018-10-20 12AM O'Clock , and ending at 2018-10-21 at midnight (this is a 24 hours). if you want to include the 2018-10-21 in your results, you must do something like this :
SET #_DateFrom = '2018-10-20 00:00:00'
SET #_DateTo = '2018-10-21 23:59:59'
So, you start at 2018-10-20 12AM O'Clock, and end at 2018-10-21 23:59:59 PM (Which is closer to 12AM O'Clock). (This is 48 hours, more or less).
This will include both dates records.
declare #_SerialNumber NVARCHAR(MAX) = '2209'
DECLARE #_DateFrom DATETIME
DECLARE #_DateTo DATETIME
SET #_DateFrom = '2018-10-01 00:15:00'
SET #_DateTo = '2018-10-28 00:15:00'
SELECT [Serial],
[Channel],
[ReadingDate],
[00:15],[00:30],[00:45],[01:00],[01:15],[01:30],[01:45],[02:00],[02:15],[02:30],[02:45],[03:00],
[03:15],[03:30],[03:45],[04:00],[04:15],[04:30],[04:45],[05:00],[05:15],[05:30],[05:45],[06:00],
[06:15],[06:30],[06:45],[07:00],[07:15],[07:30],[07:45],[08:00],[08:15],[08:30],[08:45],[09:00],
[09:15],[09:30],[09:45],[10:00],[10:15],[10:30],[10:45],[11:00],[11:15],[11:30],[11:45],[12:00],
[12:15],[12:30],[12:45],[13:00],[13:15],[13:30],[13:45],[14:00],[14:15],[14:30],[14:45],[15:00],
[15:15],[15:30],[15:45],[16:00],[16:15],[16:30],[16:45],[17:00],[17:15],[17:30],[17:45],[18:00],
[18:15],[18:30],[18:45],[19:00],[19:15],[19:30],[19:45],[20:00],[20:15],[20:30],[20:45],[21:00],
[21:15],[21:30],[21:45],[22:00],[22:15],[22:30],[22:45],[23:00],[23:15],[23:30],[23:45],[00:00]
FROM(
SELECT
SerialNumber AS [Serial],
ChannelName AS [Channel],
(CASE WHEN
CAST(ReadingDate AS TIME) = '00:00:00'
THEN CAST(DATEADD(DAY, -1, ReadingDate) AS DATE)
ELSE CAST(ReadingDate AS DATE)
END) AS [ReadingDate],
CAST(ReadingDate AS TIME) AS [ReadingTime],
ChannelValue AS [Value]
FROM [Staging].[UriData]
WHERE ReadingDate BETWEEN #_DateFrom AND #_DateTo
AND SerialNumber = #_SerialNumber
and ChannelName = 'v1'
) AS [Raw]
PIVOT
(
MAX( [Value] ) FOR [ReadingTime] IN([00:15],[00:30],[00:45],[01:00],[01:15],[01:30],[01:45],[02:00],
[02:15],[02:30],[02:45],[03:00],[03:15],[03:30],[03:45],[04:00],
[04:15],[04:30],[04:45],[05:00],[05:15],[05:30],[05:45],[06:00],
[06:15],[06:30],[06:45],[07:00],[07:15],[07:30],[07:45],[08:00],
[08:15],[08:30],[08:45],[09:00],[09:15],[09:30],[09:45],[10:00],
[10:15],[10:30],[10:45],[11:00],[11:15],[11:30],[11:45],[12:00],
[12:15],[12:30],[12:45],[13:00],[13:15],[13:30],[13:45],[14:00],
[14:15],[14:30],[14:45],[15:00],[15:15],[15:30],[15:45],[16:00],
[16:15],[16:30],[16:45],[17:00],[17:15],[17:30],[17:45],[18:00],
[18:15],[18:30],[18:45],[19:00],[19:15],[19:30],[19:45],[20:00],
[20:15],[20:30],[20:45],[21:00],[21:15],[21:30],[21:45],[22:00],
[22:15],[22:30],[22:45],[23:00],[23:15],[23:30],[23:45],[00:00])
) AS pvt
ORDER BY ReadingDate DESC, Channel, [Serial]

Get database records which satisfy two date ranges and within a specific timing in SQL server

I have following [RestaurantOffer] table.
Offers, which is valid only within two date ranges (i.e FromDate and ToDate) and at a particular timing(FromTime,ToTime).
So I want to write a query which would give me all Offers on current date(Today) and the time will be more than current Time(Today's Current Time). Because I don't want to get the expired Offers.
Database :
FromDate(date),
ToDate(date),
FromTime(time),
ToTime(time)
UPDATE :
**Note :**This Offers is not valid all 24 hours.. It is valid only FromTime-ToTime Range.
What I want :
1st: Give me All today's records if today satisfies FromDate and Todate
range.
2nd : After getting all the records for today , I want to get all the records which if more than or equal today's Current Time.
Try following query:
SELECT * FROM RestaurantOffer WHERE (GETDATE() >= FromDate AND GETDATE() <= ToDate) AND (cast(GETDATE() as datetime) >= FromTime AND cast(GETDATE() as datetime) <= ToTime);
Try this:
--DROP TABLE #temp
CREATE TABLE #temp
(
FROMDate DATE
, ToDate DATE
, FromTime TIME
, ToTime TIME
);
INSERT INTO #temp
( FROMDate, ToDate, FromTime, ToTime )
VALUES ( '2016-05-01' -- FROMDate - date
, '2016-06-01' -- ToDate - date
, '11:30:00:000' -- FromTime - time
, '17:30:00:000' -- ToTime - time
),
( '2016-05-01' -- FROMDate - date
, '2016-06-01' -- ToDate - date
, '11:30:00:000' -- FromTime - time
, '17:30:00:000' -- ToTime - time
),
( '2016-05-01' -- FROMDate - date
, '2016-06-01' -- ToDate - date
, '11:30:00:000' -- FromTime - time
, '17:30:00:000' -- ToTime - time
),
( '2016-05-01' -- FROMDate - date
, '2016-06-01' -- ToDate - date
, '11:30:00:000' -- FromTime - time
, '19:30:00:000' -- ToTime - time
);
SELECT FROMDate
, ToDate
, FromTime
, ToTime
FROM #temp
WHERE ( CAST(GETDATE() AS DATE) >= FROMDate
AND CAST(GETDATE() AS DATE) <= ToDate
)
AND ( CAST(GETDATE() AS TIME) >= FromTime
AND CAST(GETDATE() AS TIME) <= ToTime
);
you can add a date and time field together to get a datetime if you cast them to datetime first.
So
SELECT *
FROM RestaurantOffer
WHERE Getdate() Between
cast(FromDate as datetime) + cast(FromTime as datetime)
and cast(ToDate as datetime)+cast(ToTime as datetime)

Find dates that are not on the first or last day of the month

I have a table named Locations that has column named effective_date with many dates from many years, and I want to retrieve only those that are not on the first day of the month or the last day of that month.
Here is a SQL Fiddle Demo with the detail below.
Generate a table and some sample test data:
CREATE TABLE Locations(
effective_date DATETIME
)
INSERT INTO Locations
VALUES('2014-01-01') -- First day so we would expect this NOT to be returned
INSERT INTO Locations
VALUES('2014-01-02') -- This should be returned
INSERT INTO Locations
VALUES('2014-01-31') -- Last day of January so this should NOT be returned
Then the query below works out the last day of the month for each date in the table, records are only returned is if the effective_date is not the first or last day of the month as calculated.
SELECT effective_date FROM Locations
WHERE -- not the first day (the easy bit!)
DATEPART(day, effective_date) <> 1
-- not the last day (slightly more complex)
AND DATEPART(day, effective_date) <>
DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,effective_date)+1,0)))
When executed only January, 02 2014 00:00:00+0000 is returned as expected.
The clever bit here is the function to calculate the last day of the current month when given a date, lets examine that and break it down:
DECLARE #sampleDate DATETIME
SET #sampleDate = '2014-01-02'
-- Calculate the number of months between '1900-01-01' and the #sampleDate
-- +1 as we want to shift into the following month so we can work back:
SELECT DATEDIFF(month,0,#sampleDate) + 1
-- Result --> 1369
-- Create a new date by adding the result of the previous step in
-- months to '1900-01-01'
SELECT DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0)
-- Result --> '2014-02-01' (giving first day of the following month)
-- Subtract one second from this
SELECT DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0))
-- Result --> '2014-01-31 23:59:59' (giving the very end of the original month)
-- Finally extract the day of the month
SELECT DATEPART(day, DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,#sampleDate)+1,0)))
-- Result --> 31
If your effective_date columns is of type date, then this SQL query will return all rows with a non-null effective_date value that is other than the 1st or last day of the month:
select t.effective_date , count(*)
from dbo.foo t
where 1 = 1 -- just for clarity
-- after the 1st day of the month
and t.effective_date > dateadd(day ,
1-day( t.effective_date ) ,
t.effective_date
)
-- and prior to the last day of the month
and t.effective_date < dateadd( day ,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
If your column carries a time component with it, that is, any of:
datetime
smalldatetime
datetime2
datetimeoffset
You'll want to cover your bases and modify the query, something like
select *
from dbo.foo t
where 1=1 -- added for clarity
-- effective date on or after the 2nd of the month
and t.effective_date >= convert(date,
dateadd(day ,
2-day( t.effective_date ) ,
t.effective_date
)
)
-- and prior to the last day of the month
and t.effective_date < convert(date,
dateadd(day,
-day( dateadd(month,1,t.effective_date) ) ,
dateadd(month,1,t.effective_date)
)
)
The first day of the month will always be 1.
You should be able to adapt this to find the last day of the current month:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
Source: http://blog.sqlauthority.com/2007/08/18/sql-server-find-last-day-of-any-month-current-previous-next/
T-SQL to display dates in a month for only first & last day. Also display dates in month excluding first & last day.
declare #EndOfMonth as DateTime
set #EndOfMonth = ( SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0)) )
select #EndOfMonth as EndOfMonths
declare #EndOfMonthMinus1 as DateTime
set #EndOfMonthMinus1 = (SELECT DATEAdd(DAY, -1, #EndOfMonth) )
select #EndOfMonthMinus1 as EndOfMonths
declare #BeginingOfMonth as DateTime
set #BeginingOfMonth = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-1),GETDATE()),101))
select #BeginingOfMonth as EndOfMonths
declare #BeginingOfMonthPlus1 as DateTime
set #BeginingOfMonthPlus1 = (SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GETDATE())-2),GETDATE()),101))
select #BeginingOfMonthPlus1 as EndOfMonths
-- select dates in month exclude first and last day
SELECT TOP 1000 [effective_date]
FROM [Locations]
where effective_date <= #EndOfMonthMinus1
and effective_date >= #BeginingOfMonthPlus1
-- select only first of month and last of month
SELECT TOP 1000 [effective_date]
FROM [Locations]
where [effective_date]<= #EndOfMonth
and [effective_date] >= #EndOfMonthMinus1
and [effective_date] >= #BeginingOfMonth
and [effective_date] <= #BeginingOfMonthPlus1
Hope this helps!