ReportDateTime EuId1 EuId2
2020-02-01 1:00 1576 Null
2020-02-01 1:00 Null 1579
2020-02-01 2:00 Null 1573
2020-02-01 2:00 1566 Null
This is what I have and this is what I want...
ReportDateTime EuId1 EuId2
2020-02-01 1:00 1576 1579
2020-02-01 2:00 1566 1573
Here is my code...
;WITH cteEq AS (
SELECT e.EntHID, e.EntCode, e.EntName
FROM cfEntity fac (NOLOCK)
JOIN cfEntityRelation er (NOLOCK) ON fac.EntHID = er.EntParentHID AND er.EntRelEffEnd = '12/31/2078'
JOIN cfEntity e (NOLOCK) ON er.EntChildHID = e.EntHID AND e.EntTypeTID = -200020
WHERE e.EntHID IN (SELECT ea.EaHID FROM cfEntityAttribute ea (NOLOCK) WHERE ea.EaKey = 'AirPermitXref_Diesel')
)
SELECT
ReportDateTime = a.EqReportDate
, EuId1 = CASE
WHEN EntName LIKE '%EU1%' THEN a.EqPwr
END
, EuId2 = CASE
WHEN EntName LIKE '%EU2%' THEN a.EqPwr
END
FROM eqHourlyAir a (NOLOCK)
JOIN cteEq e (NOLOCK) ON a.EqHID = e.EntHID
OUTER APPLY (
SELECT ad.EqHID, ad.EqReportDate, ad.EqRunTime
FROM eqHourlyAir ad (NOLOCK)
LEFT JOIN cfEntityAttribute ea (NOLOCK) ON ad.EqHID = CAST(ea.EaValue AS INT) AND ea.EaKey = 'AirPermitXref_DWI'
WHERE ea.EaHID = a.EqHID
AND ad.EqReportDate = a.EqReportDate
) dwi
OUTER APPLY (
SELECT ad.EqHID, ad.EqReportDate, ad.EqRunTime
FROM eqHourlyAir ad (NOLOCK)
LEFT JOIN cfEntityAttribute ea (NOLOCK) ON ad.EqHID = CAST(ea.EaValue AS INT) AND ea.EaKey = 'AirPermitXref_Diesel'
WHERE ea.EaHID = a.EqHID
AND ad.EqReportDate = a.EqReportDate
) dsl
WHERE CAST(a.EqReportDate AS DATE) >= #StartDate AND CAST(a.EqReportDate AS DATE) <= #EndDate
ORDER BY a.EqReportDate
using nolock hint is not the best idea !
if you have one null value and only one non value for each reportingdate you can grooup by ReportDateTime and get the max value :
...
SELECT
ReportDateTime = a.EqReportDate,
EuId1 = MAX(CASE WHEN EntName LIKE '%EU1%' THEN a.EqPwr END),
EuId2 = MAX(CASE WHEN EntName LIKE '%EU2%' THEN a.EqPwr END)
FROM
{...}
WHERE
CAST(a.EqReportDate AS DATE) >= #StartDate
AND CAST(a.EqReportDate AS DATE) <= #EndDate
GROUP BY a.EqReportDate
ORDER BY
a.EqReportDate
From you sample data it's very easy to select your desired result as below:
select ReportDateTime ,max(EuId1) EuId1,max(EuId2) EuId2 from
(select * from table1 join table2 on .... )t
group by ReportDateTime
But your query indicates that there is more to the story. Please share some more information.
Related
I have two tables:
CLIENTS
ID NAME
001 John
002 Sara
CLIENT_STATUS
CLIENT_ID STATUS DATE
001 3 2018-01-02
001 2 2018-01-04
002 2 2018-01-02
002 1 2018-01-03
I want to filter by status = 1 and I just want the most recent date within the specified time frame.
I have this so far:
DECLARE
#StartDate DATE,
#EndDate DATE
SET #StartDate = '2016-07-01'
SET #EndDate = '2018-06-30'
SELECT
c.NAME
, c.ID
, cs.STATUS
FROM CLIENT c
LEFT JOIN (
SELECT cs.CLIENT_ID, cs.DATE
FROM CLIENT_STATUS
WHERE STATUS = 1 AND h.DATE BETWEEN #StartDate AND #EndDate
) AS hst ON hst.CLIENT_ID = c.ID
Only that doesn't Order by the most recent date.
Please note this is part of a larger query.
Left (or INNER) join with a sub-query that has row numbers:
SELECT *
FROM CLIENTS
LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY CLIENT_ID ORDER BY DATE DESC) AS rn
FROM CLIENT_STATUS
WHERE STATUS = 1
) RECENT_STATUS ON CLIENTS.ID = RECENT_STATUS.CLIENT_ID AND RECENT_STATUS.rn = 1
You can use row_number() function :
SELECT TOP (1) WITH TIES c.ID, c.NAME, cs.DATE
FROM CLIENT c INNER JOIN
CLIENT_STATUS cs
ON cs.CLIENT_ID = c.ID
WHERE cs.STATUS = 1 AND cs.DATE >= #StartDate AND cs.DATE <= #EndDate
ORDER BY ROW_NUMBER() OVER (PARTITION BY c.ID ORDER BY cs.DATE DESC);
I’m looking to join two tables that do not have a common data point, but common value (date). I want a table that lists the date and total number of hired/terminated employees on that day. Example is below:
Table 1
Hire Date Employee Number Employee Name
--------------------------------------------
5/5/2018 10078 Joe
5/5/2018 10077 Adam
5/5/2018 10078 Steve
5/8/2018 10079 Jane
5/8/2018 10080 Mary
Table 2
Termination Date Employee Number Employee Name
----------------------------------------------------
5/5/2018 10010 Tony
5/6/2018 10025 Jonathan
5/6/2018 10035 Mark
5/8/2018 10052 Chris
5/9/2018 10037 Sam
Desired result:
Date Total Hired Total Terminated
--------------------------------------
5/5/2018 3 1
5/6/2018 0 2
5/7/2018 0 0
5/8/2018 2 1
5/9/2018 0 1
Getting the total count is easy, just unsure as the best approach from the standpoint of "adding" a date column
If you need all dates within some window then you need to join the data to a calendar. You can then left join and sum flags for data points.
DECLARE #StartDate DATETIME = (SELECT MIN(ActionDate) FROM(SELECT ActionDate = MIN(HireDate) FROM Table1 UNION SELECT ActionDate = MIN(TerminationDate) FROM Table2)AS X)
DECLARE #EndDate DATETIME = (SELECT MAX(ActionDate) FROM(SELECT ActionDate = MAX(HireDate) FROM Table1 UNION SELECT ActionDate = MAX(TerminationDate) FROM Table2)AS X)
;WITH AllDates AS
(
SELECT CalendarDate=#StartDate
UNION ALL
SELECT DATEADD(DAY, 1, CalendarDate)
FROM AllDates
WHERE DATEADD(DAY, 1, CalendarDate) <= #EndDate
)
SELECT
CalendarDate,
TotalHired = SUM(CASE WHEN H.HireDate IS NULL THEN NULL ELSE 1 END),
TotalTerminated = SUM(CASE WHEN T.TerminationDate IS NULL THEN NULL ELSE 1 END)
FROM
AllDates D
LEFT OUTER JOIN Table1 H ON H.HireDate = D.CalendarDate
LEFT OUTER JOIN Table2 T ON T.TerminationDate = D.CalendarDate
/* If you only want dates with data points then uncomment out the where clause
WHERE
NOT (H.HireDate IS NULL AND T.TerminationDate IS NULL)
*/
GROUP BY
CalendarDate
I would do this with a union all and aggregations:
select dte, sum(is_hired) as num_hired, sum(is_termed) as num_termed
from (select hiredate as dte, 1 as is_hired, 0 as is_termed from table1
union all
select terminationdate, 0 as is_hired, 1 as is_termed from table2
) ht
group by dte
order by dte;
This does not include the "missing" dates. If you want those, a calendar or recursive CTE works. For instance:
with ht as (
select dte, sum(is_hired) as num_hired, sum(is_termed) as num_termed
from (select hiredate as dte, 1 as is_hired, 0 as is_termed from table1
union all
select terminationdate, 0 as is_hired, 1 as is_termed from table2
) ht
group by dte
),
d as (
select min(dte) as dte, max(dte) as max_dte)
from ht
union all
select dateadd(day, 1, dte), max_dte
from d
where dte < max_dte
)
select d.dte, coalesce(ht.num_hired, 0) as num_hired, coalesce(ht.num_termed) as num_termed
from d left join
ht
on d.dte = ht.dte
order by dte;
Try this one
SELECT ISNULL(a.THE_DATE, b.THE_DATE) as Date,
ISNULL(a.Total_Hire,0) as Total_Hire,
ISNULL (b.Total_Terminate,0) as Total_terminate
FROM (SELECT Hire_date as the_date, COUNT(1) as Total_Hire
FROM TABLE_HIRE GROUP BY HIRE_DATE) a
FULL OUTER JOIN (SELECT Termination_Date as the_date, COUNT(1) as Total_Terminate
FROM TABLE_TERMINATE GROUP BY HIRE_DATE) a
ON a.the_date = b.the_date
I have table1 in this data is
ID Name StartDate EndDate
1 Paris 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
2 UK 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
3 France 2014-02-01 00:00:00.000 2014-02-28 23:59:59.000
and sp is
ALTER procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE CAST(StartDate as date)>= CAST(#fromdate as date) and CAST(EndDate as date)<= CAST(#todate as date)
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE CAST(RU.StartDate as date)>= CAST(#fromdate as date) and CAST(RU.EndDate as date)<= CAST(#todate as date) and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed ) S GROUP BY s.RegNo, s.Name) Q
from that sp when i enter parameters DATA IS
[spdata] '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000', 'pARIS'
Name No CAR Tin Cake Flow Unit total Speed SF
John 412 0 0 12 0 5 17 82 60
Mike 48 2 1 5 1 3 9 160 464
ACNme 438 0 1 5 2 3 11 10 264
XYZ 248 0 1 5 3 3 12 60 244
now i want when i change time '2016-07-01 00:00:00.000', '2016-07-31 23:59:59.000',
like this
'2016-07-01 02:02:00.000', '2016-07-31 12:59:59.000',
then records also reflect on this time means according to date plus time data will be display
Don't cast your StartDate , EndDate , #fromdate , #todate as Date.
`Alter procedure [dbo].[spdata]
#fromdate datetime,
#todate datetime,
#Region varchar(50)
as
Select (Select Sum(Convert(int,SF)) from RVU inner dbo.VI vh on RVU.FID = vh.FID WHERE vh.No = Q.No and ID in (
Select ID from RU WHERE StartDate >= #fromdate and EndDate <=#todate
)) as SF
from (
Select
S.Name,
S.No,
SUM(Case when s.Vme='Car' then total else 0 end) as CAR,
SUM(Case when s.Vme='Tin' then total else 0 end) as Tin,
SUM(Case when s.Vme='Cake' then total else 0 end) as Cake,
SUM(Case when s.Vme='Flow' then total else 0 end) as Flow,
SUM(Case when s.Vme='Unit' then total else 0 end) as Unit,
SUM(total) total ,
MAX(S.Speed) Speed
from (
Select vh.Name as Name,vh.No as No,VV.Vame,count(VV.Vme) as total, RV.SF as MA,
RV.Speed from VVU VV inner join RVU RV on VV.MID=RV.ID inner join RU RU on RV.ID=RU.ID
left join dbo.VI vh on RV.FID = vh.FID WHERE RU.StartDate >= #fromdate and RU.EndDate <= #todate and
RU.Name_C= #Name_C AND Vme <> '' Group By vh.Name, vh.No, VV.Vme, RV.SF,
RV.Speed
) S GROUP BY s.RegNo, s.Name) Q`
I have the following query (SQL Server):
select a.Booking_Type, b.Unit_Code, a.Start_Date, a.End_Date
from Booking a
inner join Property b
on a.Property_ID = b.Property_ID
where a.Agency_ID = 1020 and
b.IsEnabled = 1 and
a.Hold_Agreement_Signed is null and
(convert(varchar(10), a.Start_Date, 102) = convert(varchar(10), getdate(), 102) or convert(varchar(10), a.End_Date, 102) = convert(varchar(10), getdate()-1, 102))
my results from this query look like:
Booking_Type Unit_Code Start_Date End_Date
0 448 2014-09-22 00:00:00 2014-09-28 00:00:00
0 448 2014-09-21 05:00:00 2014-09-21 05:00:00
0 K187 2014-09-19 00:00:00 2014-09-21 00:00:00
0 K187 2014-09-18 00:00:00 2014-09-21 00:00:00
What I am looking to get is a single row with Unit_Code = 448 because it has a row with a Start_Date of today and a row with an End_Date of yesterday (there was a checkout yesterday and a checkin today).
How do I modify my query to obtain this?
you will need to join a second instance of Booking:
select a.Booking_Type, b.Unit_Code, a.Start_Date, a.End_Date
from Booking inner join Property b a.Property_ID = b.Property_ID
inner join Booking b1
on a.Property_ID = b1.Property_ID
and convert your where condition from OR to AND
... convert(varchar(10), a.Start_Date, 102) = convert(varchar(10), getdate(), 102)
**AND**
convert(varchar(10), **B1**.End_Date, 102) = convert(varchar(10), getdate()-1, 102))
If you just want to return the Unit_Code that meets your date criteria, you should use HAVING:
select b.Unit_Code
from Booking a
inner join Property b
on a.Property_ID = b.Property_ID
where a.Agency_ID = 1020
and b.IsEnabled = 1
and a.Hold_Agreement_Signed is null
GROUP BY b.Unit_Code
HAVING MAX(CASE WHEN CAST(a.Start_Date AS DATE) = CAST(GETDATE() AS DATE) THEN 1 END) = 1
AND MAX(CASE WHEN CAST(a.End_Date AS DATE) = CAST(GETDATE()-1 AS DATE) THEN 1 END) = 1
SELECT USERINFO.UserID
,SUM(DATEDIFF(DAY, DateFrom, DateTo) + 1) AS total_leave_days
FROM USERINFO
INNER JOIN CHECKINOUT ON USERINFO.USERID = CHECKINOUT.USERID
LEFT OUTER JOIN DEPARTMENTS ON DEPARTMENTS.DEPTID = USERINFO.DEFAULTDEPTID
left join AuthLeave on AuthLeave.userid = userinfo.userid
and AuthLeave.DATEFROM>='2014-01-01'
and AuthLeave.DATETO<='2014-06-30'
WHERE (CHECKINOUT.CHECKTIME >= '2014-01-01')
AND (CHECKINOUT.CHECKTIME <= '2014-06-30')
AND DEPARTMENTS.DEPTNAME = 'GEN/SUP-TBL'
GROUP BY USERINFO.UserID
here is my code from this i can get below out put
UserID total_leave_days
35 NULL
350 NULL
30 NULL
10 735
167 NULL
21 920
1 621
224 NULL
so it is not correct my Authleave table data is below:
UserID DATEFROM DATETO
1 2014-03-10 2014-03-15
10 2014-05-28 2014-05-29
21 2014-05-27 2014-05-27
1 2014-04-10 2014-04-15
from now i want output like below:
UserID total_leave_days
35 NULL
350 NULL
30 NULL
10 2
167 NULL
21 1
1 12
224 NULL
so how can i do this ?
Can you try This SQL
SELECT U.[UserID],
C.[Leave]
FROM [USERINFO] U
LEFT JOIN (SELECT [UserID],
SUM(DATEDIFF(DAY,[DATEFROM],[DATETO])) [Leave]
FROM [CHECKINOUT]
WHERE [CHECKTIME] >= '2014-01-01' AND [CHECKTIME] <= '2014-06-30'
GROUP BY [UserID]
) C ON U.[USERID] = C.[USERID]
LEFT JOIN [DEPARTMENTS] D ON D.[DEPTID] = U.[DEFAULTDEPTID]
LEFT JOIN [AuthLeave] A on A.[userid] = U.[userid]
WHERE D.[DEPTNAME] = 'GEN/SUP-TBL'
enter code here
Edit:
See the below SQL, I got a bit confused by Table Names.
SELECT U.[UserID],
L.[Leave]
FROM [USERINFO] U
JOIN CHECKINOUT C ON U.USERID = C.USERID
LEFT JOIN [DEPARTMENTS] D ON D.[DEPTID] = U.[DEFAULTDEPTID]
LEFT JOIN (SELECT [UserID],
SUM(DATEDIFF(DAY,[DATEFROM],[DATETO])) [Leave]
FROM [AuthLeave]
WHERE [DATEFROM] >= '2014-01-01' AND [DATETO] <= '2014-06-30'
GROUP BY [UserID]
) L ON L.[UserID] =U.[UserID]
WHERE D.[DEPTNAME] = 'GEN/SUP-TBL'
AND C.[CHECKTIME] >= '2014-01-01' AND C.[CHECKTIME] <= '2014-06-30'