Below is the sample data which gets filled into sql server database from different PLC machine. datetime,machineID, cycletime(TIME TAKEN TO PRODUCE THAT MATERIAL) AND shift
There are 3 shifts in company A(6:30Am to 2:30PM), B(2:30 to 10:30), C(10:30 to 6:30AM).
when i take C Shift count, my query should take next day data also till 6:30AM time. Where as A shift should take current day data starting from 6:30Am to 2:30Pm.Where as B shift should take current day data starting from 2:31pm to 10:30PM.
Desired Output::
I need to find the quantity for each hour...6:30 to 7:30 what is the quantity... 7:30 to 8:30 what is the quantity and so on for each individual hour. Quantity should not get added with previous hour quantity.. individual hour quantity
You can start with this, and then wrap it with
"SELECT ... just the columns you want
FROM this example
GROUP BY ...."
SELECT
-- isolate Date from Time from HourMinutes only for testing
CONVERT(VARCHAR(10), [MDate], 111) as RealDate
,CONVERT(VARCHAR, [MTime], 108) as RealTime
,SUBSTRING(CONVERT(VARCHAR, [MTime], 108),4,5) as HrMn
-- from midnight to 6:30 adjust to prior day
, Case When (CONVERT(VARCHAR, [MTime], 108) < '06:30:00')
Then CONVERT(VARCHAR(10), DATEADD(day,-1,[MDate]), 111)
Else CONVERT(VARCHAR(10), [MDate], 111)
End as RptDate
-- from after the half hour, report it with the next hour
,Case When (SUBSTRING(CONVERT(VARCHAR, [MTime], 108),1,5)) > '23:30:00'
Then ' 0:30'
When (SUBSTRING(CONVERT(VARCHAR, [MTime], 108),4,5)) > '30:00'
Then STR(DATEPART ( hour , [MTime] ) + 1, 2) + ':30'
Else STR(DATEPART ( hour , [MTime] ), 2) + ':30'
End as RptHour
,[MachinelD]
,[CYCLETIM]
,[Shift]
FROM [StackOver].[dbo].[CShift]
For your add-on question of getting only Previous or Current shift,
we need to think ahead to what the Where clause might look like--
Where (MDate = #fromDate and MTime >= #fromTime)
Or (MDate > #fromDate)
And then, before the main SELECT/FROM, create appropriate local vars --
Declare #fromDate as datetime, #fromTime as datetime
If CONVERT (time, GETDATE()) <= '06:30:00' Begin
Set #fromDate=DATEADD(day,-1,CONVERT (date, GETDATE())) --yesterday
Set #fromTime='14:30'
End
Else If CONVERT (time, GETDATE()) <= '14:30:00' Begin
Set #fromDate=DATEADD(day,-1,CONVERT (date, GETDATE())) --yesterday
Set #fromTime='22:30'
End
Else If CONVERT (time, GETDATE()) <= '22:30:00' Begin
Set #fromDate=CONVERT (date, GETDATE()) --today
Set #fromTime='06:30'
End
Else Begin -- time > 22:30
Set #fromDate=CONVERT (date, GETDATE()) --today
Set #fromTime='14:30'
End
-- for testing only, show the values
Select #fromDate, #fromTime
I leave any remaining question(s) to your own solution
Related
I've a scenario when a SELECT CASE statement is limiting the number of rows returned. Whilst I'm not a professional DB, I get by with some reasonable SQL and I didn't think that a SELECT CASE would actually limit the results?, just perform the THEN part of the CASE if the WHEN qualified.
To give some context, I've a transaction table which logs whenever an item is moved between a depot and the customer on some rental activity. Each transaction is registered as a row with a reference order and date of the transaction. To get both the customer receipt transaction and back to depot transaction on a single line, I've used (what might be a crude!) FROM SELECT. However, this part seems ok.
I'm on a SQL Server 2012.
Now, depending on what dates all of this happened, I've a taken the first date and last date involved and applied a SELECT CASE to define some conditions and resulting Date Difference calculations.
DECLARE #RUNDATE AS DECIMAL(8) = '20170101'
DECLARE #DAYFIRST AS DATETIME = DATEADD(m, DATEDIFF(m, 0, CONVERT(DATE, CAST(#RUNDATE AS VARCHAR(8)), 112)),0)
DECLARE #DAYEND AS DATETIME = DATEADD(s, -1, DATEADD(m, DATEDIFF(m, 0, CONVERT(DATE, CAST(#RUNDATE AS VARCHAR(8)), 112))+1, 0))
DECLARE #DAYSINPERIOD AS DECIMAL(2) = DAY(EOMONTH(CONVERT(DATE, CAST(#RUNDATE AS VARCHAR(8)), 112)))
SELECT MTITNO AS 'Item Number',
MTBANO AS 'Serial Number',
MTRORN AS 'Rental Order',
MTRORL AS 'Rental Order Line',
MTTRQT AS 'Delivered Quantity',
CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) AS 'Customer Receipt Date', --received in M3 to the customer, although this is aligned to when qty left the yard manually by logistics
CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112) AS 'Return To Depot Date', --last date in the return chain, receiving to the yard. If still in transit this equals the termination date
CASE
WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) < #DAYFIRST AND NEXTDATE IS NULL --is started before current period and no return activity or termination
THEN #DAYSINPERIOD --simply count the days in the current month as utilised
ELSE 0
END AS 'On Rent Entire Period',
CASE
WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) < #DAYFIRST AND NEXTDATE >= #DAYFIRST AND NEXTDATE <= #DAYEND --is started before current period but has a return activity/termination date
THEN DATEDIFF("DD",#DAYFIRST,CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112))+1 --difference between start of month and the nextdate (+1 for date difference include all)
ELSE 0
END AS 'Started Previous Period, Ended This Period',
CASE
WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= #DAYFIRST AND NEXTDATE IS NULL --is started in the current period and no return activity or termination
THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),#DAYEND)+1 --difference between start date and last day of the current month (in line with utilisation) (+1 for date differnce include all)
ELSE 0
END AS 'Started This Period, No End Date',
CASE
WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= #DAYFIRST AND NEXTDATE >= #DAYFIRST AND NEXTDATE <= #DAYEND --is started in the current period and has a return activity/termination date
THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112))+1 --different between start date and the nextdate (+1 for date differnce include all)
ELSE 0
END AS 'Started and Ended This Period', --current period rental days (should match utilisation as sum of all lines)
#DAYSINPERIOD AS 'Calendar Days in Month', --how many days in the current month
#DAYFIRST AS 'First of Month', --what is the date of the first day of the current month
#DAYEND AS 'Last of Month' --what is the date of the last day of the current month
FROM
(
SELECT MTITNO,
MTBANO,
MTRORN,
MTRORL,
MTTRQT,
MTTRDT,
(
SELECT MIN(MTTRDT)
FROM MVXJDTA.MITTRA T2
WHERE T1.MTITNO = T2.MTITNO
AND T1.MTBANO = T2.MTBANO
AND T1.MTRORN = T2.MTRORN
AND T1.MTRORL = T2.MTRORL
AND T1.MTTRQT = T2.MTTRQT
AND T2.MTTRDT > T1.MTTRDT
) AS NEXTDATE
FROM MVXJDTA.MITTRA T1
WHERE MTCONO = 880
AND MTTTYP = '50'
AND MTTRQT > 0
AND MTCAMU <> ''
AND MTRORN LIKE 'A0%'
) T
This only returns the first 2 rows in what should be an entire data set.
2 rows
However, if I comment out the 4th SELECT CASE, then I get all records returned?!
all rows
-- CASE
-- WHEN CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112) >= #DAYFIRST AND NEXTDATE >= #DAYFIRST AND NEXTDATE <= #DAYEND --is started in the current period and has a return activity/termination date
-- THEN DATEDIFF(D,CONVERT(DATE, CAST(MTTRDT AS VARCHAR(8)), 112),CONVERT(DATE, CAST(NEXTDATE AS VARCHAR(8)), 112))+1 --different between start date and the nextdate (+1 for date differnce include all)
-- ELSE 0
-- END AS 'Started and Ended This Period', --current period rental days (should match utilisation as sum of all lines)
The strange thing is that the 3rd row should match the condition I've just commented out.
Can anyone help me better understand why a SELECT CASE would be a limit to the rows returned? And where my probable poor syntax might be the cause!!!
I'm importing my data to excel and so I need to see the date as a varchar to use for a graph in excel but I also need the data for the individual hours in the day as well. My manager wants to see data for the past hour whenever he checks my chart. This is my code so far. Dayshift has been fine but I can't get the hours to go past 24 for nightshift so I can't group them in my graph in excel.
convert(VARCHAR, TimeStamp, 101) as date
,StationID as lane
,DATEPART(hh,TimeStamp)
,.185 as posSD1
,-.185 as negSD1
,.370 as posSD2
,-.370 as negSD2
,.556 as posSD3
,-.556 as negSD3
, COUNT (TrickleActual) as Count
, convert(decimal (18,3) ,AVG (TrickleActual - TrickleTarget)) as Average
FROM CherryBoxInfo
WHERE TimeStamp >= '2015-05-01' -- '2015-05-01 18:30:00'
and TimeStamp between convert(DATETIME, convert(VARCHAR, TimeStamp, 101) + ' ' + '19:00:00') and convert(DATETIME, convert(VARCHAR, DATEADD(day, 1, TimeStamp), 101) + ' ' + '04:30:00')
and (TrickleActual-TrickleTarget) BETWEEN -1 and 1
GROUP BY
convert(VARCHAR, TimeStamp, 101)
,StationID
,DATEPART(hh,TimeStamp)
ORDER BY convert(VARCHAR, TimeStamp, 101)
,StationID
,DATEPART(hh,TimeStamp)
Instead of grouping on datepart, group on date truncated to hour.
Here is how to truncate a date:
select dateadd(hh, datediff(hh, 0, #dt), 0)
Hoping someone can tell me where I am going wrong here, I started with a Business Hours query found at Calculate business hours between two dates, it's the second top answer because the top answer was not providing the correct output upon testing. The issue I am having is when I cross over to a new day and the end datetime exceeds the Business Day End. Here is my test:
select dbo.BusinessSeconds('09:00:00','17:00:00','2014-12-24 16:59:59','2014-12-26 18:00:00');
So if I go from 1 second before COB to the start of the next day, I get 1 second, which is correct. If I go from the same start to the end of the day the next day, I get 28801, or 1 full day and 1 second - which is also correct. However, if I extend the date end time to 17:00:01 through 17:59:59 it also includes those seconds but if I hit 18:00:00, the time truncates back to the original 17:00:00 end of day. So I will get correct data for any given end time unless it is during the 17:00:00-17:59:59 timeframes and then I potentially get up to an extra hour of time that I should not have.
Any help would be greatly appreciated as I have a deliverable on this by tomorrow.
ALTER Function [dbo].[BusinessSeconds](#BusinessDayStart TIME,#BusinessDayEnd TIME,#StartDate DATETIME,#EndDate DATETIME) Returns Int
AS
Begin
--TEST: select dbo.BusinessSeconds('09:00:00','17:00:00','2014-12-24 16:59:59','2014-12-26 18:00:00');
Declare #WorkMin INT = 0 -- Initialize counter
Declare #Reverse BIT -- Flag to hold if direction is reverse
Declare #StartHour TIME = #BusinessDayStart -- Start of business hours (can be supplied as an argument if needed)
Declare #EndHour TIME = #BusinessDayEnd -- End of business hours (can be supplied as an argument if needed)
Declare #Holidays Table (HDate DateTime) -- Table variable to hold holidayes
-- If dates are in reverse order, switch them and set flag
If #StartDate>#EndDate
Begin
Declare #TempDate DateTime=#StartDate
Set #StartDate=#EndDate
Set #EndDate=#TempDate
Set #Reverse=1
End
Else Set #Reverse = 0
-- Get country holidays from table based on the country code (Feel free to remove this or modify as per your DB schema)
-- Insert Into #Holidays(HDate) select DATEADD(month,((LEFT(CAL_ID,4)-1900)*12)+LEFT(RIGHT(CAL_ID,4),2)-1,RIGHT(CAL_ID,2)-1) from B_CALENDAR where CAL_DAY_PK = 263 and HDATE >= DateAdd(dd, DateDiff(dd,0,#StartDate), 0)
Insert Into #Holidays (HDate) Select HolidayDate from V_BUS_HOL Where HolidayDate >= DateAdd(dd, DateDiff(dd,0,#StartDate), 0)
If CAST(#StartDate as TIME) < #StartHour Set #StartDate = CAST(CAST(#StartDate as DATE) as DATETIME) + CAST(#StartHour as DATETIME) -- If Start time is less than start hour, set it to start hour
If CAST(#StartDate as TIME) >= DATEADD(HOUR,1,#EndHour) Set #StartDate = CAST(CAST(DATEADD(DAY,1,#StartDate) as DATE) as DATETIME) + CAST(#StartHour as DATETIME) -- If Start time is after end hour, set it to start hour of next day
If CAST(#EndDate as TIME) >= DATEADD(HOUR,1,#EndHour) Set #EndDate = CAST(CAST(#EndDate as DATE) as DATETIME) + CAST(#EndHour as DATETIME) -- If End time is after end hour, set it to end hour
If CAST(#EndDate as TIME) < #StartHour Set #EndDate = CAST(CAST(DATEADD(DAY,-1,#EndDate) as DATE) as DATETIME) + CAST(#EndHour as DATETIME) -- If End time is before start hour, set it to end hour of previous day
If #StartDate>#EndDate Return 0
-- If Start and End is on same day
If DateDiff(Day,#StartDate,#EndDate) <= 0
Begin
If Datepart(dw,#StartDate)>1 And DATEPART(dw,#StartDate)<7 -- If day is between sunday and saturday
If (Select Count(*) From #Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,#StartDate), 0)) = 0 -- If day is not a holiday
If #EndDate<#StartDate Return 0 Else Set #WorkMin=DATEDIFF(SECOND, #StartDate, #EndDate) -- Calculate difference
Else Return 0
Else Return 0
End
Else Begin
Declare #Partial int=1 -- Set partial day flag
While DateDiff(Day,#StartDate,#EndDate) > 0 -- While start and end days are different
Begin
If Datepart(dw,#StartDate)>1 And DATEPART(dw,#StartDate)<7 -- If this is a weekday
Begin
If (Select Count(*) From #Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,#StartDate), 0)) = 0 -- If this is not a holiday
Begin
If #Partial=1 -- If this is the first iteration, calculate partial time
Begin
Set #WorkMin=#WorkMin + DATEDIFF(SECOND, #StartDate, DateAdd(hour, DATEPART(HOUR,#EndHour), DateDiff(DAY, 0, #StartDate)))
Set #StartDate=DateAdd(hour, DATEPART(HOUR,#StartHour)+24, DateDiff(DAY, 0, #StartDate))
Set #Partial=0
End
Else Begin -- If this is a full day, add full minutes
Set #WorkMin=#WorkMin + (DATEPART(HOUR,#EndHour)-DATEPART(HOUR,#StartHour))*60
Set #StartDate = DATEADD(DD,1,#StartDate)
End
End
Else Set #StartDate = DATEADD(DD,1,#StartDate)
End
Else Set #StartDate = DATEADD(DD,1,#StartDate)
End
If Datepart(dw,#StartDate)>1 And DATEPART(dw,#StartDate)<7 -- If last day is a weekday
If (Select Count(*) From #Holidays Where HDATE=DateAdd(dd, DateDiff(dd,0,#StartDate), 0)) = 0 -- And it is not a holiday
If #Partial=0 Set #WorkMin=#WorkMin + DATEDIFF(SECOND, #StartDate, #EndDate) Else Set #WorkMin=#WorkMin + DATEDIFF(SECOND, DateAdd(hour, DATEPART(HOUR,#StartHour), DateDiff(DAY, 0, #StartDate)), #EndDate)
End
If #Reverse=1 Set #WorkMin=-#WorkMin
Return #WorkMin
End
This one is an old one, however I believe that your problem is datetime/time data types. You didn't state the version of SQL Server you are using but if you have 2008 or above, you may want to adjust your tables and this function to use the datetime2 format. It is more accurate. datetime/smalldatetime both are only accurate to a certain point, then they round which could cause the problem you are looking at.
So I have this code, this is for grabbing data for the last 11 month of sale including the current month, make it a whole year. What do I have to do to change it to grabbing data for the last 12 months plus current month? I know I have to change something on the right(select period)... but not sure
In this one, the left function shows how to get the current year (2014 ) minus 1 to give 2013.. but I don't understand the right function, what does 2 mean?
Thanks
period <= (
SELECT Period
FROM dbo.FiscalDates
WHERE (Date = CONVERT(varchar(10), GETDATE(), 102))) and period >= (
convert(varchar, left((
SELECT Period
FROM dbo.FiscalDates
WHERE (Date = CONVERT(varchar(10), GETDATE(), 102))),4)-1)+'-'+
convert(varchar, right((
SELECT Period
FROM dbo.FiscalDates
WHERE (Date = CONVERT(varchar(10), GETDATE(), 102))),2)))
group by prodnum, period, WhseNum
Whoah buddy I think you may be overcomplicating things here. If you want to get data for the past X number of months then just use DATEADD it's a very useful function.
All you need to do then is
select
YourColumns
FROM YourTable
WHERE YourDate >= DATEADD(MONTH, -13, CAST(GETDATE() AS DATE))
and bam there you go.
DECLARE
#FormYear AS INT,
#FormMonth AS INT,
#ToYear AS INT,
#ToMonth AS INT,
#FromDate AS DATE,
#ToDate AS DATE
SET #FormYear=YEAR(DATEADD(DAY, -365, GETDATE()))
SET #FormMonth=MONTH(DATEADD(DAY, -365, GETDATE()))
SET #ToYear=YEAR(GETDATE())
SET #ToMonth=MONTH(GETDATE())
SET #FromDate= CAST(CAST(#FormMonth AS VARCHAR) +'-'+'01'+ '-' +CAST(#FormYear AS VARCHAR) AS DATE)
SET #ToDate= CAST(CAST(#ToMonth AS VARCHAR) +'-' + '01'+'-' + CAST(#ToYear AS VARCHAR) AS DATE)
After that, just select-
YourDateField Between #FormDate AND #ToDate
I am making a program that auto-runs using windows scheduler. What I'd like to do is set the program to run on the 1st and the 16th of every month. If the program run's on the 1st. I'd like to have the query run for last month... For example if today was the first of august I would want it to run 7/1/12 - 7/31/12. If I run the program on the 16th I want it to run the query for the current month to the 15th. For example if it were 8/16, I would want the program to run the query for 8/1/12 - 8/15/12. What is the best way to accomplish this? Do I go with 2 seperate programs with the query attaching it to the correct date range? One scheduled to run on the first of every month, and one on the 16th? How would I go about getting the date range and the year as it will depend on which month/year it is run... My query is:
SELECT Store_Number, Invoice_Number, Invoice_Date, Extended_Price, Warranty_Amount, Quantity_Sold, Invoice_Detail_Code
FROM Invoice_Detail_Tb
WHERE (Warranty_Amount > 0) AND (Invoice_Date BETWEEN CONVERT(DATETIME, '2012-08-01 00:00:00', 102) AND CONVERT(DATETIME, '2012-08-05 00:00:00', 102))
ORDER BY Store_Number, Invoice_Date
Try 8/1/2012 and 8/16/2012 as the date. It returns the values you want to see:
declare #date datetime = '8/16/2012', #start datetime, #end datetime
if datepart(dd, #date) = 1
begin
set #start = dateadd(mm, -1, #date)
set #end = dateadd(dd, -1, #date)
end
else
begin
set #start = dateadd(dd, -15, #date)
set #end = dateadd(dd, -1, #date)
end
select #start, #end
It would be fairly easy to adapt this so that it would dynamically calculate the correct start and end dates based on any input date -- so you could run it anytime during the month.
This should be simple, let me throw some examples for you.
I truly think this should be one scheduled task, not multiple ones.
It is easier at the end of the day to point and look at one scheduled task (one procedure)
then go digging up multiple procedures just to see what might have wen't wrong.
The task can be scheduled using the SQL Server Agent (under the jobs section). The job can point to one single stored procedure.
In the procedure you can do a simple if else if logic.
IF DAY(GetDate()) = 1
--code here
ELSE IF DAY(GETDATE()) = 16
--code here
DAY(date_expression) returns the day in a datetime column. Ironically there is a MONTH and YEAR function if you for some reason need those. The rest is simple, if you are on the first date of the month then perform the monthly query from months first date till next months first day - 1, this becomes:
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
Otherwise if it hits on the 16th, you can run on the first day until half of the month.
If you have your query in a view, you might use this:
where
Invoice_Date between
(
case
when datepart(dd, getdate()) = 1 then dateadd(mm, -1, getdate())
else dateadd(dd, -15, getdate())
end
)
and
(
case
when datepart(dd, getdate()) = 1 then dateadd(dd, -1, getdate())
else dateadd(dd, -1, getdate())
end
)
UPDATE: Ignoring the time
(I know it looks ugly.)
where
Invoice_Date between
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(mm, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -15, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
and
(
case
when datepart(dd, dateadd(dd, datediff(dd, 0, getdate()), 0)) = 1 then dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
else dateadd(dd, -1, dateadd(dd, datediff(dd, 0, getdate()), 0))
end
)
This is how I usually do something like that. Your stored procedure should look something like this:
declare
#today datetime ,
#dtFrom datetime ,
#dtThru datetime
------------------------------------------------------
-- get the current date, discarding the time component
------------------------------------------------------
set #today = convert(datetime,convert(varchar,current_timestamp,112),112) -- get todays date, discarding the time component
---------------------------------------------------------------------------------------------------------------------------------------------------
-- determine the start/end dates of the query period.
--
-- if the query date (#today) is in the 1st half of the month (1st - 15th), the query range is the entire preceding month
-- if the query date (#today) is in the last half of the month (16 - 31st), the query range is the 1st of the current month up to the current date
---------------------------------------------------------------------------------------------------------------------------------------------------
if ( datepart(day) < 16 )
begin
set #dtThru = dateadd(day, - datepart(day, #today ) , #today ) -- set the end date to the last day of the previous month
set #dtFrom = dateadd(day, 1 - datepart(day, #dtThru ) , #dtThru ) -- set the start date to the first day of the previous month
end
else
begin
set #dtfrom = dateadd(day, 1 - datepart(day, #today) , #today ) -- set the start date to the first day of the current month
set #dtThru = #today
end
----------------------------------------------------------------------------------------------------------------------
-- finally, adjust the start/end times to cover the entire gamut of date/time values for the month
--
-- We don't have to modify #dtFrom at all: we know its time component is 00:00:00.000 already. However, we want
-- #dtThru to have a time component of 23:59:59.997, due to SQL Server's broken way of counting time -- any time value
-- higher than that (e.g., '23:59.59.999') is 'rounded up' to start-of-day (00:00.00.000), the next day. Brilliant!
--
----------------------------------------------------------------------------------------------------------------------
set #dtThru = dateadd(ms, -3 , dateadd(day,1,#dtThru) )
--------------------------------
-- return the data to the caller
--------------------------------
SELECT Store_Number ,
Invoice_Number ,
Invoice_Date ,
Extended_Price ,
Warranty_Amount ,
Quantity_Sold ,
Invoice_Detail_Code
FROM Invoice_Detail_Tb id
WHERE Warranty_Amount > 0
AND Invoice_Date BETWEEN #dtFrom AND #dtThru
ORDER BY Store_Number ,
Invoice_Date
If you aren't using a stored procedure, you can accomplish the same thing with a parameterized query. Compute the two DateTime values needed. Put placeholders in your select statement ('#dtFrom' and '#dtThru'). When you execute the query, pass in your two DateTime values as SqlParameter objects with names matching the placeholders.