SQL Get amount paid in statement account in different dates - sql

I have this schema
Item:
| ItemId | Name | Price |
|--------|-------|-------|
| 1 | Item1| 5.00 |
| 2 | Item2| 2.00 |
OrderHeader:
| OrderId| OrderNum| OrderDate |
|--------|---------|------------|
| 1 | ORD1 | 2017-05-10 |
| 2 | ORD2 | 2017-05-12 |
OrderDetails:
|OrderId| ItemId | Total |
--------|--------|---------
| 1 | 1 | 3 |
| 2 | 1 | 2 |
How can I get this result:
|ItemId | OrderId | Paid | Debt |
--------|-----------|----------------
| 1 | 1 | 3 | 2 |
| 1 | 2 | 5 | 0 |
In the result set, the column paid must contains the total of previous payments and plus the new one.
How can I use a Common table expression for example to solve this?

This, you should have provided us:
DECLARE #Item TABLE (Id int, [Name] varchar(15), Price int)
DECLARE #OrderDetails TABLE (OrderId int, ItemId int, Total int)
INSERT INTO #ITEM VALUES (1, 'ITEM1', 5), (2, 'ITEM2', 2)
INSERT INTO #OrderDetails VALUES (1, 1, 3), (2, 1, 2)
This, seems to work, and I think it still has room for improvement:
SELECT OrderId, ItemId, [SUM1], R.Price - [SUM1]
FROM #OrderDetails AS A
LEFT JOIN #Item AS R ON A.ItemId = R.Id
OUTER APPLY (
SELECT SUM(SUB1.TOTAL) AS [SUM1]
FROM #OrderDetails AS SUB1
WHERE SUB1.ItemId = A.ItemId AND SUB1.OrderId <= A.OrderId
) AS B

Related

How to show values that has a suitable pair in sql server

I have a table like this
---------------------------------------------
Id | TransactionId | Amount | Account| crdr |
---------------------------------------------
1 | 1 | 100 | 11111 | 1 |
2 | 2 | 130 | 13133 | 1 |
3 | 1 | 100 | 12111 | 2 |
4 | 2 | 130 | 13233 | 2 |
5 | 2 | 110 | 12122 | 1 |
What I need to display is, show these records as pairs (I have grouped them by transactionid, Amount).
SELECT TransactionId ,Amount , Account, CrDr
FROM Table1 ORDER BY TransactionId ASC,Amount ASC, CrDr ASC
But I want to ignore the records which dont have a pair, as a Example for this above records set result should be like this
---------------------------------------------
TransactionId | Amount | Account| crdr |
---------------------------------------------
1 | 100 | 11111 | 1 |
1 | 100 | 12111 | 2 |
2 | 130 | 13133 | 1 |
2 | 130 | 13233 | 2 |
Can someone suggest a solution for this.
You could use a correlated subquery with a NOT EXISTS condition to ensure that another record exists with the same TransactionId and Amount:
SELECT TransactionId ,Amount , Account, CrDr
FROM Table1 t
WHERE EXISTS (
SELECT 1
FROM Table1 t1
WHERE
t.id <> t1.id
AND t.TransactionId = t1.TransactionId
AND t.Amount = t1.Amount
)
ORDER BY TransactionId ASC,Amount ASC, CrDr ASC
Demo on DB Fiddle:
TransactionId | Amount | Account | CrDr
------------: | -----: | ------: | ---:
1 | 100 | 11111 | 1
1 | 100 | 12111 | 2
2 | 130 | 13133 | 1
2 | 130 | 13233 | 2
Try this:
DECLARE #DataSource TABLE
(
[Id] INT
,[TransactionId] INT
,[Amount] INT
,[Account] INT
,[crdr] INT
);
INSERT INTO #DataSource ([Id], [TransactionId], [Amount], [Account], [crdr])
VALUES (1, 1, 100, 11111, 1)
,(2, 2, 130, 13133, 1)
,(3, 1, 100, 12111, 2)
,(4, 2, 130, 13233, 2)
,(5, 2, 110, 12122, 1);
WITH DataSource AS
(
SELECT *
,COUNT(*) OVER (PARTITION BY [TransactionId], [Amount]) AS [Count]
FROM #DataSource
)
SELECT *
FROM DataSource
WHERE [Count] = 2
ORDER BY TransactionId ASC,Amount ASC, CrDr ASC;
Try this: This this simplest solution of this problem
;with cte
as
(
select TransactionId, Amount
from Table1
group by TransactionId, Amount
having count(*) > 1
)
select *
from Table1 t
inner join cte c on t.TransactionId = c.TransactionId and t.Amount = c.Amount

Select MAX date using data from several columns SQL

I know this is a much asked question and I've had a look through whats already available but I believe my case is slightly unique (and if it's not please point me in the right direction).
I am trying to find the latest occurrence of a row associated to a user a currently across two tables and several columns.
table: statusUpdate
+-------+-----------+-----------+-------------------+
| id | name | status | date_change |
+-------+-----------+-----------+-------------------+
| 1 | Matt | 0 | 01-01-2001 |
| 2 | Jeff | 1 | 01-01-2001 |
| 3 | Jeff | 2 | 01-01-2002 |
| 4 | Bill | 2 | 01-01-2001 |
| 5 | Bill | 3 | 01-01-2004 |
+-------+-----------+-----------+-------------------+
table: relationship
+-------+-----------+--------------+
| id | userID |stautsUpdateID|
+-------+-----------+--------------+
| 1 | 22 | 1 |
| 2 | 33 | 2 |
| 3 | 33 | 3 |
| 4 | 44 | 4 |
| 5 | 44 | 5 |
+-------+-----------+--------------+
There is a third table which links userID to its own table but these sample tables should be good enough to get my question over.
I am looking to get the latest status change by date. The problem currently is that it returns all instances of a status change.
Current results:
+-------+---------+-----------+-------------------+
|userID |statusID | status | date_change |
+-------+---------+-----------+-------------------+
| 33 | 2 | 1 | 01-01-2001 |
| 33 | 3 | 2 | 01-01-2002 |
| 44 | 4 | 2 | 01-01-2001 |
| 44 | 5 | 3 | 01-01-2004 |
+-------+---------+-----------+-------------------+
Expected results:
+-------+-----------+-----------+-------------------+
|userID |statusID | status | date_change |
+-------+-----------+-----------+-------------------+
| 33 | 3 | 2 | 01-01-2002 |
| 44 | 5 | 3 | 01-01-2004 |
+-------+-----------+-----------+-------------------+
I hope this all makes sense, please ask for more information otherwise.
Just to reiterate I just want to return the latest instance of a users status change by date.
Sample code of one of my attempts:
select
st.ID, st.status, st.date_change, r.userID
from statusUpdate st
inner join Relationship r on st.ID = r.statusUpdateID
inner join (select ID, max(date_change) as recent from statusUpdate
group by ID) as y on r.stausUpdateID = y.ID and st.date_change =
y.recent
Hope someone can point me in the right direction.
use row_number() to get the last row by user
select *
from
(
select st.ID, st.status, st.date_change, r.userID,
rn = row_number() over (partition by r.userID order by st.date_change desc)
from statusUpdate st
inner join Relationship r on st.ID = r.statusUpdateID
) as d
where rn = 1
I ADDED MAX condition to your answer
CREATE TABLE #Table1
([id] int, [name] varchar(4), [status] int, [date_change] datetime)
;
INSERT INTO #Table1
([id], [name], [status], [date_change])
VALUES
(1, 'Matt', 0, '2001-01-01 00:00:00'),
(2, 'Jeff', 1, '2001-01-01 00:00:00'),
(3, 'Jeff', 2, '2002-01-01 00:00:00'),
(4, 'Bill', 2, '2001-01-01 00:00:00'),
(5, 'Bill', 3, '2004-01-01 00:00:00')
;
CREATE TABLE #Table2
([id] int, [userID] int, [stautsUpdateID] int)
;
INSERT INTO #Table2
([id], [userID], [stautsUpdateID])
VALUES
(1, 22, 1),
(2, 33, 2),
(3, 33, 3),
(4, 44, 4),
(5, 44, 5)
select
max(st.ID) id , max(st.status) status , max(st.date_change) date_change, r.userID
from #Table1 st
inner join #Table2 r on st.ID = r.stautsUpdateID
inner join (select ID, max(date_change) as recent from #Table1
group by ID) as y on r.stautsUpdateID = y.ID and st.date_change =
y.recent
group by r.userID
output
id status date_change userID
1 0 2001-01-01 00:00:00.000 22
3 2 2002-01-01 00:00:00.000 33
5 3 2004-01-01 00:00:00.000 44

Unable to write the SQL query as per my required output

I have two tables in MS Access database (Table1, Table2) with same columns namely Id, PartNo, Nomenclature, Quantity and Wksp. Id is the primary key in them. Id can be same in both tables. Now I want to write a query to get the output as shown under required output. How can I achieve this?
Table1
+----+--------+--------------+----------+----------+
| Id | PartNo | Nomenclature | Quantity | Wksp |
+----+--------+--------------+----------+----------+
| 1 | Part1 | Nomenc1 | 2 | Wksp1 |
| 2 | Part2 | Nomenc2 | 4 | Wksp1 |
| 3 | Part3 | Nomenc3 | 6 | Wksp1 |
| 4 | Part4 | Nomenc4 | 8 | Wksp1 |
+----+--------+--------------+----------+----------+
Table2
+----+--------+--------------+----------+-------+
| Id | PartNo | Nomenclature | Quantity | Wksp |
+----+--------+--------------+----------+-------+
| 1 | Part1 | Nomenc1 | 1 | Wksp2 |
| 2 | Part2 | Nomenc2 | 3 | Wksp2 |
| 3 | Part3 | Nomenc3 | 5 | Wksp2 |
| 4 | Part11 | Nomenc11 | 7 | Wksp2 |
| 5 | Part7 | Nomenc7 | 9 | Wksp2 |
+----+--------+--------------+----------+-------+
Required Output
+----+--------+--------------+-------+-------+
| Id | PartNo | Nomenclature | Wksp1 | Wksp2 |
+----+--------+--------------+-------+-------+
| 1 | Part1 | Nomenc1 | 2 | 1 |
| 2 | Part2 | Nomenc2 | 4 | 3 |
| 3 | Part3 | Nomenc3 | 6 | 5 |
| 4 | Part11 | Nomenc11 | 0 | 7 |
| 5 | Part7 | Nomenc7 | 0 | 9 |
| 6 | Part4 | Nomenc4 | 8 | 0 |
+----+--------+--------------+-------+-------+
First create a query to collect the IDs:
SELECT Id
FROM Table1
UNION
SELECT Id
FROM Tabel2;
Save this as, say, TBboth.
Then use this as source:
SELECT
TBboth.Id,
Nz(Table1!PartNo, Table2!PartNo) AS PartNo,
Nz(Table1!Nomenclature, Table2!Nomenclature) As Nomenclature,
Sum(Nz(Table1!Quantity,0)) AS Wksp1,
Sum(Nz(Table2!Quantity,0)) AS Wksp2
FROM
(TBboth
LEFT JOIN
TB1 ON TBboth.Id = TB1.Id)
LEFT JOIN
TB2 ON TBboth.Id = TB2.Id
GROUP BY
TBboth.Id,
Nz(Table1!PartNo, Table2!PartNo),
Nz(Table1!Nomenclature, Table2!Nomenclature);
Try this:
select Id , PartNo , Nomenclature, ISNULL(Wksp1,0) Wksp1, ISNULL(Wksp2,0) Wksp2
from
(
select Id , PartNo , Nomenclature ,Wksp, sum(Quantity) 'count' from Table1
group by Id , PartNo , Nomenclature,Wksp
union all
select Id , PartNo , Nomenclature ,Wksp, sum(Quantity) 'count' from Table2
group by Id , PartNo , Nomenclature,Wksp
) src
pivot
(
sum(count)
for Wksp in ([Wksp1], [Wksp2])
) P;
Try with This Method if you are using MS SQL Server
DECLARE #T1 TABLE
(
Id INT,
Part VARCHAR(20),
Qty INT,
Wksp VARCHAR(20) DEFAULT('Wksp 1')
)
DECLARE #T2 TABLE
(
Id INT,
Part VARCHAR(20),
Qty INT,
Wksp VARCHAR(20) DEFAULT('Wksp 2')
)
INSERT INTO #T1
VALUES(1,'Part1',10,'Wksp 1'),(2,'Part2',15,'Wksp 1'),(3,'Part3',12,'Wksp 1')
INSERT INTO #T1
VALUES(1,'Part1',10,'Wksp 2'),(2,'Part2',15,'Wksp 2'),(4,'Part4',20,'Wksp 2')
SELECT
Id = coalesce(a.id,b.id),
Part = coalesce(a.Part,b.Part),
Qty = coalesce(a.Qty,b.Qty),
Wksp =coalesce(a.Wksp,b.Wksp)
FROM #T1 A
FULL JOIN #T2 b
on a.Id = b.Id

Bring information from 2 tables and put it in the same column

I have this table of articles
---------------------------------------------
| Article | Location | existence |
---------------------------------------------
| 200116 | cc3111 | 1 |
---------------------------------------------
| 200116 | ee3091 | 1 |
---------------------------------------------
And this count table
----------------------------------------------------
| Article | Location | Quantity |
----------------------------------------------------
| 200116 | cc3111 | 10 |
----------------------------------------------------
| 200116 | EE3091 | 8 |
----------------------------------------------------
| 200116 | EE2102 | 5 |
----------------------------------------------------
| 200116 | DD5131 | 7 |
----------------------------------------------------
What I'm trying to do is give me one result like the next.
--------------------------------------------------------------------------
| Article | Location | Existence | Quantity | DIF |
--------------------------------------------------------------------------
| 200116 | CC3111 | 1 | 10 | 9 |
--------------------------------------------------------------------------
| 200116 | EE3091 | 1 | 8 | 7 |
--------------------------------------------------------------------------
| 200116 | DD5131 | 0 | 7 | 7 |
--------------------------------------------------------------------------
| 200116 | EE2102 | 0 | 5 | 5 |
----------------------------- -------------------------------------------
But without doing it with a Union since then I have to make another query, I just do not know how to join it without usingUnion.
-SOME HELP TO PERFORM THIS QUERY
-I do not know how to add the location in the same column
This looks like a left join:
select t2.*, coalesce(t1.existence, 0) as existence,
(t2.quantity - coalesce(t1.existence, 0)) as dif
from t2 left join
t1
on t2.article = t1.article and t2.location = t1.location;
Here's another option...
IF OBJECT_ID('tempdb..#Article', 'U') IS NOT NULL
DROP TABLE #Article;
CREATE TABLE #Article (
Article INT NOT NULL,
Location CHAR(6) NOT NULL,
Existance INT NOT NULL
);
IF OBJECT_ID('tempdb..#Counts', 'U') IS NOT NULL
DROP TABLE #Counts;
CREATE TABLE #Counts (
Article INT NOT NULL,
Location CHAR(6) NOT NULL,
Quantity INT NOT NULL
);
INSERT #Article(Article, Location, Existance) VALUES
(200116, 'cc3111', 1), (200116, 'ee3091', 1);
INSERT #Counts(Article, Location, Quantity) VALUES
(200116, 'cc3111', 10), (200116, 'EE3091', 8),
(200116, 'EE2102', 5), (200116, 'DD5131', 10);
SELECT * FROM #Article a;
SELECT * FROM #Counts c;
--=====================================================
SELECT
Article = COALESCE(a.Article, c.Article),
Location = COALESCE(a.Location, c.Location),
Existance = COALESCE(a.Existance, 0),
Quantity = COALESCE(c.Quantity, 0),
DIF = COALESCE(c.Quantity, 0) - COALESCE(a.Existance, 0)
FROM
#Article a
FULL JOIN #Counts c
ON a.Article = c.Article
AND a.Location = c.Location;
You need to JOIN these tables instead of doing a UNION. The former will put columns side by side, whereas the latter will stack two similar sources together...

Check values in all previous rows in SQL table

I have the following SQL table:
declare #t table(START_DATE datetime,INDEX_ID int, GROSS_SALES_PRICE decimal(10,2));
insert into #t values
('20150619',10000410,38)
,('20170311',10000410,26.49)
,('20170312',10000410,26.49)
,('20170317',10000410,38)
,('20170318',10000410,38)
,('20170321',10000410,38);
I would like to check if there are any temporary changes in GROSS_SALES_PRICE
For example, in this table I have a price 38, then I have two rows with 26.49 and then 38 again. There can be any number of lower price rows so I think I have to check multiple previous rows?
I would like to make third column with value of 1 if this situation happened:
WITH maxPrice AS
(
SELECT INDEX_ID, MAX(GROSS_SALES_PRICE) MaxPrice
FROM #t
GROUP BY INDEX_ID
)
SELECT t.INDEX_ID, t.GROSS_SALES_PRICE,
CASE WHEN GROSS_SALES_PRICE < maxPrice.MaxPrice THEN 1 ELSE 0 END AS [CHANGED]
FROM #t t
INNER JOIN maxPrice
ON maxPrice.INDEX_ID = t.INDEX_ID;
GO
INDEX_ID | GROSS_SALES_PRICE | CHANGED
-------: | :---------------- | ------:
10000410 | 38.00 | 0
10000410 | 26.49 | 1
10000410 | 26.49 | 1
10000410 | 38.00 | 0
10000410 | 38.00 | 0
10000410 | 38.00 | 0
dbfiddle here