Select only observations with a date more recent than the 30/6/2021 (dd/mm/yyyy) - sql

I have the following code:
Select Tbl.Fromdate, Tbl.Por, Tbl.Porname, Tbl.Bmref3
From(
Select
To_Char(P.Fromdate, 'dd-mm-yyyy') As Fromdate, P.Por, P.Porname, W.Bmref3,
, RANK() OVER (PARTITION BY P.Por ORDER BY P.fromdate DESC) AS rank
From Tmsdat.Climandatecomps W
Inner Join Tmsdat.Portfolios P On (W.Porik = P.Porik)
Where 1=1
) Tbl
Where 1=1
And Tbl.Rank = 1
;
However, I wish to select only the observations that have a Fromdate more recent than the June 30, 2021. I tried to add Tbl.Fromdate> '30-06-2021' to the WHERE clause, but I did not receive the desired results.
Do you have any suggestions?
Thank you in advance.
Best regards,

You would put the condition in the inner query:
Select To_Char(P.Fromdate, 'dd-mm-yyyy') As Fromdate, P.Por, P.Porname, W.Bmref3,
RANK() OVER (PARTITION BY P.Por ORDER BY P.fromdate DESC) AS rank
From Tmsdat.Climandatecomps W inner join
Tmsdat.Portfolios P
On (W.Porik = P.Porik)
Where p.FromDate > date '2021-06-30'

Related

SQLite Getting multiple results with LIMIT 1

I have the following problem.
Part of a task is to determine the visitor(s) with the most money spent between 2000 and 2020.
It just looks like this.
SELECT UserEMail FROM Visitor
JOIN Ticket ON Visitor.UserEMail = Ticket.VisitorUserEMail
where Ticket.Date> date('2000-01-01') AND Ticket.Date < date ('2020-12-31')
Group by Ticket.VisitorUserEMail
order by SUM(Price) DESC;
Is it possible to output more than one person if both have spent the same amount?
Use rank():
SELECT VisitorUserEMail
FROM (SELECT VisitorUserEMail, SUM(PRICE) as sum_price,
RANK() OVER (ORDER BY SUM(Price) DESC) as seqnum
FROM Ticket t
WHERE t.Date >= date('2000-01-01') AND Ticket.Date <= date('2021-01-01')
GROUP BY t.VisitorUserEMail
) t
WHERE seqnum = 1;
Note: You don't need the JOIN, assuming that ticket buyers are actually visitors. If that assumption is not true, then use the JOIN.
Use a CTE that returns all the total prices for each email and with NOT EXISTS select the rows with the top total price:
WITH cte AS (
SELECT VisitorUserEMail, SUM(Price) SumPrice
FROM Ticket
WHERE Date >= '2000-01-01' AND Date <= '2020-12-31'
GROUP BY VisitorUserEMail
)
SELECT c.VisitorUserEMail
FROM cte c
WHERE NOT EXISTS (
SELECT 1 FROM cte
WHERE SumPrice > c.SumPrice
)
or:
WITH cte AS (
SELECT VisitorUserEMail, SUM(Price) SumPrice
FROM Ticket
WHERE Date >= '2000-01-01' AND Date <= '2020-12-31'
GROUP BY VisitorUserEMail
)
SELECT VisitorUserEMail
FROM cte
WHERE SumPrice = (SELECT MAX(SumPrice) FROM cte)
Note that you don't need the function date() because the result of date('2000-01-01') is '2000-01-01'.
Also I think that the conditions in the WHERE clause should include the =, right?

How do i find the most frequent facility in SQL

Currently, my table comprises two - Facility table Facility table and Booking table Booking table
How do I list the most used popular facility used by the members in 2017?
Year has to be 2017
The most frequent facility used each month
After trying to do
This is what I have now
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
ORDER BY
MONTH(b.BookingStartDateTime) DESC
I believe this should work.
select Month, 'Most Frequent' from (
select *, row_number() over (partition by Month order by Frequency desc) rnk from (
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT',
count(*) as 'Frequency'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
) rnk
) a where rnk = 1
order by month desc
Added a non-window function version, you need to do inner joins or where exists method to get your result
with rnk as (
SELECT
MONTH(b.BookingStartDateTime) AS 'Month',
f.FacilityDesc AS 'MOST FREQUENT',
count(*) as 'Frequency'
FROM
Booking b
INNER JOIN
Facility f ON b.FacilityID = f.FacilityID
WHERE
YEAR(b.BookingStartDateTime) = 2017
GROUP BY
MONTH(b.BookingStartDateTime), f.FacilityDesc
)
select Month, 'Most Frequent' from rnk where exists(
select Month, freq from (
select Month, max(Frequency) freq from rnk group by Month
) a where a.Month = rnk.Month and a.freq = rnk.Frequency
)
order by Month desc

oracle window functions

Could someone help me out with this query:
SELECT SUM(summa), name,
TO_CHAR(invoice_date, 'YYYY/mm')
OVER (PARTITON EXTRACT(MONTH FROM i.invoice_date, c.name)
FROM invoice i, customer c
WHERE i.customer_id = c.id
AND months_between(sysdate, invoice_date) = 3
AND rownum < 11 GROUP BY invoice_date, name
ORDER BY SUM(SUMMA) DESC;
Supposed to get the first ten rows from last three months, grouped by month and ordered by sum.
Thanks.
First, use proper explicit join syntax. Second, you need row_number():
SELECT t.*
FROM (SELECT SUM(summa) as sumsumma, name,
TO_CHAR(invoice_date, 'YYYY/mm') as yyyymm,
ROW_NUMBER() OVER (PARTITION BY TO_CHAR(invoice_date, 'YYYY/mm')
ORDER BY SUM(summa) DESC
) as seqnum
FROM invoice i JOIN
customer c
ON i.customer_id = c.id
WHERE months_between(sysdate, invoice_date) = 3
GROUP BY invoice_date, name
) t
WHERE seqnum <= 10
ORDER BY sumsumma DESC;

SQL Server 2008 calculating data difference when we have only one date column

I have a date column Order_date and I am looking for ways to calculate the date difference between customer last order date and his recent previous ( previous form last) order_date ....
Example
Customer : 1, 2 , 1 , 1
Order_date: 01/02/2007, 02/01/2015, 06/02/2014, 04/02/2015
As you can see customer # 1 has three orders.
I want to know the date difference between his recent order date (04/02/2015) and his recent previous (06/02/2014).
For SQL Server 2012 & 2014 you could use LAG with a DATEDIFF to see the number of days between them.
For older versions, a CTE would probably be your best bet:
;WITH CTE AS
(
SELECT CustomerID,
Order_Date,
rn = ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY Order_Date DESC)
)
SELECT c1.CustomerID,
DATEDIFF(d, c1.Order_Date, c2.Order_Date)
FROM CTE c1
INNER JOIN CTE c2 ON c2.rn = c1.rn + 1
In SQL Server 2012+, you can use lag() to get the difference between any two dates:
select t.*,
datediff(day, lag(order_date) over (partition by customer order by order_date),
order_date) as days_dff
from table t;
If you have an older version, you can do something similar with correlated subqueries or outer apply.
EDIT:
If you just want the difference between the two most recent dates, use conditional aggregation instead:
select customer,
datediff(day, max(case when seqnum = 2 then order_date end),
max(case when seqnum = 1 then order_date end)
) as MostRecentDiff
from (select t.*,
row_number() over (partition by customer order by order_date desc) as seqnum
from table t
) t
group by customer;
If you're using SQL Server 2008 or later, you can try CROSS APPLY.
SELECT [customers].[customer_id], DATEDIFF(DAY, MIN([recent_orders].[order_date]), MAX([recent_orders].[order_date])) AS [elapsed]
FROM [customers]
CROSS APPLY (
SELECT TOP 2 [order_date]
FROM [orders]
WHERE ([orders].[customer_id] = [customers].[customer_id])
) [recent_orders]
GROUP BY [customers].[customer_id]
SELECT DATEDIFF(DAY, Y.PrevLastOrderDate, Y.LastOrderDate) AS PreviousDays
FROM
(
SELECT X.LastOrderDate
, (SELECT MAX(OrderDate) FROM dbo.Orders SO WHERE SO.CustomerID=1 AND SO.OrderDate < X.LastOrderDate) AS PrevLastOrderDate
FROM
(
select MAX(OrderDate) AS LastOrderDate
FROM dbo.Orders O
WHERE O.CustomerID=1
)X
)Y
drop table #Invoices
create table #Invoices ( OrderId int , OrderDate datetime )
insert into #Invoices (OrderId , OrderDate )
select 101, '01/01/2001' UNION ALL Select 202, '02/02/2002' UNION ALL Select 303, '03/03/2003'
UNION ALL Select 808, '08/08/2008' UNION ALL Select 909, '09/09/2009'
;
WITH
MyCTE /* http://technet.microsoft.com/en-us/library/ms175972.aspx */
( OrderId,OrderDate,ROWID) AS
(
SELECT
OrderId,OrderDate
, ROW_NUMBER() OVER ( ORDER BY OrderDate ) as ROWID
FROM
#Invoices inv
)
SELECT
OrderId,OrderDate
,(Select Max(OrderDate) from MyCTE innerAlias where innerAlias.ROWID = (outerAlias.ROWID-1) ) as PreviousOrderDate
,
[MyDiff] =
CASE
WHEN (Select Max(OrderDate) from MyCTE innerAlias where innerAlias.ROWID = (outerAlias.ROWID-1) ) iS NULL then 0
ELSE DATEDIFF (mm, OrderDate , (Select Max(OrderDate) from MyCTE innerAlias where innerAlias.ROWID = (outerAlias.ROWID-1) ) )
END
, ROWIDMINUSONE = (ROWID-1)
, ROWID as ROWID_SHOWN_FOR_KICKS , OrderDate as OrderDateASecondTimeForConvenience
FROM
MyCTE outerAlias
ORDER BY outerAlias.OrderDate Desc , OrderId

How to pull the whole row which has the latest date in SQL?

I’m trying to select the pair of product – distribution center attached with the most recent order (based on order date). For one order I can have multiple products, but the whole order will be shipped from one specific distribution center.
How do I select the specific product-distribution center attached with the latest order?
My structure is basically like this:
data.orderdetail table has ordernum, orderdate, distributioncenter
I tried to pull like this, but it doesn’t give me the desired result. I’m using sql server 2008:
SELECT DISTINCT y.OrderNum, y.Product, y.DistributionCenter
, CAST(y.OrderDate AS DATE) AS Orderdate
FROM (SELECT OrderNum, MAX(CAST(Orderdate AS date)) AS orderdate
FROM data.OrderDetail
GROUP BY OrderNum) AS x
INNER JOIN data.OrderDetail AS y
ON y.OrderNum = x.OrderNum
It looks as if you need one more clause in your join Condition
You've got
ON y.OrderNum = x.OrderNum
Which will return all the orders that match the Order number in the subquery
But you'll need
ON y.OrderNum = x.OrderNum
AND y.OrderDate = x.orderdate
Which will return all the orders that match the Order number in the subquery and the maximum date for that order number
SELECT DISTINCT
y.OrderNum,
y.Product,
y.DistributionCenter,
CAST(y.OrderDate AS DATE) AS Orderdate
FROM (
SELECT
OrderNum,
MAX(CAST(Orderdate AS date)) AS orderdate
FROM data.OrderDetail
GROUP BY OrderNum
) AS x
INNER JOIN
data.OrderDetail AS y
ON y.OrderNum = x.OrderNum
AND y.OrderDate = x.orderdate
I believe what you are looking for is row_number. This will partition your result set by OrderNum then rank the sets by the OrderDate. You can then filter off the extra rows in another where clause.
select result.*,
CAST(result.OrderDate as date) as Orderdate,
from (
select y.*,
row_number() over (
partition by y.OrderNum order by CAST(y.OrderDate as date) desc
) rank_
from (
select OrderNum,
MAX(CAST(Orderdate as date)) as orderdate
from data.OrderDetail
group by OrderNum
) as x
inner join data.OrderDetail as y on y.OrderNum = x.OrderNum
) result
where result.rank_ = 1;
select * from
(
SELECT OrderNum, Product, DistributionCenter, OrderDate
, ROW_NUMBER() over (partition by OrderNum order by OrderDate desc) as rownum
FROM OrderDetail
) as xxx
where xxx.rownum = 1
ROW_NUMBER (Transact-SQL)
Try this.
; WITH CTE1
AS (
SELECT
od.OrderNum
, od.Product
, od.DistributionCenter
, CAST(od.OrderDate AS DATE) AS OrderDate
, RowNumber = ROW_NUMBER() OVER (PARTITION BY od.Product, od.DistributionCenter ORDER BY CAST(od.OrderDate AS DATE) DESC)
FROM data.OrderDetail od
)
SELECT
OrderNum
, Product
, DistributionCenter
, OrderDate
FROM CTE1
WHERE RowNumber = 1