How to use Select query with MAX Date? - sql

I am trying to get latest Date from Database.But getting query error on 'Reservation.EntryDate'
Select Rooms.RoomTitle,Rooms.IsReserved,Reservation.CheckInTime,Reservation.CheckOutTime
From Reservation,Rooms
INNER JOIN
(SELECT Reservation.RoomID, MAX(Reservation.EntryDate) AS MaxDateTime
FROM Reservation
GROUP BY Reservation.RoomID) groupedtt
ON Rooms.RoomID = groupedtt.RoomID
AND Reservation.EntryDate = groupedtt.MaxDateTime
What am I doing wrong?

Don't mix implicit and explicit join syntax
Select ro.RoomTitle,
ro.IsReserved,
res.CheckInTime,
res.CheckOutTime
From Reservation res
join Rooms ro ON ro.RoomID = res.RoomID
join
(
SELECT RoomID, MAX(EntryDate) AS MaxDateTime
FROM Reservation
GROUP BY RoomID
) groupedtt ON ro.RoomID = groupedtt.RoomID
AND res.EntryDate = groupedtt.MaxDateTime

Related

Order by on a nested query

Is their a way to order this by the Time column? I am not sure how to do this. The time is the schedule and I just need it to go from the morning to the evening.
Can I just nest another select statement and use that?
Thank you.
SELECT
DoseLevel,
LastName,
FirstName,
DOB,
EMPLID,
Time,
(
SELECT v.ColorCode
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentColorCode,
(
SELECT mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2 ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentManuDesc
FROM
(
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvse.AdminScheduleSlotsEmployeeID,
cd.ABCDocumentationID,
cvss.Time,
cd.ModifyDate AS 'StartTime'
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
WHERE CAST(TIME AS Date) = CAST(GETDATE() AS Date) AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
) dt
First off, there is no need for the derived table dt, as you are not doing any further processing.
Secondly, you can combine the two correlated subqueries into one with an APPLY.
Thirdly, conversions on columns can cause performance issues, so you can change the date check to a half-open interval, converting just GETDATE().
Finally you can add at the end an ORDER BY clause to sort.
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvss.Time,
Parent.ColorCode,
Parent.Description
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
OUTER APPLY
(
SELECT v.ColorCode, mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS Parent
WHERE TIME >= CAST(GETDATE() AS Date) AND TIME < CAST(DATEADD(day, 1, GETDATE()) AS DATE)
AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
ORDER BY TIME
please
declare #tm table (id int identity, timee time(7))
insert into #tm (timee) values ('01:05:45'),
('10:15:18'),
('14:18:59'),
('09:15:10'),
('18:19:21'),
('21:05:17')
this is a default
select * from #tm order by id
this is a, what do you need
select tm.*,
iif(tm.part_time = 1, 'morning', 'evening') m_e from (select
case
when timee between '09:00:00' and '19:00:00' then 1
else 2 end part_time,
*
from #tm) tm
order by part_time, timee

How I can select highest review from a user?

I need to select reviews for product, but unique by user (i.e. one review from user).
With my code, I select all reviews, and I can see few reviews left by one user.
SELECT
tr.reviewText, tr.reviewDate, tr.reviewRating,
u.userName AS userName,
u.userFirstName AS userFirstName, u.userSurname AS userSurname,
u.countryId AS countryId
FROM
tblReviews tr
INNER JOIN
tblOrderProduct op ON op.orderProductId = tr.orderProductId
AND op.productOptionId IN (SELECT productOptionId
FROM tblProductOption
WHERE productSubCuId = 111
AND productOptionActive = 1)
LEFT JOIN
tblOrder o ON o.orderId = op.orderId
LEFT JOIN
tblUser u ON u.userRandomId = o.userRandomId
WHERE
tr.reviewsStatusId = 2
ORDER BY
tr.reviewRating DESC, tr.reviewDate DESC
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
Can I get just one review from each user?
Maybe I need select userId -> group results by userId and select one per group? [I tried to do so, but I didn't succeed :( ]
You can use row_number to number the reviews and select any one like below:
;with per_user_one_review
as
(SELECT tr.reviewText, tr.reviewDate, tr.reviewRating,
u.userName as userName,
u.userFirstName as userFirstName, u.userSurname as userSurname,
u.countryId as countryId, row_number() over (partition by u.userRandomId order by tr.reviewDate desc) rn
FROM tblReviews tr
INNER JOIN tblOrderProduct op
ON op.orderProductId = tr.orderProductId
AND op.productOptionId IN (
SELECT productOptionId FROM tblProductOption
WHERE productSubCuId = 111 AND productOptionActive = 1
)
LEFT JOIN tblOrder o ON o.orderId = op.orderId
LEFT JOIN tblUser u ON u.userRandomId = o.userRandomId
WHERE tr.reviewsStatusId = 2
ORDER BY tr.reviewRating DESC, tr.reviewDate DESC
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY
)
select * from per_user_one_review where rn = 1
It will pick the latest review (reviewDate desc) from the user.
If you need the last review you could use a join with the suquery for max review date grouped by orderProductId
(and as a suggestion you could use a inner join instead of a IN clasue based on a subquery)
select tr.reviewText
, tr.reviewDate
, tr.reviewRating
, u.userName
, u.userFirstName
, u.userSurname
, u.countryId
from tblReviews tr
INNER JOIN (
select max(reviewDate) max_date, orderProductId
from tblReviews
group by orderProductId
) t1 on t1.orderProductId = tr.orderProductId and t1.max_date = tr.reviewDate
INNER JOIN tblOrderProduct op ON op.orderProductId = tr.orderProductId
INNER JOIN (
SELECT productOptionId
FROM tblProductOption
WHERE productSubCuId = 111 AND productOptionActive = 1
) t2 ON op.productOptionId = t2.productOptionId
LEFT JOIN tblOrder o ON o.orderId = op.orderId
LEFT JOIN tblUser u ON u.userRandomId = o.userRandomId
WHERE tr.reviewsStatusId = 2
ORDER BY tr.reviewRating DESC, tr.reviewDate DESC
OFFSET 0 ROWS FETCH NEXT 100 ROWS ONLY

Count with row_number function SQL CTE

I have the below CTEs that work perfectly, but I want to count the "cl.memb_dim_id" by "cl.post_date" but I am not sure how to do that? When adding in the count function I get an error that highlights the ' row number' so I am assuming I cant have both order and group together ????
WITH
DATES AS
(
select to_date('01-jan-2017') as startdate,to_date('02-jan-2017') as enddate
from dual
),
Claims as (select distinct
cl.memb_dim_id,
row_number () over (partition by cl.Claim_number order by cl.post_date desc) as uniquerow,
cl.Claim_number,
cl.post_date,
ct.claim_type,
ap.claim_status_desc,
dc.company_desc,
dff.io_flag_desc,
pr.product_desc,
cl.prov_dim_id,
cl.prov_type_dim_id
from dw.fact_claim cl
inner join dates d
on 1=1
and cl.post_date >= d.startdate
and cl.post_date <= d.enddate
and cl.provider_par_dim_id in ('2')
and cl.processing_status_dim_id = '1'
and cl.company_dim_id in ('581','585','586','589','590','591','588','592','594','601','602','603','606','596','598','597','579','599','578','577','573','574','576','575')
left join dw.DIM_CLAIM_STATUS ap
on cl.claim_status_dim_id = ap.claim_status_dim_id
left join dw.dim_claim_type ct
on cl.claim_type_dim_id = ct.claim_type_dim_id
and cl.claim_type_dim_id in ('1','2','6','7')
left join dw.DIM_COMPANY dc
on cl.company_dim_id = dc.company_dim_id
left join dw.DIM_IO_FLAG dff
on cl.io_flag_dim_id = dff.io_flag_dim_id
left join dw.dim_product pr
on cl.product_dim_id = pr.product_dim_id
)
Select * from claims where uniquerow ='1'
First, does this work?
count(cl.memb_dim_id) over (partition by cl.Claim_number, cl.post_date) as cnt,
Second, it is strange to be using analytic functions with select distinct.

SQL Server Delete Rows from Table leaving the record with the Max CreationDate

I want to delete the older records from the table based on creation date,leaving the latest one
attempted SQL,but did not work.
SELECT *
--DELETE L
FROM ItemPriceListMap L
LEFT JOIN (
SELECT ItemPriceListUID3,MAX(CAST(CreationDate as DATE)) MaxDate
FROM ItemPriceListMap
GROUP BY ItemPriceListUID3
)M ON L.ItemPriceListUID3 = M.ItemPriceListUID3 AND CAST(L.CreationDate as DATE) = M.MaxDate
WHERE M.ItemPriceListUID3 IS NULL
The view of the mapping
SELECT I.Description,ipl.UnitListPrice1,iplmp.VatMRP,iplmp.CreationDate FROM ItemPriceListMap iplmp
INNER JOIN ItemPriceList ipl ON iplmp.ItemPriceListUID3 = ipl.UID
INNER JOIN Item i ON ipl.ItemUID = i.UID
ORDER BY I.Description,iplmp.CreationDate
EDIT:
More Sample Data
Using this SQL
SELECT I.Description,iplmp.ItemPriceListUID3,iplmp.CreationDate FROM ItemPriceListMap iplmp
INNER JOIN ItemPriceList ipl ON iplmp.ItemPriceListUID3 = ipl.UID
INNER JOIN Item i ON ipl.ItemUID = i.UID
ORDER BY I.Description,iplmp.CreationDate
so after I execute the delete command the highlighted row should be left in the table(yellow),highlighted in blue is the same Item
TRY THIS: You can use your own query by doing some simple changes as below, you have to join as <> with the max date so it will not delete that record, only delete others which matches ItemPriceListUID3 and <> MaxDate
SELECT *
--DELETE L
FROM ItemPriceListMap L
INNER JOIN (SELECT MAX(CAST(CreationDate as DATE)) MaxDate
FROM ItemPriceListMap
) M ON CAST(L.CreationDate as DATE) <> M.MaxDate
Try this :
DELETE L
FROM ItemPriceListMap L
WHERE CreationDate <> (SELECT MAX(CreationDate) MaxDate
FROM ItemPriceListMap LL
WHERE L.ItemPriceListUID3 = LL.ItemPriceListUID3)
Note : Take backup of your data first.
Use a CTE and a row_number
with CTE as
(
select a1.*, row_number() over(
partition by ItemPriceListUID3 -- remove this if you don't need the grouping
order by CreationDate desc) as R_ORD
from ItemPriceListMap a1
)
delete
from CTE
where R_ORD > 1

use field in sql join where clause

I am trying to write a crystal report using a sql statement because it runs much much faster. But I am having trouble with some of the linkings. I need to use the result of a link for criteria in subsequent links.
Ok, here is a sample of what my statement looks like:
(The lines marked with ** are the lines in question)
SELECT
Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT
Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM
Pub.Part
) AS Part
LEFT OUTER JOIN (
SELECT
Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM
Pub.Customer
WHERE
Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN (
SELECT
Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty
FROM
Pub.OrderHed JOIN Pub.OrderDtl ON
Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE
**Pub.OrderHed.CustNum = Cust.CustNum AND**
**Pub.OrderDtl.PartNum = Part.PartNum AND**
YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY
Pub.OrderDtl.PartNum
) AS YTD ON Part.PartNum = YTD.PartNum
Now, I get an error that says:
Part.PartNum cannot be found or is not specified for the query.
I get the same error for Cust.CustNum. Will you help me figure out what I am doing wrong? Thanks!
The problem is that you are using one of the aliases, inside of a sub-query which you cannot do. You will have to do something similar to this:
SELECT Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM Pub.Part
) AS Part
LEFT OUTER JOIN
(
SELECT Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM Pub.Customer
WHERE Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN
(
SELECT Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty,
Pub.OrderHed.CustNum
FROM Pub.OrderHed
JOIN Pub.OrderDtl
ON Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY Pub.OrderDtl.PartNum, Pub.OrderHed.CustNum
) AS YTD
ON Part.PartNum = YTD.PartNum
AND Cust.CustNum = YTD.CustNum
Looking at your query more, you can actually get rid of two of the subqueries:
SELECT Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM Pub.Part Part
LEFT OUTER JOIN Pub.Customer Cust
ON Part.CustID = Cust.CustID
AND Cust.CustID = '1038'
LEFT OUTER JOIN
(
SELECT d.PartNum,
Sum(d.OrderQty) AS Qty,
h.CustNum
FROM Pub.OrderHed h
JOIN Pub.OrderDtl d
ON h.OrderNum = d.OrderNum
WHERE YEAR(h.OrderDate)=YEAR(CURDATE())
GROUP BY d.PartNum
) AS YTD
ON Part.PartNum = YTD.PartNum
AND Cust.CustNum = YTD.CustNum
This is because you can't access a parent sub-query (cust, part) within another sub-query (YTD)
However, the solution is easy in your case, filter in the ON clause instead:
SELECT
Part.PartNum,
Cust.CustNum,
Cust.CustID,
YTD.Qty
FROM
(
SELECT
Pub.Part.PartNum,
Pub.Part.UserChar1 AS CustID
FROM
Pub.Part
) AS Part
LEFT OUTER JOIN (
SELECT
Pub.Customer.CustID,
Pub.Customer.CustNum,
Pub.Customer.Name
FROM
Pub.Customer
WHERE
Pub.Customer.CustID = '1038'
) AS Cust
ON Part.CustID = Cust.CustID
LEFT OUTER JOIN (
SELECT
Pub.OrderDtl.PartNum,
Sum(Pub.OrderDtl.OrderQty) AS Qty,
Pub.OrderHed.CustNum
FROM
Pub.OrderHed JOIN Pub.OrderDtl ON
Pub.OrderHed.OrderNum = Pub.OrderDtl.OrderNum
WHERE
YEAR(Pub.OrderHed.OrderDate)=YEAR(CURDATE())
GROUP BY
Pub.OrderDtl.PartNum
) AS YTD ON Part.PartNum = YTD.PartNum AND Cust.CustNum = YTD.CustNum