Getting the daily sales report given the date - sql

Given a date, the table displays the items sold on that date.
The table groups the category of the items and show the total sales value for each category. At the end, the report shows the total sales value for the day(s). Something like this:
ID Category Price Units Total Value
----------------------------------------------------
2244 class 10.50 10 105.00
2555 class 5.00 5 25.00
3455 class 20.00 1 20.00
Total 16 150.00
1255 pop 20.00 5 100.00
5666 pop 10.00 10 100.00
Total 15 200,00
1244 rock 2.50 20 50.00
8844 rock 5.00 50 250.00
Total 70 300.00
----------------------------------------------
Total Daily Sales 101 650.00
DBMS: SQL Server 2012
Bolded: primary keys
Item (upc, title*, type, category, company, year, price, stock)
PurchaseItem (receiptId, upc, quantity)
Order (receiptId, date, cid, card#, expiryDate, expectedDate, deliveredDate)
Rough work of what I have so far..
SELECT I.upc, I.category, I.price, P.quantity, P.quantity*I.price AS totalValue, SUM(totalValue), SUM(P.quantity) AS totalUnits, O.date
FROM Item I, Order O
JOIN (SELECT P.quantity
FROM PurchaseItem P, Item I
WHERE I.upc = P.upc)
ON I.upc = P.upc
WHERE O.date = ({$date}) AND O.receiptId = P.receiptId
GROUP BY I.upc, I.category, I.price, P.quantity, totalValue, O.date
Alright, this isn't right and I'm kind of stuck. Need some help!
I want it so it produces the total value of items from one category then in the end, it will add up the total value of the items from all categories.
SAMPLE TABLES
Item(2568, Beatles, rock, Music Inc, 1998, 50.50, 5000)
PurchaseItem (5300, 2568, 2)
Order (5300, 10/09/2014, ...Not important..) cid is customerId and card# is credit card number.

SSRS or a similar reporting package can usually handles this for you natively. If this has to be done in SQl script then a quick solution would be a cursor/while loop. pseudo code would look like this;
create tempsales table;
get distinct list of categories;
for each category
Begin
insert into tempsale (...)
sales where category = #category
group by category, item
insert into tempsales (...) -- use NULL value for item or perhaps a value of 'TOTAL'
Sales where category = #category
group by category
when last category
insert into tempsales (...) -- use NULL value for item AND Category or perhaps a value of 'TOTAL'
total with no group
end
select from tempsales;

See if this helps:
CREATE SAMPLE DATA
use tempdb;
create table Item(
upc int,
category varchar(100),
price decimal(8,2)
)
create table PurchaseItem(
receiptId int,
upc int,
quantity int
)
create table [Order](
receiptId int,
[date] date
)
insert into Item values
(2244, 'class', 10.50),
(2555, 'class', 5.0),
(3455, 'class', 20.0),
(1255, 'pop', 20.0),
(5666, 'pop', 10.0),
(1244, 'rock', 2.50),
(8844, 'rock', 5.0)
insert into PurchaseItem values
(5300, 2244, 10),
(5300, 2555, 5),
(5300, 3455, 1),
(5300, 1255, 5),
(5300, 5666, 10),
(5300, 1244, 20),
(5300, 8844, 50)
insert into [Order] values(5300,'20140910')
SOLUTION
;with cte as(
select
i.upc as Id,
i.category as Category,
i.price as Price,
p.quantity as Units,
price * quantity as TotalValue
from [Order] o
inner join PurchaseItem p
on p.receiptId = o.receiptId
inner join Item i
on i.upc = p.upc
)
select
Id,
case
when grouping(Id) = 1 then 'Total'
else Category
end as Category,
Price,
sum(Units) as Units,
sum(TotalValue) as TotalValue
from cte
group by
grouping sets(Category, (Category, Id, Price, Units, TotalValue))
union all
select
null,
'Total Daily Sales',
null,
sum(Units),
sum(Totalvalue)
from cte
DROP SAMPLE DATA
drop table item
drop table PurchaseItem
drop table [Order]

Related

How to value cost of sales using FIFO in SQL Server

I want value the cost of goods sold using the FIFO method.
I know how many beers I sold. Based on my price I bought those beers at, what is the cost of those sales? So, my sales of 7 Peronis are valued at £1.70 -- based on the FIFO valuation method.
How do I calculate in SQL Server.
I am going to be working this out for many products and from many branches at the same time, so I would like to use a method that does not involve cursors (or any other types of loops).
-- SETUP
DROP TABLE IF EXISTS #Deliveries;
CREATE TABLE #Deliveries (DeliveryDate DATE, ProductCode VARCHAR(10), Quantity INT, Cost DECIMAL(6,2));
INSERT INTO #Deliveries (DeliveryDate, ProductCode, Quantity, Cost)
VALUES
('2020-11-23', 'PERONI', 2, 0.20), ('2020-11-24', 'PERONI', 4, 0.30), ('2020-11-25', 'PERONI', 7, 0.10),
('2020-11-23', 'BUDWEISER', 5, 0.20), ('2020-11-24', 'BUDWEISER', 5, 0.50), ('2020-11-25', 'BUDWEISER', 4, 0.80);
DROP TABLE IF EXISTS #StockResults;
CREATE TABLE #StockResults (ProductCode VARCHAR(10), SalesQty INT, CostOfSalesValue DECIMAL(6,2));
INSERT INTO #StockResults (ProductCode, SalesQty)
VALUES ('PERONI', 7), ('BUDWEISER', 4);
SELECT * FROM #Deliveries;
SELECT * FROM #StockResults;
-- DESIRED RESULT
/*
ProductCode SalesQty CostOfSalesValue
PERONI 7 1.70
BUDWEISER 4 0.80
*/
This is probably not very efficient but it shows you one way in which this can be achieved which should help you come up with your finished solution. I would imagine that there needs to be a lot more complexity built into this process to account for things like stock wastage, but I'll leave that up to you:
Query
-- SETUP
declare #Deliveries table (DeliveryDate date, ProductCode varchar(10), Quantity int, Cost decimal(6,2));
insert into #Deliveries (DeliveryDate, ProductCode, Quantity, Cost) values ('2020-11-23', 'PERONI', 2, 0.20), ('2020-11-24', 'PERONI', 4, 0.30), ('2020-11-25', 'PERONI', 7, 0.10),('2020-11-23', 'BUDWEISER', 5, 0.20), ('2020-11-24', 'BUDWEISER', 5, 0.50), ('2020-11-25', 'BUDWEISER', 4, 0.80);
declare #StockResults table (ProductCode varchar(10), SalesQty int);
insert into #StockResults (ProductCode, SalesQty) values ('PERONI', 7), ('BUDWEISER', 4);
-- QUERY
with r as
(
select d.ProductCode
,d.DeliveryDate
,d.Quantity
,d.Cost
,isnull(sum(d.Quantity) over (partition by d.ProductCode order by d.DeliveryDate rows between unbounded preceding and 1 preceding),0) as RunningQuantityStart
,sum(d.Quantity) over (partition by d.ProductCode order by d.DeliveryDate) as RunningQuantityEnd
from #Deliveries as d
)
select r.ProductCode
,s.SalesQty
,sum(case when r.RunningQuantityEnd >= s.SalesQty
then (s.SalesQty - r.RunningQuantityStart) * r.Cost
else (r.RunningQuantityEnd - r.RunningQuantityStart) * r.Cost
end
) as CostOfSalesValue
from r
join #StockResults as s
on r.ProductCode = s.ProductCode
and r.RunningQuantityStart < s.SalesQty
group by r.ProductCode
,s.SalesQty;
##Output
+-------------+----------+------------------+
| ProductCode | SalesQty | CostOfSalesValue |
+-------------+----------+------------------+
| BUDWEISER | 4 | 0.80 |
| PERONI | 7 | 1.70 |
+-------------+----------+------------------+
Below query might help you:
declare #maxQty int
select #maxQty = max(SalesQty) from #StockResults
;WITH AllNumbers AS
(
SELECT 1 AS Number
UNION ALL
SELECT Number+1 FROM AllNumbers WHERE Number < #maxQty
)
select ProductCode, SalesQty, SUM(Cost) as CostOfSalesValue from
(
SELECT SR.ProductCode, SR.SalesQty, DLM.RN, DLM.Cost FROM #StockResults SR
outer apply
(
select ROW_NUMBER()OVER (order by DeliveryDate asc) as RN, Dl.Cost from #Deliveries Dl
inner join AllNumbers AL on AL.Number <= Dl.Quantity
where Dl.ProductCode = SR.ProductCode
) as DLM
) result
where RN <= SalesQty
group by ProductCode, SalesQty

Is it possible to use SELECT DISTINCT and GROUP BY together?

Is it possible to use SELECT DISTINCT and GROUP BY clause together?
I need DISTINCT to avoid duplicate values and make a single entry of the records, and then get the Total quantity of those duplicate values.
For example, I have columns like Item Name and Quantity and their records are (product A,5), (product A,7).
Since products are the same I want it as a single entry and then total its quantity. So, the output on my report would be like this: (product A,12)
Can DISTINCT and GROUP BY clause solve this together?
Based on your comment on Used_By_Already's answer, I think you need to use sum() over (...) construct, such as the following...
create table [dbo].[Purchases_Supplier] (
[Purchased From] nvarchar(50),
Address nvarchar(50),
[Transaction Month] nvarchar(6),
Category nvarchar(50),
Articles nvarchar(50),
Unit int,
[Unit Price] money,
Qty int,
Tin nvarchar(50),
Cashier nvarchar(50)
);
insert [dbo].[Purchases_Supplier] values
('Acme', '123 Street', '202003', 'Baubles', 'Product A', 1, 1.1, 5, 'Nickel', 'John'),
('Acme', '123 Street', '202003', 'Baubles', 'Product A', 1, 1.1, 7, 'Nickel', 'John'),
('Acme', '123 Street', '202003', 'Baubles', 'Product B', 1, 1.1, 9, 'Silver', 'Maria'),
('Acme', '123 Street', '202003', 'Baubles', 'Product B', 1, 1.1, 11, 'Silver', 'Maria');
declare #Supplier_Name nvarchar(50) = N'Acme',
#Month_Purc nvarchar(6) = '202003',
#Cat nvarchar(50) = 'Baubles';
select
Articles,
Qty,
Unit,
[Unit Price],
[Purchased From],
Address,
Tin,
Cashier,
-- NOTE: partition by has everything in the GROUP BY except [Qty]...
sum(Qty) over (partition by Articles, Unit, [Unit Price], [Purchased From], Address, Tin, Cashier) as Total
from dbo.Purchases_Supplier
where [Purchased From] = #Supplier_Name
and [Transaction Month] = #Month_Purc
and Category = #Cat
group by Articles, Qty, Unit, [Unit Price], [Purchased From], Address, Tin, Cashier;
Which yields the result:
Articles Qty Unit Unit Price Purchased From Address Tin Cashier Total
Product A 5 1 1.1000 Acme 123 Street Nickel John 12
Product A 7 1 1.1000 Acme 123 Street Nickel John 12
Product B 9 1 1.1000 Acme 123 Street Silver Maria 20
Product B 11 1 1.1000 Acme 123 Street Silver Maria 20
GROUP BY will result in distinct rows, it does this automatically, you do NOT also need SELECT DISTINCT to reduce the number of rows.
CREATE TABLE mytable(
product VARCHAR(1) NOT NULL
,quantity INTEGER NOT NULL
);
INSERT INTO mytable(product,quantity) VALUES ('a',7);
INSERT INTO mytable(product,quantity) VALUES ('a',5);
INSERT INTO mytable(product,quantity) VALUES ('b',17);
INSERT INTO mytable(product,quantity) VALUES ('b',15);
select product, sum(quantity) as qty
from mytable
group by product
product | qty
:------ | --:
a | 12
b | 32
db<>fiddle here
Note that there is a single row in that result, i.e. only one row for each distinct value in the column called product because we specified that column in the GROUP BY clause.
db<>fiddle here

Product Final Price after Many Discount given

I have two tables.
One table of Ids and their prices, and second table of discounts per Id.
In the table of discounts an Id can has many Discounts, and I need to know the final price of an Id.
What is the Best way to query it (in one query) ?
The query should be generic for many discounts per id (not only 2 as mentioned below in the example)
For example
Table one
id price
1 2.00
2 2.00
3 2.00
Table two
id Discount
1 0.20
1 0.30
2 0.40
3 0.50
3 0.60
Final result:
id OrigPrice PriceAfterDiscount
1 2.00 1.12
2 2.00 1.20
3 2.00 0.40
Here's another way to do it:
SELECT T1.ID, T1.Price, T1.Price * EXP(SUM(LOG(1 - T2.Discount)))
FROM T1 INNER JOIN T2 ON T1.ID = T2.ID
GROUP BY T1.ID, T1.Price
The EXP/LOG trick is just another way to do multiplication.
If you have entries in T1 without discounts in T2, you could change the INNER JOIN to a LEFT JOIN. You would end up with the following:
ID Price Discount
4 2.00 NULL
Your logic can either account for the null in the discounted price column and take the original price instead, or just add a 0 discount record for those.
Generally it can be done with a trick with LOG/EXP functions but it is complex.
Here is a basic example:
declare #p table(id int, price money)
declare #d table(id int, discount money)
insert into #p values
(1, 2),
(2, 2),
(3, 2)
insert into #d values
(1, 0.2),
(1, 0.3),
(2, 0.4),
(3, 0.5),
(3, 0.6)
select p.id,
p.price,
p.price * ca.discount as PriceAfterDiscount
from #p p
cross apply (select EXP(SUM(LOG(1 - discount))) as discount FROM #d where id = p.id) ca
For simpler(cursor based approach) you will need a recursive CTE, but in this case you need some unique ordering column in Discounts table to run it correctly. This is shown in #Tanner`s answer.
And finally you can approach this with a regular cursor
I believe this produces the desired results using a CTE to iterate through the discounts. The solution below is re-runnable in isolation.
Edited: to include data that might not have any discounts applied in the output with a left join in the first part of the CTE.
CREATE TABLE #price
(
id INT,
price DECIMAL(5, 2)
);
CREATE TABLE #discount
(
id INT,
discount DECIMAL(5, 2)
);
INSERT INTO #price
(
id,
price
)
VALUES
(1, 2.00),
(2, 2.00),
(3, 2.00),
(4, 3.50); -- no discount on this item
INSERT INTO #discount
(
id,
discount
)
VALUES
(1, 0.20),
(1, 0.30),
(2, 0.40),
(3, 0.50),
(3, 0.60);
-- new temporary table to add a row number to discounts so we can iterate through them
SELECT d.id,
d.discount,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY d.discount) rn
INTO #GroupedDiscount
FROM #discount AS d;
-- note left join in first part of cte to get prices that aren't discounted included
WITH cte
AS (SELECT p.id,
p.price,
CASE
WHEN gd.discount IS NULL THEN
p.price
ELSE
CAST(p.price * (1.0 - gd.discount) AS DECIMAL(5, 2))
END AS discountedPrice,
gd.rn
FROM #price AS p
LEFT JOIN #GroupedDiscount AS gd
ON gd.id = p.id
AND gd.rn = 1
UNION ALL
SELECT cte.id,
cte.price,
CAST(cte.discountedPrice * (1.0 - gd.discount) AS DECIMAL(5, 2)) AS discountedPrice,
cte.rn + 1 AS rn
FROM cte
INNER JOIN #GroupedDiscount AS gd
ON gd.id = cte.id
AND gd.rn = cte.rn + 1
)
SELECT cte.id,
cte.price,
MIN(cte.discountedPrice) AS discountedPrice
FROM cte
GROUP BY id,
cte.price;
DROP TABLE #price;
DROP TABLE #discount;
DROP TABLE #GroupedDiscount;
Results:
id price discountedPrice
1 2.00 1.12
2 2.00 1.20
3 2.00 0.40
4 3.50 3.50 -- no discount
As others have said, EXP(SUM(LOG())) is the way to do the calculation. Here is basically same approach from yet another angle:
WITH CTE_Discount AS
(
SELECT Id, EXP(SUM(LOG(1-Discount))) as TotalDiscount
FROM TableTwo
GROUP BY id
)
SELECT t1.id, CAST(Price * COALESCE(TotalDiscount,1) AS Decimal(18,2)) as FinalPRice
FROM TableOne t1
LEFT JOIN CTE_Discount d ON t1.id = d.id
SQLFIddle Demo

Query matching stock trading buyers/sellers based on conditions

I'm trying to create a stored procedure that matches buyers and sellers for a fake stock market program. I eventually I'd like to use this to populate a transaction table to finalize peoples orders. This would also be in a SQL Server Agent Job. Here's the table I have:
Id UserId Type QtyRemaining Price CreatedOn
1 3 BUY 50 1.00 2012-09-09 05:25:48.4470000
2 6 BUY 50 1.00 2012-09-09 19:25:34.4300000
3 5 SELL 30 1.00 2012-09-09 19:22:59.5900000
4 3 SELL 50 0.90 2012-09-09 06:39:34.9100000
5 2 SELLALL 50 1.00 2012-09-09 04:10:01.8400000
There are several conditions that need to be satisfied to make these matches:
A buyer must look for a seller that has >= amount of shares that the buyer wants if its a 'SELL' order. If its a 'SELLALL' order then the Qty must be equal for the buyer to buy the stock. E.g. The seller must be selling 50 shares and the buyer MUST be buying 50 shares at the same price or lower.
A buyer wants the minimum price for the stock.
If there are multiple sellers with the conditions above a buyer takes the oldest selling stock first after the minimum price.
So the pairs of traders would be #1 and #4, #2 and #5. Therefore #3 would still be pending.
Here's the code I was playing around with but I can't get it to match up properly with the minimum price and the oldest first:
select o.*, oa.*, r.* from [Order] o
join OrderActivity oa on o.Id = oa.OrderId
join (
select o2.Id, o2.VideoId, o2.UserId, oa2.Price, oa2.QtyRemaining, o2.[Type] from [Order] o2
join OrderActivity oa2 on o2.Id = oa2.OrderId
where o2.Type = 'buy' and oa2.Status = 'open'
) as r on (o.VideoId = r.VideoId and oa.Price <= r.Price and r.QtyRemaining = oa.QtyRemaining and o.UserId != r.UserId)
where (o.Type = 'sell' or o.Type = 'sellall') and oa.Status = 'open'
try this
Briefly ,
1.Rank buyer based on the createddate(named as stocks in the below query) 2.Rank seller based on the price,createddate(named as lowNoldstock)3.Get the matching rank
select stocks.*,lowNoldStock.*
from (select *,row_number() over(order by createdon) as buyerrank
from stocktable(nolock) where c='buy' ) stocks
inner join
(select *,row_number() over(order by price,createdon) as sellerrank
from stocktable(nolock) where [type]='sell' or [type]='sellall' ) lowNoldstock
on (stocks.qty<=lowNoldStock.qty and lowNoldStock.type='sell')
or (lowNoldStock.type='sellall' and stocks.qty=lowNoldStock.qty and stocks.price>=lowNoldStock.price)
where lowNoldStock.sellerrank=stocks.buyerrank
test script in sql fiddle ,for some reason it is showing partial result in sql fiddle
This works in my local database
You are welcome to play with this:
declare #Transactions as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into #Transactions ( Id, UserId, Type, QtyRemaining, Price, CreatedOn ) values
( 1, 3, 'BUY', 50, 1.00, '2012-09-09 05:25:48.447' ),
( 2, 6, 'BUY', 50, 1.00, '2012-09-09 19:25:34.430' ),
( 3, 5, 'SELL', 30, 1.00, '2012-09-09 19:22:59.590' ),
( 4, 3, 'SELL', 50, 0.90, '2012-09-09 06:39:34.910' ),
( 5, 2, 'SELLALL', 50, 1.00, '2012-09-09 04:10:01.840' )
-- Split the transactions into temporary working tables.
declare #Buyers as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
declare #Sellers as Table
( Id Int, UserId Int, Type VarChar(8), QtyRemaining Int, Price Money, CreatedOn DateTime )
insert into #Buyers
select Id, UserId, Type, QtyRemaining, Price, CreatedOn
from #Transactions
where Type = 'BUY'
insert into #Sellers
select Id, UserId, Type, QtyRemaining, Price, CreatedOn
from #Transactions
where Type like 'SELL%'
-- Process the buy orders in the order in which they were created.
declare #BuyerId as Int = ( select top 1 Id from #Buyers order by CreatedOn )
declare #SellerId as Int
declare #Balance as Int
while #BuyerId is not NULL
begin
-- Pair a seller, if possible, with the current buyer.
; with Willard as (
select Row_Number() over ( order by S.Price, S.CreatedOn ) as Priority,
S.Id as S_Id, S.QtyRemaining as S_QtyRemaining,
B.QtyRemaining as B_QtyRemaining
from #Sellers as S inner join
#Buyers as B on B.Id = #BuyerId and
case
when S.Type = 'SELL' and B.QtyRemaining <= S.QtyRemaining then 1
when S.Type = 'SELLALL' and B.QtyRemaining = S.QtyRemaining then 1
else 0
end = 1
)
select #SellerId = S_Id, #Balance = S_QtyRemaining - B_QtyRemaining
from Willard
where Priority = 1
-- Display the result.
select #BuyerId as BuyerId, #SellerId as SellerId, #Balance as RemainingShares
-- Update the working tables.
if #Balance = 0
delete from #Sellers
where Id = #SellerId
else
update #Sellers
set QtyRemaining = #Balance
where Id = #SellerId
delete from #Buyers
where Id = #BuyerId
-- Find the next buy order.
set #BuyerId = ( select top 1 Id from #Buyers order by CreatedOn )
end
-- Display any unfilled orders.
select 'Unmatched Buy', *
from #Buyers
select 'Unmatched Sell', *
from #Sellers

Database Join Query

I am having a problem with a database join query and I am looking for someone to help me out.
Basically I've got two tables, Invoices and Receipts.
Invoices
Invoice ID
Amount
Date_Added
Receipts
ReceiptID
InvoiceID
Amount
Date_Added
The thing is that I need to produce a table like below, but I have multiple records in Receipts and I am pretty sure that the data is stored in a good way, just not exactly sure what the query would be.
InvoiceID RecieptID Amount Balance Date_Added
1 0 100.00 100.00 01.05.2012
1 1 100.00 0.00 02.05.2012
2 0 250.00 250.00 03.05.2012
3 0 100.00 350.00 04.05.2012
2 2 100.00 250.00 05.05.2012
Does this make sense? So it should be in date order. So effectively I can see line by line what is going on each date.
Setup:
USE tempdb;
GO
CREATE TABLE dbo.Invoices
(
InvoiceID INT,
Amount DECIMAL(12,2),
DateAdded SMALLDATETIME
);
CREATE TABLE dbo.Receipts
(
ReceiptID INT,
InvoiceID INT,
Amount DECIMAL(12,2),
DateAdded SMALLDATETIME
);
SET NOCOUNT ON;
INSERT dbo.Invoices SELECT 1, 100, '20120501'
UNION ALL SELECT 2, 250, '20120503'
UNION ALL SELECT 3, 100, '20120504';
INSERT dbo.Receipts SELECT 1, 1, 100, '20120502'
UNION ALL SELECT 2, 2, 100, '20120505';
Query:
;WITH x AS
(
SELECT InvoiceID, ReceiptID, Amount, DateAdded,
rn = ROW_NUMBER() OVER (ORDER BY DateAdded)
FROM
(
SELECT InvoiceID, ReceiptID = 0, Amount, DateAdded
FROM dbo.Invoices -- where clause?
UNION ALL
SELECT InvoiceID, ReceiptID, Amount, DateAdded
FROM dbo.Receipts -- where clause?
) AS y
),
z AS
(
SELECT xrn = x.rn, x.InvoiceID, x.ReceiptID, x.Amount, x.DateAdded,
PlusMinus = CASE WHEN x.ReceiptID > 0 THEN -x.Amount ELSE x.Amount END
FROM x LEFT OUTER JOIN x AS x2
ON x.rn = x2.rn + 1
)
SELECT InvoiceID, ReceiptID, Balance = (
SELECT SUM(COALESCE(PlusMinus, Amount))
FROM z AS z2
WHERE z2.xrn <= z.xrn
), Amount, DateAdded
FROM z
ORDER BY DateAdded;
Cleanup:
DROP TABLE dbo.Invoices, dbo.Receipts;
you can make a view that select data from the 2 tables like if the DB is oracle :
CREATE VIEW INVOICE_RECPT_VIEW as
select a.InvoiceID, b.RecieptID, b.Amount, b.Date_Added
from invoices a, receipts b
where a.InvoiceID = b.InvoiceID
order by Date_Added