Between date condition is not working in SQL Server - sql

I have a data as below,
Trying to run below query but returning 0 rows,
Below query should return highlighted row data as shown above.
Can anybody please explain me, what i'm missing?
select * from Flt_OperativeFlight_SchedulePeriods
where
(
(cast('2018-04-05' as date) between cast(ScheduleStartDate as date) and cast(ScheduleEndDate as date) )
or
(cast('2018-04-11' as date) between cast(ScheduleStartDate as date) and cast(ScheduleEndDate as date) )
)
and CarrierCode='SQ' and FlightNumber='0004'

You could re-write as:
select *
from Flt_OperativeFlight_SchedulePeriods
where CarrierCode='SQ' and FlightNumber='0004' and
(ScheduleStartDate >= '2018-04-05' and ScheduleEndDate <= '2018-04-11')

It happens because
'2018-04-05' < '2018-04-06'
and
'2018-04-11' > '2018-04-10'
As variant maybe it is what you want
select *
from Flt_OperativeFlight_SchedulePeriods
where CarrierCode='SQ' and FlightNumber='0004' and
(
(ScheduleStartDate between '20180405' and '20180411')
or (ScheduleEndDate between '20180405' and '20180411')
)

You can try this
SELECT *
FROM `Flt_OperativeFlight_SchedulePeriods`
WHERE ScheduleStartDate >= '2018-04-05' AND ScheduleEndDate <= '2018-04-11'
AND CarrierCode='SQ' and FlightNumber='0004'

Seems like you want to get overlapping periods, then you need this logic:
start_1 <= end_2 and end_1 >= start_2
For your query:
where
(
cast('2018-04-05' as date) <= cast(ScheduleEndDate as date)
and
cast('2018-04-11' as date) >= cast(ScheduleStartDate as date)
)
Depending on your logic you might have to < or >

Related

group by issue in sql

i'm trying to get in a new column the sessions who are between 08:00 and 18:00. You can see my last CASE in the CTE. For each date there should be a new column "TotalRestrictedSessions" which indicate how many session were on that particular date. If there are none, in this case i have to write 0. I suspect that my problem is when i convert the DATE?
WITH ParkeonCTE
AS
(
SELECT
OccDate = CONVERT(DATE, OC.LocalStartTime),
TotalOccSessions = COUNT(OC.SessionId),
AuthorityId,
TotalOccDuration = ISNULL(SUM(OC.DurationMinutes),0),
TotalNumberOfOverstay = SUM(CAST(OC.IsOverstay AS INT)),
TotalMinOfOverstays = ISNULL(SUM(OC.OverStayDurationMinutes),0),
(CASE
WHEN OC.OspId IS NULL THEN 'OffStreet' ELSE 'OnStreet'
END
) AS ParkingContextType,
(CASE
WHEN CAST(OC.LocalStartTime AS TIME) >= '08:00:00' AND CAST(OC.LocalStartTime AS TIME) <=
'18:00:00'
THEN COUNT(OC.SessionId)
END
) AS TotalRestrictedSessions
FROM Analytics.OccupancySessions AS OC
WHERE OC.AuthorityId IS NOT NULL
GROUP BY CONVERT(DATE,OC.LocalStartTime), OC.AuthorityId,OC.OspId
)
SELECT OC.OccDate,
OC.ParkingContextType,
OC.AuthorityId,
OC.TotalRestrictedSessions,
SUM(OC.TotalOccSessions) AS TotalOccSessions,
AVG(OC.TotalOccDuration) AS AvgOccMinutesDuration, -- wrong
SUM(OC.TotalOccDuration) AS TotalOccDuration,
SUM(OC.TotalNumberOfOverstay) AS TotalNumberOfOverstay,
SUM(OC.TotalMinOfOverstays) AS TotalMinOfOverstays,
CAST(AVG(OC.TotalMinOfOverstays) AS decimal(10,2)) AS AvgMinOfOverstays -- wrong
FROM ParkeonCTE AS OC
GROUP BY OC.OccDate, OC.AuthorityId, OC.ParkingContextType
ORDER BY OC.OccDate DESC
You just need to move your aggregation outside of your CASE expression, called conditional aggregation.
SUM(CASE
WHEN CAST(OC.LocalStartTime AS TIME) >= '08:00:00'
AND CAST(OC.LocalStartTime AS TIME) <= '18:00:00'
THEN 1
ELSE 0
END
) AS TotalRestrictedSessions
Generally, you should include the current query results and your desired results in your question to make it easier to figure out where the issues are.

Compare datetime on select with date only

I want to compare two datetimes based upon if their date is shared.
This works:
SELECT *
FROM XXX
WHERE CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE)
However, I wanted to actually get the result as an extra column:
SELECT
CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE)
, *
FROM XXX
The latter doesn't work as SQLServer complains that the syntax is invalid.
Any suggestions?
The result should be as follows:
LoadDateLAG | LoadDateLEAD | (LoadDateLAG = LoadDateLEAD) [as bit]
I need this functionality to compress a historized table
- remove unnecessary entries (e.g., only keep the last entry per day).
SQL Server 2012+
SELECT IIF(CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE),1,0),* FROM XXX
You can use CASE WHEN:
SELECT
LoadDateLAG, LoadDateLEAD,
CASE WHEN CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE) THEN 1 ELSE 0 END AS isDateEquals
FROM XXX
-- WHERE CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE)
In case you also want to show the DATE values too (instead of DATETIME), you can use the following SELECT:
SELECT
CAST(LoadDateLAG AS DATE) AS LoadDateLAG,
CAST(LoadDateLEAD AS DATE) AS LoadDateLEAD,
CASE WHEN CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE) THEN 1 ELSE 0 END AS isDateEquals
FROM XXX
-- WHERE CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE)
In case you want to show the DATE values (instead of 1 or 0) if equals, you can use the following SELECT:
SELECT
LoadDateLAG, LoadDateLEAD,
CASE WHEN CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE) THEN CAST(LoadDateLAG AS DATE) ELSE NULL END AS equalsDate
FROM XXX
-- WHERE CAST(LoadDateLAG AS DATE) = CAST(LoadDateLEAD AS DATE)
demo: http://sqlfiddle.com/#!18/30b0e/11/1

Hourly gaps in data for a month

Hi Fellow StackOverflowers
I'm really struggling with finding the right approach for this (in my mind) relatively simple Gap-finding problem.
I have a table with hourly datetimes (hourly log file imported to DB).
I need to find the missing hours during a period (lets say april).
So imagine having the following data in DB table [imported_logs]
[2018-04-02 10:00:000]
[2018-04-02 11:00:000]
[2018-04-02 12:00:000]
[2018-04-02 17:00:000]
i need the result for april gap analysis to be:
[ GAP-BEGIN ] [ GAB_END ]
[2018-04-01 00:00:000] [2018-04-02 10:00:000] <-- problem
[2018-04-02 13:00:000] [2018-04-02 17:00:000] <-- can be found using below code
[2018-04-02 18:00:000] [2018-05-01 00:00:000] <-- problem
My problem is mainly finding the start and end ranges, but the following code is helping finding the cap in between available data.
WITH t AS (
SELECT *, rn = ROW_NUMBER() OVER (PARTITION BY zone ORDER BY hourImported)
FROM logsImportedTable
Where hourImported > '2018-04-01' and hourImported < '2018-05-01' and zone = 1
)
SELECT t1.zone, t1.hourImported as GapStart, t2.hourImported as GapEnd
FROM t t1
INNER JOIN t t2 ON t2.zone = t1.zone AND t2.rn = t1.rn + 1
WHERE DATEDIFF(MINUTE, t1.hourImported, t2.hourImported) > 60
which gives me only the result:
[zone] [gap_start ] [gap_end ]
[1 ] [2018-04-02 13:00:00.000] [2018-04-02 17:00:00.000]
So basically if no logs has been imported during april at all the current implemetation would show no missing data at all (kinda wrong)
I'm thinking that i need to somehow add some new datapoints just before beginning and end of the april period to somehow get the query to catch the start and end of the month as missing data?
What would you bright guys/girls do?
/Kind regards
For this situation, just add the initial and end values, if appropriate:
<your query here>
union all
select '2018-04-01 00:00:000', min(lit.hourImported)
from logsImportedTable lit
where lit.hourImported >= '2018-04-01 00:00:00'
having min(lit.hourImported) > '2018-04-01 00:00:00'
union all
select '2018-05-01 00:00:000', max(lit.hourImported)
from logsImportedTable lit
where lit.hourImported <= '2018-05-01 00:00:00'
having max(lit.hourImported) > '2018-05-01 00:00:00';
Ok thx to the great help from #Gordon this is my final solution to the problem. It will give the gaps even if entire month of data is missing and all small gaps within.
DECLARE #zone INT = 1, #currentPeriodStart DATETIME = '2018-01-01',
#currentPeriodEnd DATETIME = '2018-02-01';
WITH t AS (
SELECT *, rn = ROW_NUMBER() over (PARTITION BY zone_id ORDER BY
time_of_file_present)
FROM test
Where time_of_file_present > #currentPeriodStart and time_of_file_present <
#currentPeriodEnd and zone_id = #zone
)
SELECT t1.zone_id, t1.time_of_file_present as gap_start,
t2.time_of_file_present as gap_end
FROM t t1
INNER JOIN t t2 ON t2.zone_id = t1.zone_id AND t2.rn = t1.rn + 1
WHERE DATEDIFF(MINUTE, t1.time_of_file_present, t2.time_of_file_present) >60
union all
select #zone, #currentPeriodStart, min(lit.time_of_file_present)
from test lit
where lit.time_of_file_present >= #currentPeriodStart
having min(lit.time_of_file_present) > #currentPeriodStart and
min(lit.time_of_file_present) < #currentPeriodEnd
union all
select #zone,max(lit.time_of_file_present), #currentPeriodEnd
from test lit
where lit.time_of_file_present <= #currentPeriodEnd
having max(lit.time_of_file_present) < #currentPeriodEnd and
max(lit.time_of_file_present) > #currentPeriodStart
union all
select #zone,#currentPeriodStart, #currentPeriodEnd
from test lit
having max(lit.time_of_file_present) < #currentPeriodStart or
max(lit.time_of_file_present) > #currentPeriodEnd
order by gap_start

Why isn't my nested SQL SELECT INTO statement working?

The basic SELECT INTO statement works, but I need to get the TransactionNumbers in another table where the date in that table is equal to whatever I setup so it the new table doesn't get all the TransactionNumbers. How to do this? Thanks for helping!
query = select * into [bos_primary_db2].dbo.[TenderEntry] from
[bos_primary_db].dbo.[TenderEntry]
where [TenderEntry].TransactionNumber in
(select TransactionNumber
from [bos_primary_db.dbo].[Transaction]
where [Transaction].Date >= '2012-2-2'
and [Transaction].Date < '2012-2-3')
You can try this:
[Transaction].Date BETWEEN '2012-02-02' and '2012-02-03'
You have to cast your String to a date:
where [Transaction].Date >= cast('2012.2.2' as date,102) and [Transaction].Date < cast('2012.2.3' as Date,102 )
Try this :
WHERE
select TransactionNumber
from [bos_primary_db.dbo].[Transaction]
where Convert(VARCHAR, [Transaction].Date,103) >= CONVERT(VARCHAR,'02/02/2012' ,103)
and CONVERT(VARCHAR,[Transaction].Date,103) < CONVERT(VARCHAR,'03/02/2012',103)

CONFLICT WITH "00:00:00" as END_TIME

I have this query:
SELECT `s`.`time` , SUM( s.love ) AS total_love, SUM( s.sad ) AS total_sad, SUM( s.angry ) AS total_angry, SUM( s.happy ) AS total_happy
FROM (`employee_workshift` AS e)
JOIN `workshift` AS w ON `e`.`workshift_uuid` = `w`.`uuid`
JOIN `shift_summary` AS s ON `w`.`uuid` = `s`.`workshift_uuid`
WHERE `s`.`location_uuid` = '81956feb-3fd7-0e84-e9fe-b640434dfad0'
AND `e`.`employee_uuid` = '3866a979-bc5e-56cb-cede-863afc47b8b5'
AND `s`.`workshift_uuid` = '8c9dbd85-18a3-6ca9-e3f3-06eb602b6f38'
AND `s`.`time` >= CAST( '18:00:00' AS TIME )
AND `s`.`time` <= CAST( '00:00:00' AS TIME )
AND `s`.`date` LIKE '%2014-03%'
My problem is it returns "NULL" but when I changed my 'end_time' to "23:59:59", it returned the right data. I've got an idea to pull the hour of both 'start_time' and 'end_time' and then insert it in a loop to get everything between them.
$time_start = 15;
$time_end = 03;
So it should produce: 15,16,17,18,19,20,21,22,23,00,01,02,03
Then I'll compare them all. But this would take a lot of line and effort than just simply using "BETWEEN". Or should I just use "in_array"? Have you encountered this? I hope someone could help. Thanks.
19:00 is certainly bigger then 00:00 - so your approach should not work.
Try using full timestamp (including date) to get all data you need.
Try to use this query. I don't know your data structure so check INNER JOIN between s and s1 tables. The join must be one row to one row - the difference only in date. Date of s1 rows must be earlier on 1 day than s table rows.
SELECT s.time , SUM( s.love ) AS total_love, SUM( s.sad ) AS total_sad, SUM( s.angry ) AS total_angry, SUM( s.happy ) AS total_happy
FROM (employee_workshift AS e)
JOIN workshift AS w ON e.workshift_uuid = w.uuid
JOIN shift_summary AS s ON w.uuid = s.workshift_uuid
JOIN shift_summary AS s1 ON (w.uuid = s.workshift_uuid AND CAST(s.date as DATE)=CAST(s1.date as DATE)+1)
WHERE s.location_uuid = '81956feb-3fd7-0e84-e9fe-b640434dfad0'
AND e.employee_uuid = '3866a979-bc5e-56cb-cede-863afc47b8b5'
AND s.workshift_uuid = '8c9dbd85-18a3-6ca9-e3f3-06eb602b6f38'
AND s1.time >= CAST( '18:00:00' AS TIME )
AND s.time <= CAST( '00:00:00' AS TIME )
AND s.date LIKE '%2014-03%'