SQL sub select if exists - sql

I am using SQL Server 2012. I have two tables to hold orders for products. Order which has a received date and OrderItem which has a price and order id fk.
I am trying to write a query get all orders within a date range, group them by the date, and then sum all the order items price to get the total of all orders for that date.
I have this working. Now I want to add another column to select the difference between the total price for that day, and 7 days ago. If there are no orders 7 days ago then the column should be null.
So at the moment I have the below query:
select cast(o.ReceivedDate as date) as OrderDate,
coalesce(count(orderItems.orderId), 0) as Orders,
coalesce(sum(orderItems.Price), 0) as Price
from [Order] o
left outer join (
select o.Id as orderId, sum(ot.Price) as Price
from OrderItem ot
join [Order] o on ot.OrderId = o.Id
where o.ReceivedDate >= #DateFrom and o.ReceivedDate <= #DateTo
group by o.Id
) as orderItems on o.Id = orderItems.orderId
where o.ReceivedDate >= #DateFrom and o.ReceivedDate <= #DateTo
group by cast(o.ReceivedDate as date)
order by cast(o.ReceivedDate as date) desc
So how can I add my other column to this query? I need to do something like:
//pseudo
if o.RecievedDate - 7 exists then orderItems.Price - Price from 7 days ago else null
But I am not sure how to do this? I have created a sqlfiddle to help explain http://sqlfiddle.com/#!6/8b837/1
So from my sample data what I want to achieve is results like this:
| ORDERDATE | ORDERS | PRICE | DIFF7DAYS |
---------------------------------------------
| 2013-01-25 | 3 | 38 | 28 |
| 2013-01-24 | 1 | 12 | null |
| 2013-01-23 | 1 | 10 | null |
| 2013-01-22 | 1 | 33 | null |
| 2013-01-18 | 1 | 10 | null |
| 2013-01-10 | 1 | 3 | -43 |
| 2013-01-08 | 2 | 11 | null |
| 2013-01-04 | 1 | 1 | null |
| 2013-01-03 | 3 | 46 | null |
As you can see, the 25th has a order 7 days ago so the difference is shown. The 24th doesn't so null is displayed.
Any help would be much appreciated.

Not sure why you are using a left outer join between [Orders] table and the subquery as there cannot be orders without order items (in general):
To get your results you could do it in a simplified version as below using a CTE
SQL-FIDDLE-DEMO
;with cte as (
select convert(date,o.ReceivedDate) orderDate,
count(distinct o.Id) as Orders,
coalesce(sum(ot.Price),0) as Price
from OrderItem ot
join [Order] o on ot.OrderId = o.Id
where o.ReceivedDate >= #DateFrom and o.ReceivedDate <= #DateTo
group by convert(date,o.ReceivedDate)
)
select c1.orderDate, c1.Orders, c1.Price, c1.Price-c2.Price DIFF7DAYS
from cte c1 left join cte c2 on dateadd(day,-7,c1.orderdate) = c2.orderdate
order by c1.orderdate desc
| ORDERDATE | ORDERS | PRICE | DIFF7DAYS |
-------------------------------------------
| 2013-01-25 | 3 | 38 | 28 |
| 2013-01-24 | 1 | 12 | (null) |
| 2013-01-23 | 1 | 10 | (null) |
| 2013-01-22 | 1 | 33 | (null) |
| 2013-01-18 | 1 | 10 | (null) |
| 2013-01-10 | 1 | 3 | -43 |
| 2013-01-08 | 2 | 11 | (null) |
| 2013-01-04 | 1 | 1 | (null) |
| 2013-01-03 | 3 | 46 | (null) |

Use a temp table and join it on the datediff.
DECLARE #DateFrom datetime
SET #DateFrom = '2012-12-02'
DECLARE #DateTo datetime
SET #DateTo = '2013-03-13'
CREATE TABLE #temp ( orderdate date, orders int, price money)
INSERT INTO #temp
SELECT cast(o.ReceivedDate AS date) AS OrderDate,
coalesce(count(orderItems.orderId), 0) AS Orders,
coalesce(sum(orderItems.Price), 0) AS Price
FROM [Order] o
LEFT OUTER JOIN (
SELECT o.Id AS orderId, sum(ot.Price) AS Price
FROM OrderItem ot
JOIN [Order] o ON ot.OrderId = o.Id
WHERE o.ReceivedDate >= #DateFrom AND o.ReceivedDate <= #DateTo
GROUP BY o.Id
) AS orderItems ON o.Id = orderItems.orderId
WHERE o.ReceivedDate >= #DateFrom AND o.ReceivedDate <= #DateTo
GROUP BY cast(o.ReceivedDate AS date)
SELECT t1.orderdate, t1.orders, t1.price,
t1.price - t2.price AS diff7days
FROM #temp t1 LEFT JOIN #temp t2
ON datediff(DAY, t2.orderdate, t1.orderdate) = 7
ORDER BY t1.orderdate DESC
http://sqlfiddle.com/#!6/8b837/34

Related

SQL joining tables based off latest previous date

Let's say I have two tables for example:
Table 1 - customer order information
x---------x--------x-------------x
cust_id | item | order date |
x---------x--------x-------------x
1 | 100 | 01/01/2020 |
1 | 112 | 03/07/2022 |
2 | 100 | 01/02/2020 |
2 | 168 | 05/03/2022 |
3 | 200 | 15/06/2021 |
----------x--------x-------------x
and Table 2 - customer membership status
x---------x--------x-------------x
cust_id | Status | startdate |
x---------x--------x-------------x
1 | silver | 01/01/2019 |
1 | bronze | 05/12/2019 |
1 | gold | 05/06/2022 |
2 | silver | 24/12/2021 |
----------x--------x-------------x
I want to join the two tables so that I can see what their membership status was at the time of purchase, to produce something like this:
x---------x--------x-------------x----------x
cust_id | item | order date | status |
x---------x--------x-------------x----------x
1 | 100 | 01/01/2020 | bronze |
1 | 112 | 03/07/2022 | gold |
2 | 100 | 01/02/2020 | NULL |
2 | 168 | 05/03/2022 | silver |
3 | 200 | 15/06/2021 | NULL |
----------x--------x-------------x----------x
Tried multiple ways include min/max, >=, group by having etc with no luck. I feel like multiple joins are going to be needed here but I can't figure out - any help would be greatly appreciated.
(also note: dates are in European/au not American format.)
Try the following using LEAD function to define periods limits for each status:
SELECT T.cust_id, T.item, T.orderdate, D.status
FROM order_information T
LEFT JOIN
(
SELECT cust_id, Status, startdate,
LEAD(startdate, 1, GETDATE()) OVER (PARTITION BY cust_id ORDER BY startdate) AS enddate
FROM customer_membership
) D
ON T.cust_id = D.cust_id AND
T.orderdate BETWEEN D.startdate AND D.enddate
See a demo on SQL Server.
SELECT
[cust_id],
[item],
[order date],
[status]
FROM
(
SELECT
t1.[cust_id],
t1.[item],
t1.[order date],
t2.[status],
ROW_NUMBER() OVER (PARTITION BY t1.[cust_id], t1.[item] ORDER BY t2.[startdate] DESC) rn
FROM #t1 t1
LEFT JOIN #t2 t2
ON t1.[cust_id] = t2.[cust_id] AND t1.[order date] >= t2.[startdate]
) a
WHERE rn = 1
SELECT
o.cust_id,
o.item,
o.order_date,
m.status
FROM
customer_order o
LEFT JOIN
customer_membership m
ON o.cust_id = m.cust_id
AND o.order_date > m.start_date
GROUP BY
o.cust_id,
o.item,
o.order_date
HAVING
Count(m.status) = 0
OR m.start_date = Max(m.start_date);

getting the time before the contact issue date SQL Query

I am comparing two time column in the my file.
What I need to do is to compare the timestamp from order_status table and compare it to the contact table - contact_time.
From the contact table, i need to be able to get the timestamp before the contact_time for each order_id.
Sample:
Order_ID Contact_Time
1 12/24/2019 12:25:00 AM
The query should show:
Order_ID Order_Status_ID Status_Description
1 3 desc3
Since based from the contact_time, the last timestamp for
order 1 is: 12/24/2019 12:10:00 AM
I only need to show the order_ID, order_status_ID and status_description.
here are the three table:
SELECT
ORDER_ID,
ORDER_STATUS_ID
FROM ORDER_STATUS
INNER JOIN META_STATUS ON ORDER_STATUS.ORDER_STATUS_ID = META_STATUS.META_STATUS_ID
INNER JOIN (
SELECT ORDER_STATUS.ORDER_ID, MAX(ORDER_STATUS.TIMESTAMP) MAX_TIME FROM ORDER_STATUS INNER JOIN CONTACT
ON ORDER_STATUS.ORDER_ID = CONTACT.ORDER_ID
WHERE CONTACT.CONTACT_TIME > ORDER_STATUS.TIMESTAMP) X
on x.ORDER_ID = ORDER_STATUS.ORDER_ID and ORDER_STATUS.TIMESTAMP = x.MAX_TIME
Hope someone can help me fix my code.
Thanks!
Try this:
WITH
a AS (
SELECT
os.Order_ID,
os.order_status_id AS Order_Status_ID,
ms.status_description AS Status_Description,
os.[Timestamp],
c.Contact_time,
ROW_NUMBER() OVER(
PARTITION BY os.Order_ID
ORDER BY [Timestamp] DESC
) AS rn
FROM Contact AS c
JOIN Order_Status AS os
ON c.Order_id = os.Order_ID AND
c.Contact_time >= os.[Timestamp]
LEFT JOIN meta_status AS ms
ON os.order_status_id = ms.order_status_id
)
SELECT *
FROM a
WHERE rn = 1;
Result:
+----------+-----------------+--------------------+-------------------------+-------------------------+----+
| Order_ID | Order_Status_ID | Status_Description | Timestamp | Contact_time | rn |
+----------+-----------------+--------------------+-------------------------+-------------------------+----+
| 1 | 3 | desc3 | 2019-12-24 00:10:00.000 | 2019-12-24 00:25:00.000 | 1 |
| 2 | 9 | | 2019-12-24 15:10:00.000 | 2019-12-24 15:30:00.000 | 1 |
| 4 | 3 | desc3 | 2019-12-24 19:32:00.000 | 2019-12-24 19:38:00.000 | 1 |
| 5 | 2 | desc2 | 2019-01-28 19:30:00.000 | 2019-01-28 19:46:00.000 | 1 |
+----------+-----------------+--------------------+-------------------------+-------------------------+----+
db-fiddle
Try this:
SELECT os.ORDER_ID
,os.ORDER_STATUS_ID,
,ms.STATUS_DESCRIPTION
FROM ORDER_STATUS AS os
INNER JOIN META_STATUS AS ms
ON os.ORDER_STATUS_ID = ms.META_STATUS_ID
INNER JOIN (
SELECT os.ORDER_ID
,MAX(os.TIMESTAMP) MAX_TIME
FROM ORDER_STATUS AS os
INNER JOIN CONTACT AS c
ON os.ORDER_ID = c.ORDER_ID
WHERE c.CONTACT_TIME > os.TIMESTAMP) x
ON x.ORDER_ID = os.ORDER_ID
AND os.TIMESTAMP = x.MAX_TIME

Group by with left outer join, exclude nulls

I have an order table and a trip table that includes payment information. It is a many to many relationship - order can split across many trips and one trip could have payment info for a couple of orders and sometimes an order. There is no "Zero" record in the Trips table - so a left join with that value as the key will return a NULL record. I am using SQL 2012
Order table
+----+----------+--------------+
| order_id | trip_nbr | veh_id |
+----+----------+--------------+
| 1 | 12 | 3 |
| 2 | 22 | 6 |
| 2 | 0 | 8 |
| 4 | 25 | 7 |
| 7 | 0 | 11 |
+----+----------+--------------+
Trips table
+----+------------+--------------+
| trip_nbr | payment | veh_id |
+----+------------+--------------+
| 12 | 20.00 | 3 |
| 22 | 123.00 | 6 |
| 22 | 12.50 | 6 |
| 25 | 133.33 | 7 |
+----+------------+--------------+
Here is my query:
select o.order_id,
t.trip_nbr,
sum(t.payment_amt)
from orders o
left outer join trips t
on o.trip_nbr = t.trip_nbr
group by o.order_id,
t.trip_nbr
Results:
+----+----------+--------------+
| order_id | trip_nbr | sum |
+----+----------+--------------+
| 1 | 12 | 20.00 |
| 2 | 22 | 135.50 |
| 2 | NULL | NULL |
| 4 | 25 | 133.33 |
| 7 | NULL | NULL |
+----+----------+--------------+
The problem is, I get lots of information from the orders table and just the payment info from the Trips table. So I don't want to exclude any order records (which would happen if I add the clause "WHERE t.trip_nbr is NOT NULL") - but I don't want to get 2 records in my grouping - one for t.trip_nbr is NULL and one where it finds a match.
Desired results:
+----+----------+--------------+
| order_id | trip_nbr | sum |
+----+----------+--------------+
| 1 | 12 | 20.00 |
| 2 | 22 | 135.50 |
| 4 | 25 | 133.33 |
| 7 | NULL | NULL |
+----+----------+--------------+
I want the unmatched record order_id = 2 to be "summarized away" - but keep the lone record for order_id = 7. The reason is that this table is later join with another table and the extra NULL records are creating duplicates.
This should work:
WITH orders2 AS
(
SELECT *,
N = SUM(CASE WHEN trip_nbr <> 0 THEN 1 ELSE 0 END) OVER(PARTITION BY order_id)
FROM orders
)
SELECT o.order_id,
t.trip_nbr,
SUM(t.payment_amt)
FROM orders2 o
LEFT OUTER JOIN trips t
ON o.trip_nbr = t.trip_nbr
WHERE N = 0 OR (N > 1 AND o.trp_nbr <> 0)
GROUP BY o.order_id,
t.trip_nbr;
You can use a window function like RANK to identify superfluous NULL- valued records and filter them out in an outer query:
select order_id,
trip_nbr,
total_payment
from (
select o.order_id,
t.trip_nbr,
sum(t.payment) as total_payment,
rank() over (partition by order_id
order by case
when t.trip_nbr IS NULL then 2
else 1
end) as rnk
from orders o
left outer join trips t
on o.trip_nbr = t.trip_nbr
group by o.order_id, t.trip_nbr) as t
where t.rnk = 1
If you convert your nulls to zero, then sum "trip_nbr" and "sum" for a given order_id. Would this not solve your challenge?
create table #Order (Order_Id int , Trip_nbr int , Veh_id int )
Create Table #Trips (trip_nbr int , Payment Numeric(13,2), Veh_id int )
insert into #Order (Order_id, Trip_nbr, Veh_id) values (1,12,3)
insert into #Order (Order_id, Trip_nbr, Veh_id) values (2,22,6)
insert into #Order (Order_id, Trip_nbr, Veh_id) values (2,0 ,8)
insert into #Order (Order_id, Trip_nbr, Veh_id) values (4,25,7)
insert into #Order (Order_id, Trip_nbr, Veh_id) values (7,0,11)
insert into #Trips (trip_nbr, Payment, Veh_id) values (12, 20.00 , 3 )
insert into #Trips (trip_nbr, Payment, Veh_id) values (22, 123.00,6 )
insert into #Trips (trip_nbr, Payment, Veh_id) values (22, 12.50 , 6 )
insert into #Trips (trip_nbr, Payment, Veh_id) values (25, 133.33 , 7 )
select Order_id, trip_nbr = sum(trip_nbr), Payment = sum(payment)
from
(
select o.order_id,
t.trip_nbr,
Payment = sum(t.Payment)
from #order o
left outer join #trips t on t.trip_nbr = o.trip_nbr
-- left outer join #order o on t.trip_nbr = o.trip_nbr
group by o.order_id, t.trip_nbr
) x
group by Order_id
order by Order_id

SQL sum of different status within 24 hrs group by hours

I am trying to sum status within 24 hour groups by hours. I have an order, order status and status table.
Order Table:
+---------+-------------------------+
| orderid | orderdate |
+---------+-------------------------+
| 1 | 2015-09-16 00:04:19.100 |
| 2 | 2015-09-16 00:01:19.490 |
| 3 | 2015-09-16 00:02:33.733 |
| 4 | 2015-09-16 00:03:58.800 |
| 5 | 2015-09-16 00:01:16.020 |
| 6 | 2015-09-16 00:01:16.677 |
| 7 | 2015-09-16 00:02:06.920 |
+---------+-------------------------+
Order Status Table:
+---------+----------+
| orderid | statusid |
+---------+----------+
| 1 | 11 |
| 2 | 22 |
| 3 | 22 |
| 4 | 11 |
| 5 | 22 |
| 6 | 33 |
| 7 | 11 |
+---------+----------+
Status Table:
+----------+----------+
| statusid | status |
+----------+----------+
| 11 | PVC |
| 22 | CCC |
| 33 | WWW |
| | |
+----------+----------+
I am try to write SQL that display the count of the status within 24 hours for distinct orderids grouped by hour like below:
+------+-----+-----+-----+
| Hour | PVC | CCC | WWW |
+------+-----+-----+-----+
| 1 | 0 | 2 | 1 |
| 2 | 1 | 1 | 0 |
| 3 | 1 | 0 | 0 |
| 4 | 1 | 0 | 0 |
+------+-----+-----+-----+
This is my SQL so far. I am stuck trying to get the sum of each order status:
SELECT
DATEPART(hour, o.orderdate) AS Hour,
SUM(
CASE (
SELECT stat.status
FROM Status stat, orderstatus os
WHERE stat.status IN ('PVC') AND os.orderid = o.id AND os.statusid = stat.id
)
WHEN 'PVC' THEN 1
ELSE 0
END
) AS PVC,
SUM(
CASE (
SELECT stat.status
FROM Status stat, orderstatus os
WHERE stat.status IN ('WWW') AND os.orderid = o.id AND os.statusid = stat.id
)
WHEN 'CCC' THEN 1
ELSE 0
END
) AS CCC,
SUM(
CASE (
SELECT stat.status
FROM Status stat, orderstatus os
WHERE stat.status IN ('CCC') AND os.orderid = o.id AND os.statusid = stat.id)
WHEN 'WWW' THEN 1
ELSE 0
END
) AS WWW
FROM orders o
WHERE o.orderdate BETWEEN DATEADD(d,-1,CURRENT_TIMESTAMP) AND CURRENT_TIMESTAMP
GROUP BY DATEPART(hour, o.orderdate)
ORDER BY DATEPART(hour, o.orderdate);
Here you go -- I'm ignoring the errors in your data since this will fail if the status table really had duplicate ids like in your example data.
SELECT hour, sum(PVC) as PVC, sum(CCC) as CCC, sum(WWW) as WWW
from (
select datepart(hour,orderdate) as hour,
case when s.status = 'PVC' then 1 else 0 end as PVC,
case when s.status = 'CCC' then 1 else 0 end as CCC,
case when s.status = 'WWW' then 1 else 0 end as WWW
from order o
join orderstatus os on o.orderid = os.orderid
join status s on s.statusid = os.statusid
) sub
group by hour
this should get you closer, then you have to pivot:
SELECT
DATEPART(HOUR,o.orderdate) AS orderDate_hour,
s.status,
COUNT(DISTINCT o.orderid) AS count_orderID
FROM
orders o INNER JOIN
orderstatus os ON
o.orderid = os.orderid INNER JOIN
status s ON
os.statusid = s.statusid
WHERE
o.orderdate >= DATEADD(d,-1,CURRENT_TIMESTAMP)
GROUP BY
DATEPART(HOUR,o.orderdate) , s.status
ORDER BY
DATEPART(HOUR,o.orderdate)
try this for the pivot:
SELECT
*
FROM
(SELECT
DATEPART(HOUR,o.orderdate) AS orderDate_hour,
s.status,
COUNT(DISTINCT o.orderid) AS count_orderID
FROM
orders o INNER JOIN
orderstatus os ON
o.orderid = os.orderid INNER JOIN
status s ON
os.statusid = s.statusid
WHERE
o.orderdate >= DATEADD(d,-1,CURRENT_TIMESTAMP)
GROUP BY
DATEPART(HOUR,o.orderdate) , s.status) s
PIVOT ( MAX(count_orderID) FOR status IN ('pvc','ccc','www')) AS p
ORDER BY
orderDate_hour

How to return only latest record on join [duplicate]

This question already has answers here:
Fetch the rows which have the Max value for a column for each distinct value of another column
(35 answers)
Closed 7 years ago.
I'm joining tables. I only want to return one record from the joining table, based on a date field.
Here's a simplified fiddle of what I've done so far: http://sqlfiddle.com/#!3/be0cdd/2
My tables:
CUSTOMER
| CustomerID |
--------------
| 1 |
PURCHASE
| PurchaseID | CustomerID | ProductID | CreateDate | ArchiveFlag |
------------------------------------------------------------------
| 1 | 1 | 443 | 01-FEB-15 | F |
| 2 | 1 | 551 | 01-MAR-15 | F |
| 3 | 1 | 151 | 01-JAN-15 | F |
| 4 | 1 | 654 | 01-MAY-15 | T |
| 5 | 1 | 345 | 01-APR-15 | T |
and here's the query itself:
select *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F';
I only want to return the latest purchase that isn't archived (in this example, purchase ID 2) for each customer.
Ideal output:
| CustomerID | PurchaseID | CustomerID_2 | ProductID | CreateDate | ArchiveFlag |
|--------------------------------------------------------------------------------
| 1 | 2 | 1 | 551 | 01-MAR-15 | F |
Oracle 12c introduced a row limiting clause and you could do (if you only want a single result):
SELECT *
FROM customer c
INNER JOIN purchase p
ON ( c.customerid = p.customerid )
WHERE p.archiveflag = 'F'
ORDER BY
CreateDate DESC
FETCH FIRST 1 ROW ONLY
In earlier versions you can do:
SQL Fiddle
Oracle 11g R2 Schema Setup:
create table CUSTOMER(CustomerID INT);
create table PURCHASE(PurchaseID INT, CustomerID INT, ProductID INT, CreateDate date, ArchiveFlag char);
insert into CUSTOMER values(1);
insert into CUSTOMER values(2);
insert into PURCHASE values(1,1,443,'01-FEB-15','F');
insert into PURCHASE values(2,1,551,'01-MAR-15','F');
insert into PURCHASE values(3,1,151,'01-JAN-15','F');
insert into PURCHASE values(4,1,654,'01-MAY-15','T');
insert into PURCHASE values(5,1,345,'01-APR-15','T');
insert into PURCHASE values(6,2,234,'01-MAY-15','T');
insert into PURCHASE values(7,2,134,'01-APR-15','F');
insert into PURCHASE values(8,2,999,'01-JAN-15','F');
insert into PURCHASE values(9,2,724,'07-JUN-15','F');
insert into PURCHASE values(10,2,345,'01-JUN-15','T');
Query 1 - If you only want to get the latest for a single customer:
SELECT *
FROM (
SELECT *
FROM Purchase
WHERE archiveflag = 'F'
AND CustomerID = 1
ORDER BY
CreateDate DESC
)
WHERE ROWNUM = 1
Results:
| PURCHASEID | CUSTOMERID | PRODUCTID | CREATEDATE | ARCHIVEFLAG |
|------------|------------|-----------|-------------------------|-------------|
| 2 | 1 | 551 | March, 01 2015 00:00:00 | F |
Query 2 - If you want to get the latest for all customers:
SELECT PurchaseID,
CustomerID,
ProductID,
CreateDate,
ArchiveFlag
FROM (
SELECT p.*,
ROW_NUMBER() OVER ( PARTITION BY p.CustomerID ORDER BY CreateDate DESC ) RN
FROM purchase p
WHERE ArchiveFlag = 'F'
)
WHERE RN = 1
Results:
| PURCHASEID | CUSTOMERID | PRODUCTID | CREATEDATE | ARCHIVEFLAG |
|------------|------------|-----------|-------------------------|-------------|
| 2 | 1 | 551 | March, 01 2015 00:00:00 | F |
| 9 | 2 | 724 | June, 07 2015 00:00:00 | F |
If PURCHASE.CUSTOMERID is a not null foreign key linked to CUSTOMER.CUSTOMERID then you do not need to join the tables (as above).
I think you want to use row_number():
select *
from customer c join
(select p.*,
row_number() over (partition by p.customerid order by p.createdate desc) as seqnum
from purchase p
where p.archiveflag = 'F'
) p
on c.customerid = p.customerid and seqnum = 1;
SQL Fiddle
Schema setup
create table CUSTOMER(CustomerID int)
create table PURCHASE(PurchaseID int, CustomerID int, ProductID int, CreateDate date, ArchiveFlag char)
insert into CUSTOMER values(1)
insert into CUSTOMER values(2)
insert into PURCHASE values(1,1,443,'01-FEB-15','F')
insert into PURCHASE values(2,1,551,'01-MAR-15','F')
insert into PURCHASE values(3,1,151,'01-JAN-15','F')
insert into PURCHASE values(4,1,654,'01-MAY-15','T')
insert into PURCHASE values(5,1,345,'01-APR-15','T')
insert into PURCHASE values(6,2,331,'01-FEB-15','T')
insert into PURCHASE values(7,2,298,'01-JUN-15','F')
Query to get latest pending for all customers
select *
from purchase pa join customer c on c.customerid=pa.customerid
where pa.archiveflag = 'F'
and pa.createdate=(select max(createdate)
from purchase pb
where pa.customerid=pb.customerid
and pb.archiveflag='F')
Output
| PurchaseID | CustomerID | ProductID | CreateDate | ArchiveFlag | CustomerID |
|------------|------------|-----------|------------|-------------|------------|
| 2 | 1 | 551 | 2015-03-01 | F | 1 |
| 7 | 2 | 298 | 2015-06-01 | F | 2 |
You can use top and order by in your query like this
select Top 1 *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F'
Order by p.CreateDate Desc;
Just use where clause: as told you wanted purchase ID 2: do as below:
SELECT * FROM
select *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F';
order by CreateDate desc
where PurchasedID = 2;
Try this one..
select top 1 *
from customer c
join purchase p
on c.customerid = p.customerid
and p.archiveflag = 'F'
order by CreateDate desc;