Counting the records of two columns from different tables - sql-server

So I have this:
select count(InvoiceUniqueness) as [Nbr], CONVERT(varchar(12), ProcessDate, 101) as [Date]
from PreProcessTransLog
where (CONVERT(DATETIME, ProcessDate, 102)) >= dateadd (m,-24,getdate()) and CONVERT(DATETIME, ProcessDate, 120) <= GETDATE()
and InitialStatus =2
group by CONVERT(varchar(12), ProcessDate, 101)
order by CAST (CONVERT(varchar(12), ProcessDate, 101) as smalldatetime) desc
I want to count the records under the InvoiceUniqueness column from the PreProcessTransLog table and count the records under (column not in the code) ManualBillHeaderID from another table called Ex_Manual_Bill_Header. I want to display both count results in a new column called Nbr. So in simpler terms, lets say I count column1 from T1 and column2 from T2. column1 has 10 records and column2 has 5. I want to join both columns into one so I can display 15 records. Keep in mind the columns have different names. hope im explaining myself

Try something like this:
SELECT
COALESCE(t1.[Date], t2.[Date]) AS [Date],
ISNULL(t1.Nbr, 0), + ISNULL(t2.Nbr, 0) AS Total
FROM
(
SELECT COUNT(InvoiceUniqueness) AS [Nbr], CONVERT(VARCHAR(12), ProcessDate, 101) AS [Date]
FROM PreProcessTransLog
WHERE (CONVERT(DATETIME, ProcessDate, 102))>=DATEADD(m, -24, GETDATE()) AND CONVERT(DATETIME, ProcessDate, 120)<=GETDATE() AND InitialStatus=2
GROUP BY CONVERT(VARCHAR(12), ProcessDate, 101)
--ORDER BY [Date]
) t1,
FULL JOIN (
SELECT COUNT(ManualBillHeaderID ) AS [Nbr], CONVERT(VARCHAR(12), ProcessDate, 101) AS [Date]
FROM <whatever table>
WHERE (CONVERT(DATETIME, ProcessDate, 102))>=DATEADD(m, -24, GETDATE()) AND CONVERT(DATETIME, ProcessDate, 120)<=GETDATE() AND InitialStatus=2
GROUP BY CONVERT(VARCHAR(12), ProcessDate, 101)
--ORDER BY [Date]
) t2 ON t1.[Date] = t2.[Date]
ORDER BY
COALESCE(t1.[Date], t2.[Date])

If I'm understanding your request accurately, I would do something like this.
Do your counts, off each table, and merge the results with a UNION ALL, wrap that up in a sub-query, and SUM() the resulting counts.
declare #table1 table (id int identity(1,1), recorddate datetime)
declare #table2 table (id int identity(1,1), otherdate datetime)
insert into #table1
select '2014-08-01' union all
select '2014-08-01'
insert into #table2
select '2014-08-01' union all
select '2014-08-02'
select SUM(num), recorddate
from (select COUNT(1) num, recorddate
from #table1
group by recorddate
union all
select COUNT(1) num, otherdate
from #table2
group by otherdate ) x
group by recorddate
In the case you want the results separate, change the last query to this:
select COUNT(*) num, recorddate
from #table1
group by recorddate
union all
select COUNT(*) num, otherdate
from #table2
group by otherdate

Try using a UNION ALL. For example:
SELECT COUNT(Column1) AS [Nbr]
FROM Table1
GROUP BY ColumnToGroupOn1
UNION ALL
SELECT COUNT(Column2)
FROM Table2
GROUP BY ColumnToGroupOn2
Or if you want to include the date column/s:
SELECT COUNT(Column1) AS [Nbr], ColumnToGroupOn1 AS [Date]
FROM Table1
GROUP BY ColumnToGroupOn1
UNION ALL
SELECT COUNT(Column2), ColumnToGroupOn2
FROM Table2
GROUP BY ColumnToGroupOn2

Related

Multi - Columns OVERLAPPING DATES

;with cte as (
select Domain_Id, Starting_Date, End_Date
from Que_Date
union all
select t.Domain_Id, cte.Starting_Date, t.End_Date
from cte
join Que_Date t on cte.Domain_Id = t.Domain_Id and cte.End_Date = t.Starting_Date),
cte2 as (
select *, rn = row_number() over (partition by Domain_Id, End_Date order by Domain_Id)
from cte
)
select DISTINCT Domain_Id, Starting_Date, max(End_Date) enddate
from cte2
where rn=1
group by Domain_Id, Starting_Date
order by Domain_Id, Starting_Date;
select * from Que_Date
This is the code that I have wrote but i am getting an extra row i.e 2nd row is extra, the expected output should have only 1st, 3rd and 4th row as output so please help me with it.
I have attached an image showing Input, Excepted Output, and the output that I am getting.
You've got so many results in your first cte. Your first cte has consisting domains. So you cannot filter domains based on your cte. So you query has unnecessary rows.
Try this solution. Cte ConsistentDomains has just consistent domains. So based on this cte, we can get not overlapped results.
Create and fill data:
CREATE TABLE FooTable
(
Domain_ID INT,
Starting_Date DATE,
End_Date Date
)
INSERT INTO dbo.FooTable
(
Domain_ID,
Starting_Date,
End_Date
)
VALUES
( 1, -- Domain_ID - int
CONVERT(datetime,'01-01-2011',103), -- Starting_Date - date
CONVERT(datetime,'05-01-2011',103) -- End_Date - date
)
, (1, CONVERT(datetime,'05-01-2011',103), CONVERT(datetime,'07-01-2011',103))
, (1, CONVERT(datetime,'07-01-2011',103), CONVERT(datetime,'15-01-2011',103))
, (2, CONVERT(datetime,'11-05-2011',103), CONVERT(datetime,'12-05-2011',103))
, (2, CONVERT(datetime,'13-05-2011',103), CONVERT(datetime,'14-05-2011',103))
Query to find not overlapping results:
DECLARE #startDate varchar(50) = '2011-01-01';
WITH ConsistentDomains AS
(
SELECT
f.Domain_ID
, f.Starting_Date
, f.End_Date
FROM FooTable f
WHERE f.Starting_Date = #startDate
UNION ALL
SELECT
s.Domain_ID
, s.Starting_Date
, s.End_Date
FROM FooTable s
INNER JOIN ConsistentDomains cd
ON s.Domain_ID = cd.Domain_ID
AND s.Starting_Date = cd.End_Date
), ConsistentDomainsRownumber AS
(
SELECT
cd.Domain_ID
, cd.Starting_Date
, cd.End_Date
, ROW_NUMBER() OVER (PARTITION BY cd.Domain_ID ORDER BY cd.Starting_Date,
cd.End_Date) RN
FROM ConsistentDomains cd
)
SELECT cd.Domain_ID
, convert(varchar, cd.Starting_Date, 105) Starting_Date
, convert(varchar, cd.End_Date, 105) End_Date
FROM ConsistentDomainsRownumber cd WHERE cd.RN = 1
UNION ALL
SELECT
ft.Domain_ID
, convert(varchar, ft.Starting_Date, 105) Starting_Date
, convert(varchar, ft.End_Date, 105) End_Date
FROM dbo.FooTable ft WHERE ft.Domain_ID NOT IN (SELECT cd.Domain_ID FROM
ConsistentDomainsRownumber cd)
Output:
I used the same table creating script as provided by #stepup, but you can also get your outcome in this way.
CREATE TABLE testtbl
(
Domain_ID INT,
Starting_Date DATE,
End_Date Date
)
INSERT INTO testtbl
VALUES
(1, convert(date, '01-01-2011' ,103), convert(date, '05-01-2011',103) )
,(1, convert(date, '05-01-2011' ,103), convert(date, '07-01-2011',103) )
,(1, convert(date, '07-01-2011' ,103), convert(date, '15-01-2011',103) )
,(2, convert(date, '11-05-2011' ,103), convert(date, '12-05-2011',103) )
,(2, convert(date, '13-05-2011' ,103), convert(date, '14-05-2011',103) )
You can make use of self join and Firs_value and last value within the group to make sure that you are comparing within the same ID and overlapping dates.
select distinct t.Domain_ID,
case when lag(t1.starting_date)over (partition by t.Domain_id order by
t.starting_date) is not null
then first_value(t.Starting_Date) over (partition by t.domain_id order by
t.starting_date)
else t.Starting_Date end StartingDate,
case when lead(t.domain_id) over (partition by t.domain_id order by t.starting_date) =
t1.Domain_ID then isnull(last_value(t.End_Date) over (partition by t.domain_id order by t.end_date rows between unbounded preceding and unbounded following),t.End_Date)
else t.End_Date end end_date
from testtbl t
left join testtbl t1 on t.Domain_ID = t1.Domain_ID
and t.End_Date = t1.Starting_Date
and t.Starting_Date < t1.Starting_Date
Output:
Domain_ID StartingDate end_date
1 2011-01-01 2011-01-15
2 2011-05-11 2011-05-12
2 2011-05-13 2011-05-14

Temptable in SQL Server

Query #1:
SELECT a.*
INTO #TempTable1
FROM
(SELECT
Vendor,
CASE WHEN CONVERT(varchar(50), DateModified, 101)='01/01/1900' THEN '' ELSE CONVERT(varchar(50), DateModified, 101) END AS 'Date of Last Check',
CASE WHEN CONVERT(varchar(50), PaycommissionDate, 101)='01/01/1900' THEN '' ELSE CONVERT(varchar(50), PaycommissionDate, 101) END AS 'Date of check for month',
SUM([Original $ Total]) 'Amount'
FROM
Tbl_Commission_Reconcilation
WHERE
Vendor IS NOT NULL
AND MONTH([Order Date]) = MONTH (GETDATE())
GROUP BY
Tbl_Commission_Reconcilation.Vendor,
CONVERT(varchar(50), DateModified, 101),
[Sales Rep], PaycommissionDate) a
Output:
Vendor Date of Last Check Date of check for month Amount
-----------------------------------------------------------------------------
Boston Warehouse 12/12/2017 12/12/2017 919.00
Woodlink 12/12/2017 12/12/2017 979.86
Query #2:
SELECT b.*
INTO #TempTable2
FROM
(SELECT
[Sales Rep],
SUM([Commission $ paid]) 'Commission $ paid'
FROM
Tbl_Commission_Reconcilation
WHERE
Vendor IS NOT NULL
AND MONTH([Order Date]) = MONTH (GETDATE())
GROUP BY
[Sales Rep]) b
Output 2:
Sales Rep Commission $ paid
---------------------------------
Tammy Hanson 379.77
Final query:
select *
from #TempTable1, #TempTable2
Final output:
Vendor DateofLastCheck Dateofcheckformonth Amount Sales Rep Commpaid
Boston
Warehouse 12/12/2017 12/12/2017 919.00 Tammy Hanson 379.77
Woodlink 12/12/2017 12/12/2017 979.86 Tammy Hanson 379.77
Output 2 shows only one commission paid 379.77 for Tammy Hanson.But in final output shows 2 times commission paid 379.77.How to rectify this problem?
How to show only one commission paid in the final output?Please, any one helps me.
You are getting the duplicate values because you are using a Cross Join ( Cartesian Product) here. Please specify at least 1 condition to match the records from both tables so that the values will be displayed only against the desired records.
As per your current query, it will return all the possible combinations of rows in both tables. change it like this
select * from #TempTable1 T1,#TempTable2 T2 WHERE T1.ColumnName = T2.ColumnName
or you can also say
select * from #TempTable1 T1
inner join #TempTable2 T2
WHERE T1.ColumnName = T2.ColumnName
-- if you want records that have matches on both tables
or
select * from #TempTable1 T1
left join #TempTable2 T2
WHERE T1.ColumnName = T2.ColumnName
-- if you want records from #TempTable1 and display null for TempTable2 if no matching records
It appears you can just do one query. The larger query already has [sales rep] in the group by clause, so why not just sum the commission?
SELECT
a.* INTO #TempTable1
FROM (
SELECT
Vendor
, CASE WHEN CONVERT(varchar(50), DateModified, 101) = '01/01/1900' THEN '' ELSE CONVERT(varchar(50), DateModified, 101) END
AS 'Date of Last Check'
, CASE WHEN CONVERT(varchar(50), PaycommissionDate, 101) = '01/01/1900' THEN '' ELSE CONVERT(varchar(50), PaycommissionDate, 101) END
AS 'Date of check for month'
, SUM([Original $ Total]) 'Amount'
, [Sales Rep]
, SUM([Commission $ paid]) 'Commission $ paid'
FROM Tbl_Commission_Reconcilation
WHERE Vendor IS NOT NULL
AND MONTH([Order Date]) = MONTH(GETDATE())
GROUP BY
Tbl_Commission_Reconcilation.Vendor
, CONVERT(varchar(50), DateModified, 101)
, [Sales Rep]
, PaycommissionDate
) a
You should also add row_number to your queries
For Table1
SELECT a.*
INTO #TempTable1
FROM
(SELECT
Vendor,
CASE WHEN CONVERT(varchar(50), DateModified, 101)='01/01/1900' THEN '' ELSE CONVERT(varchar(50), DateModified, 101) END AS 'Date of Last Check',
CASE WHEN CONVERT(varchar(50), PaycommissionDate, 101)='01/01/1900' THEN '' ELSE CONVERT(varchar(50), PaycommissionDate, 101) END AS 'Date of check for month',
SUM([Original $ Total]) 'Amount',
ROW_NUMBER() OVER(ORDER BY Vendor, DateModified, [Sales Rep]) RN
FROM
Tbl_Commission_Reconcilation
WHERE
Vendor IS NOT NULL
AND MONTH([Order Date]) = MONTH (GETDATE())
GROUP BY
Tbl_Commission_Reconcilation.Vendor,
CONVERT(varchar(50), DateModified, 101),
[Sales Rep], PaycommissionDate) a
For Table 2
SELECT b.* INTO #TempTable2
from
(SELECT [Sales Rep],SUM([Commission $ paid]) 'Commission $ paid',
ROW_NUMBER() OVER(ORDER BY [Sales Rep]) RN
from Tbl_Commission_Reconcilation where Vendor is not null and Month([Order Date])= MONTH (Getdate())
group by [Sales Rep])b
and also left join table1 and table2 with this RN column
select
*
from #TempTable1 t1
LEFT JOIN #TempTable2 t2
ON t1.RN = t2.RN

Select date and time range when date and time are in two seperate columns

I'm working on a database where the date and time is in two seperate columns and I'm tasked to show records between two dates and times intervals.
I have made the following query, but that gives me only the records from 10 to 12 on both dates. I'm missing the records from after 12 to 10 the next day.
How can I accomplish this?
SELECT
[guid],
[date],
[time],
[pos]
FROM
SomeTable
WHERE
[guid] = '0Q8m48D_uHua6P0'
AND [date] >= '2017-09-12'
AND time >= '10:00'
AND [date] <= '2017-09-13'
AND time <= '12:00';
Have a clause for beginning and end date exceptions:
SELECT [guid], [date], [time], [pos]
FROM [table]
WHERE [guid] = '0Q8m48D_uHua6P0'
and [date] >= '2017-09-12' AND [time] >= iif([date] = '2017-09-12', '10:00', [time])
AND [date] <= '2017-09-13' AND [time] <= iif([date] = '2017-09-13', '12:00', [time]);
You could of course combine them and then use BETWEEN to filter, like this:
SELECT
[guid],
[date],
[time],
[pos]
FROM
SomeTable
WHERE [guid] = '0Q8m48D_uHua6P0'
AND (DATEADD(day, DATEDIFF(day,'19000101', [date]), CAST([time] AS DATETIME2(7)))) BETWEEN '2017-09-12 12:00:00.000' and '2017-09-12 12:00:00.000'
..but this is a bad idea, since you have a function on your conditions, which will might make the query optimizer ignore any indexes you might have in place (since such a query is not sargable)
So, I would create a new persisted computed column on your table called [Datetime] or anything that makes sense to you and then give it a default value as:
DATEADD(day, DATEDIFF(day,'19000101', [date]), CAST([time] AS DATETIME2(7))))
Then you would be able to write the query as follows:
SELECT
[guid],
[date],
[time],
[pos]
FROM
SomeTable
WHERE [guid] = '0Q8m48D_uHua6P0'
AND [Datetime] BETWEEN '2017-09-12 12:00:00.000' and '2017-09-12 12:00:00.000'
You can compute a column as DATETIME and then filter on it.
;with cte as (
SELECT
[guid],
[date],
[time],
[pos],
DT = cast([date] as datetime) + cast([time] as datetime)
FROM
SomeTable
WHERE
[guid] = '0Q8m48D_uHua6P0'
)
select *
from cte
where DT between '20170912 10:00' and '20170913 12:00'
Here is one way of doing this
SELECT
[guid],
[date],
[time],
[pos]
FROM
SomeTable
WHERE
[guid] = '0Q8m48D_uHua6P0'
AND
CAST (
CONVERT(Varchar(10), [date], 112) + ' ' +
CONVERT(Varchar(8), [time]) AS DateTime) Between '2017-09-12 10:00'
AND '2017-09-13 12:00'

Check order row depending on result query in sql server

I have a table checks2:
AllTaskNo int,
CheckQuosimaNo int,
Masroof numeric(18,3),
Maqbood numeric(18,3),
Date1 smalldatetime
I have a query to get balance:
SELECT
AllTaskNo
,CheckQuosimaNo
,Masroof
,Maqbood
,Date
,(SELECT 0 + SUM(Maqbood - Masroof) AS Expr1
FROM Checks2 AS t2
WHERE (BankNo = 6)
AND (CheckQuosimaNo <= Checks2.CheckQuosimaNo)
AND (Date1 BETWEEN CONVERT(DATETIME, '01/01/2014', 103)
AND CONVERT(DATETIME, '31/10/2015', 103)) AND AllTaskNo
IN (SELECT No
FROM AllTasks
WHERE (BankNo = 6)
AND (Date BETWEEN CONVERT(DATETIME, '01/01/2014', 103)
AND CONVERT(DATETIME, '31/10/2015', 103))))) AS NetAmount
FROM
Checks2
WHERE
(BankNo = 6)
AND
(Date1 BETWEEN CONVERT(DATETIME, '01/01/2014', 103)
AND CONVERT(DATETIME, '31/10/2015', 103))
ORDER BY
BankNo
,Date1
,CheckQuosimaNo
the result is:
enter image description here
I need to make a formula (like excel for example NetAmount = NetAmount before + Maqbood - Masroof)
I expect that the selected row in NetAmount = 656360 but then query produce NetAmount=5567675.976
How can I fix this problem
There are many way to do this like Over and Correlated Sub Queries
Over:
SELECT
AllTaskNo ,Maqbood , Masroof,
SUM(-1*Maqbood +Masroof) OVER (ORDER BY AllTaskNo ) AS NetAmount
FROM Checks2 T1
Correlated Sub Queries (Need Sql server 2014+)
SELECT
AllTaskNo ,Maqbood , Masroof,
(
SELECT
SUM(-1*Maqbood +Masroof)
FROM Checks2 T2
WHERE T2.AllTaskNo <=T1.AllTaskNo
) AS NetAmount FROM Checks2 T1
Feel free to comment if you need any further assistance on this item
I have been solve my problem by my own solution ... I think there is a shorter solution .. but any way I get what I want... My solution is:
1- Make a table (Checks3) with a new field named (rank) which is the correct order of the command result.
2- Create a new command mostly like the first one containing the (bank balance formula).
if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[Checks3]') and OBJECTPROPERTY(id, N'IsUserTable') = 1) drop table [dbo].[Checks3]
SELECT Checks2.BankNo, Checks2.AllTaskNo, Checks2.CheckQuosimaNo, Checks2.Masroof, Checks2.Maqbood, Checks2.Date1, rank() OVER (ORDER BY checks2.date1, checks2.CheckQuosimaNo) as rank
INTO Checks3
FROM Checks2 INNER JOIN
AllTasks ON Checks2.AllTaskNo = AllTasks.No where Checks2.BankNo =6 and (Checks2.[Date1] BETWEEN CONVERT(DATETIME, '01/10/2015', 103) AND CONVERT(DATETIME,'31/10/2015', 103)) ORDER BY CHECKS2.BankNo, CHECKS2.CheckQuosimaNo
SELECT Checks3.AllTaskNo, Checks3.CheckQuosimaNo, Checks3.Masroof, Checks3.Maqbood, Checks3.Date1,
( SELECT 0+SUM(t2.Maqbood - t2.Masroof) FROM Checks3 t2
WHERE t2.BankNo =6 and t2.rank <= Checks3.rank
and (t2.[Date1] BETWEEN CONVERT(DATETIME, '01/10/2014', 103) AND CONVERT(DATETIME,'31/10/2015', 103))
) as NetAmount
FROM Checks3
where Checks3.BankNo =6 and (Checks3.[Date1] BETWEEN CONVERT(DATETIME, '01/10/2014', 103) AND CONVERT(DATETIME,'31/10/2015', 103)) ORDER BY CHECKS3.RANK

How to query Open-high-low-close (OHLC) data from SQL Server

I'm trying to retrieve data for a Open-high-low-close (OHLC) chart directly from the database, it's the kind of chart you see of stocks. Is this possible, and if, how?
I have a table like this (simplified):
Date | Price | PriceType
A record is created for each day, I will report per month / year, not per day as used for stocks.
I would like to query something like this:
SELECT PriceType, MAX(Price) as High, MIN(Price) as Low, [Price of first item of month] as Open, [Price of last item of month] as Close GROUP BY PriceType, Year(Date), Month(Date)
To access the SQL Server I use LLBLGen, so an anwser based on that technology would be great, a generic SQL server will do too!
It's SQL 2005, but 2008 is also an option.
Thanks.
This appears to work. There may well be a less verbose way to do it.
--create test data
CREATE TABLE #t
(priceDate DATETIME
,price MONEY
,priceType CHAR(1)
)
INSERT #t
SELECT '20090101',100,'A'
UNION SELECT '20090102',500,'A'
UNION SELECT '20090103',20 ,'A'
UNION SELECT '20090104',25 ,'A'
UNION SELECT '20090105',28 ,'A'
UNION SELECT '20090131',150,'A'
UNION SELECT '20090201',501,'A'
UNION SELECT '20090203',21 ,'A'
UNION SELECT '20090204',26 ,'A'
UNION SELECT '20090205',29 ,'A'
UNION SELECT '20090228',151,'A'
UNION SELECT '20090101',100,'B'
UNION SELECT '20090102',500,'B'
UNION SELECT '20090103',20 ,'B'
UNION SELECT '20090104',25 ,'B'
UNION SELECT '20090105',28 ,'B'
UNION SELECT '20090131',150,'B'
UNION SELECT '20090201',501,'B'
UNION SELECT '20090203',21 ,'B'
UNION SELECT '20090204',26 ,'B'
UNION SELECT '20090205',29 ,'B'
UNION SELECT '20090228',151,'B'
--query
;WITH rangeCTE
AS
(
SELECT MIN(priceDate) minDate
,MAX(priceDate) maxDate
FROM #t
)
,datelistCTE
AS
(
SELECT CAST(CONVERT(CHAR(6),minDate,112) + '01' AS DATETIME) AS monthStart
,DATEADD(mm,1,CAST(CONVERT(CHAR(6),minDate,112) + '01' AS DATETIME)) -1 AS monthEnd
,1 AS monthID
FROM rangeCTE
UNION ALL
SELECT DATEADD(mm,1,monthStart)
,DATEADD(mm,2,monthStart) - 1
,monthID + 1
FROM datelistCTE
WHERE monthStart <= (SELECT maxDate FROM rangeCTE)
)
,priceOrderCTE
AS
(
SELECT *
,ROW_NUMBER() OVER (PARTITION BY monthID, priceType
ORDER BY priceDate
) AS rn1
,ROW_NUMBER() OVER (PARTITION BY monthID, priceType
ORDER BY priceDate DESC
) AS rn2
,ROW_NUMBER() OVER (PARTITION BY monthID, priceType
ORDER BY price DESC
) AS rn3
,ROW_NUMBER() OVER (PARTITION BY monthID, priceType
ORDER BY price
) AS rn4
FROM datelistCTE AS d
JOIN #t AS t
ON t.priceDate BETWEEN d.monthStart AND d.monthEnd
WHERE monthStart <= (SELECT maxDate FROM rangeCTE)
)
SELECT o.MonthStart
,o.priceType
,o.Price AS opening
,c.price AS closing
,h.price AS high
,l.price AS low
FROM priceOrderCTE AS o
JOIN priceOrderCTE AS c
ON c.priceType = o.PriceType
AND c.monthID = o.MonthID
JOIN priceOrderCTE AS h
ON h.priceType = o.PriceType
AND h.monthID = o.MonthID
JOIN priceOrderCTE AS l
ON l.priceType = o.PriceType
AND l.monthID = o.MonthID
WHERE o.rn1 = 1
AND c.rn2 = 1
AND h.rn3 = 1
AND l.rn4 = 1
This is a little query I wrote that seems to work nicely for one time span at a time. All you need to do is comment the select DATEPARTS in order to get to the timespan you are looking for. Or you could just make multiple views for different timespans. Also the underlying data table uses Bid Ask tick style data. If you are using mids or last prices you could eliminate the case statements from the selects.
Select
tmp.num,
rf.CurveName,
rf.Period as Period,
CASE WHEN (tmp2.Bid is null or tmp2.Ask is null) then isnull(tmp2.Bid,0)+isnull(tmp2.Ask,0) else (tmp2.Bid+tmp2.Ask)/2 end as [Open],
tmp.Hi,
tmp.Lo,
CASE WHEN (rf.Bid is null or Rf.Ask is null) then isnull(rf.Bid,0)+isnull(rf.Ask,0) else (rf.Bid+rf.Ask)/2 end as [Close],
tmp.OpenDate,
tmp.CloseDate,
tmp.yr,
tmp.mth,
tmp.wk,
tmp.dy,
tmp.hr
from BidAsk rf inner join
(SELECT count(CurveName)as num,CurveName,
Period,
max(CASE WHEN (Bid is null or Ask is null) then isnull(Bid,0)+isnull(Ask,0) else (Bid+Ask)/2 end) as Hi,
min(CASE WHEN (Bid is null or Ask is null) then isnull(Bid,0)+isnull(Ask,0) else (Bid+Ask)/2 end) as Lo,
max(CurveDateTime) as CloseDate, min(CurveDateTime) as OpenDate,
DATEPART(year, CurveDateTime) As yr,
DATEPART(month, CurveDateTime) As mth,
DATEPART(week, CurveDateTime) As wk,
DATEPART(Day, CurveDateTime) as dy,
DATEPART(Hour, CurveDateTime) as hr
--DATEPART(minute, CurveDateTime) as mnt
FROM
BidAsk
GROUP BY
CurveName,Period,
DATEPART(year, CurveDateTime),
DATEPART(month, CurveDateTime),
DATEPART(week, CurveDateTime),
DATEPART(Day, CurveDateTime) ,
DATEPART(Hour, CurveDateTime)
--DATEPART(minute, CurveDateTime)
) tmp on
tmp.CurveName=rf.CurveName and
tmp.CloseDate=rf.CurveDateTime and
tmp.Period=rf.Period
inner join BidAsk tmp2 on
tmp2.CurveName=rf.CurveName and
tmp2.CurveDateTime=tmp.Opendate and
tmp2.Period=rf.Period
ORDER BY
CurveName,Period,tmp.yr,tmp.mth
--DATEPART(year, CurveDateTime),
--DATEPART(month, CurveDateTime)
--DATEPART(day, CurveDateTime),
--DATEPART(Hour, CurveDateTime),
--DATEPART(minute, CurveDateTime) )

Resources