Get data from SQL - sql

Select
Id,
ROW_NUMBER() over(Order By(Select 1)) as SNo,
Tableno as 'Table Number',
convert(Date, tableorder.Date) as Date,
(LTRIM(RIGHT(CONVERT(VARCHAR(20), tableorder.Date, 100), 7))) as Time,
case
when TableOrder.Status = 1 then 'Open'
when TableOrder.Status = 0 then 'Close'
else 'Undifined'
end As 'Order Status',
KotNO as 'Kot Number',
(Select SUM(NetAmount)
from Bill
where Bill.OrderId = TableOrder.Id) as 'Total Amount'
from
TableOrder
Where
IsActive = '1' And IsDelete = '0'
This query returns this data:
Id SNo Table Number Date Time Order Status Kot Number Total Amount
318 1 1 4/3/2013 12:00AM Close 1218 270
319 2 1 4/3/2013 12:00AM Close 7581 335
320 3 1 4/3/2013 12:00AM Close 7582 110
321 4 1 4/3/2013 12:00AM Close 7585 165
323 5 4 4/3/2013 12:00AM Close 7586 80
324 6 1 4/3/2013 12:00AM Close 7587 45
325 7 3 4/3/2013 12:00AM Close 7588 150
326 8 1 4/3/2013 12:00AM Close 7589 145
327 9 1 4/3/2013 12:00AM Close 7590 70
328 10 4 4/3/2013 12:00AM Close 7591 120
I want to add 2 columns in this query for Vat 5% rate Amount = vat type id 2 and Vat 15% rate Amount = vat Type id 4
I have a second query like this in this query I use TableOrder id = 319
Select
Vt.Id, Vt.Description,
abs(Vt.Rate) as VRate,
Sum((( ItemPrice * Qty) - NetAmount)) as VatAmount
from
BillItem1 as B1
Left JOIN
ItemDescription ItD ON ItD.Id = B1.itemId
Left Join
VatType Vt on Vt.Id = ItD.TaxId
where
B1.IsActive = 1 and B1.IsDelete = 0
and B1.OrderId = 319
Group By
Vt.Id, Vt.Rate, Vt.Description
Order By
SUM((ItemPrice*Qty) - NetAmount) DESC
Output:
Id Description VRate VatAmount
2 Food 5 8.8094
4 Cold drinks 15 7.143
In this query get vat 5% for Vat type Id = 2 and 15 % for Vat type Id = 4 in above data 390 TableOrder Id Show Total Amount 270 and Vat Amount is (8.8094+7.143)
I want this amount show in below data in column
Table relation is
In Table BillItem Table I have Item Id and TableOrder Id
In Item Table I have VatTypeId

I think I see what you're after. Try the following...
SELECT
Id,
ROW_NUMBER() OVER(ORDER BY(SELECT 1)) as SNo,
Tableno AS 'Table Number',
convert(DateTime, tableorder.Date) AS [Date],
(LTRIM(RIGHT(CONVERT(VARCHAR(20), tableorder.Date, 100), 7))) as [Time],
CASE
WHEN TableOrder.Status = 1 THEN 'Open'
WHEN TableOrder.Status = 0 THEN 'Close'
ELSE 'Undefined'
END AS 'Order Status',
KotNO AS 'Kot Number',
SUM(Bill.NetAmount) AS 'Total Amount',
SUM(Bill.NetAmount) * 0.05 AS 'Tax 5',
SUM(Bill.NetAmount) * 0.15 AS 'Tax 15'
FROM
TableOrder INNER JOIN
Bill
ON TableOrder.Id = Bill.OrderId
WHERE
IsActive = '1' And
IsDelete = '0'
GROUP BY
Id,
Tableno,
TableOrder.[Date],
TableOrder.Status,
KotNO
See how that works for you.

Related

SQL query to get top 24 records, then average the first 12 and bottom 12

I'm attempting to analyze each account's performance (A_Count & B_Count) during their first year versus their second year. This should only return clients who have at least 24 months of totals (records).
Volume Table
Account
ReportDate
A_Count
B_Count
1001A
2019-01-01
47
100
1001A
2019-02-01
50
105
1002A
2019-02-01
50
105
I think I'm on the right track by wanting to grab the top 24 records for each account (only if 24 exist) and then grabbing the top 12 and bottom 12, but not sure how to get there.
I guess ideal output would be:
Account
YR1_A_Avg
YR1_B_Avg
YR2_A_Avg
YR2_B_Avg
FirstDate
LastDate
1001A
47
100
53
115
2019-01-01
2021-12-31
1002A
50
105
65
130
2019-02-01
2022-01-01
1003A
15
180
38
200
2017-05-01
2019-04-01
I'm not too worried about performance.
Assuming there are no gaps in ReportDate (per Account).
select Account
,avg(case when year_index = 1 then A_Count end) as YR1_A_Avg
,avg(case when year_index = 1 then B_Count end) as YR1_B_Avg
,avg(case when year_index = 2 then A_Count end) as YR2_A_Avg
,avg(case when year_index = 2 then B_Count end) as YR2_B_Avg
,min(ReportDate) as FirstDate
,max(ReportDate) as LastDate
from
(
select *
,count(*) over(partition by Account) as cnt
,(row_number() over(partition by Account order by ReportDate)-1)/12 +1 as year_index
from Volume
) t
where cnt >= 24 and year_index <= 2
group by Account

Running assignment of values with break T-SQL

With the below table of data
Customer
Amount Billed
Amount Paid
Date
1
100
60
01/01/2000
1
100
40
01/02/2000
2
200
150
01/01/2000
2
200
30
01/02/2000
2
200
10
01/03/2000
2
200
15
01/04/2000
I would like to create the next two columns
Customer
Amount Billed
Amount Paid
Assigned
Remainder
Date
1
100
60
60
40
01/01/2000
1
100
40
40
0
01/02/2000
2
200
150
150
50
01/01/2000
2
200
30
30
20
01/02/2000
2
200
10
10
10
01/03/2000
2
200
15
10
-5
01/04/2000
The amount paid on each line should be removed from the amount billed and pushed onto the next line for the same customer. The process should continue until there are no more records or the remainder is < 0.
Is there a way of doing this without a cursor? Maybe a recursive CTE?
Thanks
As I mentioned in the comments, this is just a cumulative SUM:
WITH YourTable AS(
SELECT *
FROM (VALUES(1,100,60 ,CONVERT(date,'01/01/2000')),
(1,100,40 ,CONVERT(date,'01/02/2000')),
(2,200,150,CONVERT(date,' 01/01/2000')),
(2,200,30 ,CONVERT(date,'01/02/2000')),
(2,200,10 ,CONVERT(date,'01/03/2000')),
(2,200,15 ,CONVERT(date,'01/04/2000')))V(Customer,AmountBilled,AmountPaid,[Date]))
SELECT Customer,
AmountBilled,
AmountPaid,
AmountBilled - SUM(AmountPaid) OVER (PARTITION BY Customer ORDER BY [Date] ASC
ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS Remainder,
[Date]
FROM YourTable
ORDER BY Customer,
[Date];
Note this returns -5 for the last row, not 5, as 200 - 205 = -5. If you want 5 wrap the whole expression in an absolute function.
You can achieve this using recursive CTE as well.
DECLARE #customer table (Customer int, AmountBilled int, AmountPaid int, PaidDate date)
insert into #customer
values
(1 ,100, 60 ,'01/01/2000')
,(1 ,100, 40 ,'01/02/2000')
,(2 ,200, 150 ,'01/01/2000')
,(2 ,200, 30 ,'01/02/2000')
,(2 ,200, 10 ,'01/03/2000')
,(2 ,200, 15 ,'01/04/2000');
;WITH CTE_CustomerRNK as
(
SELECT *, ROW_NUMBER() OVER(PARTITION BY customer order by paiddate) AS RNK
from #customer),
CTE_Customer as
(
SELECT customer, AmountBilled, AmountPaid, (amountbilled-amountpaid) as remainder, paiddate ,RNK FROM CTE_CustomerRNK where rnk = 1
union all
SELECT r.customer, r.AmountBilled, r.AmountPaid, (c.remainder - r.AmountPaid) as remainder, r.PaidDate, r.rnk
FROM CTE_CustomerRNK as r
inner join CTE_Customer as c
on c.Customer = r.Customer
and r.rnk = c.rnk + 1
)
SELECT customer, AmountBilled, AmountPaid, remainder, paiddate
FROM CTE_Customer order by Customer
customer
AmountBilled
AmountPaid
remainder
paiddate
1
100
60
40
2000-01-01
1
100
40
0
2000-01-02
2
200
150
50
2000-01-01
2
200
30
20
2000-01-02
2
200
10
10
2000-01-03
2
200
15
-5
2000-01-04

SQL sum of two fields

I have a table with following fields
vchnrno credit debit amount
JV1 BA10 0 100
JV1 BA11 0 10
JV1 0 BC10 90
JV1 0 BC11 20
Usually sum of credit side= sum of debit side for every JV
here
credit = sum of BA10+ BA11 = 110
debit = sum of BC10 + BC 11 = 110
I want to find all JV's whose sum of debit - sum of credit >0
Looks like SUM + CASE might do the job. Here's how:
SQL> with test (vchnrno, credit, debit, amount) as
2 (select 'JV1', 'BA10', '0' , 100 from dual union all
3 select 'JV1', 'BA11', '0' , 10 from dual union all
4 select 'JV1', '0' , 'BC10', 90 from dual union all
5 select 'JV1', '0' , 'BC11', 20 from dual union all
6 --
7 select 'xxx', 'XX20', '0' , 50 from dual union all
8 select 'xxx', '0' , 'xx30', 70 from dual
9 )
10 select vchnrno, sum_credit, sum_debit, sum_debit - sum_credit diff
11 from (select vchnrno,
12 sum(case when credit <> '0' then amount end) sum_credit,
13 sum(case when debit <> '0' then amount end) sum_debit
14 from test
15 group by vchnrno
16 )
17 where sum_debit - sum_credit > 0;
VCH SUM_CREDIT SUM_DEBIT DIFF
--- ---------- ---------- ----------
xxx 50 70 20
SQL>
I included vchnrno = xxx into sample data because JV1 doesn't match criteria (sum of debit = sum of credit) so it wouldn't be returned anyway.

SQL cumulative sum until a flag value and resetting the sum

I'm still learning SQL and I'm trying to figure out a problem that I wasn't able to solve. So my problem is that I'm trying to select a table(let say Expense), ordered by date and in the table I have a column named Charged and I want to add charges to be cumulative(This part I figured out). However after that I have another column that will be acting as a flag called PayOut. When the PayOut value is 1 I want the summation of Charged(SumValue) to reset to zero. How would I do this? Here is what I have tried and the current output I get and what output I want. Note: I saw some posts using CTE's but wasn't the same scenario and more complex.
select ex.date,
ex.Charged,
(case when(ex.PayOut=1) then 0
else sum(ex.Charged) over (order by ex.date)end) as SumValue,
ex.PayOut
from Expense ex
order by ex.date asc
The data looks like this
Date Charged PayOut
01/10/2018 10 0
01/20/2018 5 0
01/30/2018 3 0
02/01/2018 0 1
02/11/2018 12 0
02/21/2018 15 0
Output I get
Date Charged PayOut SumValue
01/10/2018 10 0 10
01/20/2018 5 0 15
01/30/2018 3 0 18
02/01/2018 0 1 0
02/11/2018 12 0 30
02/21/2018 15 0 45
Output Wanted
Date Charged PayOut SumValue
01/10/2018 10 0 10
01/20/2018 5 0 15
01/30/2018 3 0 18
02/01/2018 0 1 0
02/11/2018 12 0 12
02/21/2018 15 0 27
Just create group from your PayOut Column and use it as a partition in OVER
WITH Expense AS (
SELECT CAST('01/10/2018' AS DATE) AS Date, 10 AS Charged, 0 AS PayOut
UNION ALL SELECT CAST('01/20/2018' AS DATE), 5, 0
UNION ALL SELECT CAST('01/30/2018' AS DATE), 3, 0
UNION ALL SELECT CAST('02/01/2018' AS DATE), 0, 1
UNION ALL SELECT CAST('02/11/2018' AS DATE), 12, 0
UNION ALL SELECT CAST('02/21/2018' AS DATE), 15, 0
)
SELECT
dat.date
,dat.Charged
,dat.PayOut
,dat.PayOutGroup
,SUM(dat.Charged) OVER (PARTITION BY dat.PayOutGroup ORDER BY dat.date) as SumValue
FROM (
SELECT
e.date
,e.Charged
,e.PayOut
,SUM(e.PayOut) OVER (ORDER BY e.date) AS PayOutGroup
FROM Expense e
) dat

Stuck with this query

My database looks like this
DailyData
rID int
Stock varchar
rDate date
Shares int
price float
What I am trying to do is get the data for two dates.
Sample data
rID stock rDate Shares price
11 Stock1 21/03/2016 15 1.22
12 Stock2 21/03/2016 22 2.23
13 Stock3 21/03/2016 17 3.32
14 Stock4 21/03/2016 10 4.24
15 Stock1 22/03/2016 15 1.25
16 Stock2 22/03/2016 20 2.27
17 Stock3 22/03/2016 17 3.32
18 Stock1 23/03/2016 15 1.28
19 Stock2 23/03/2016 20 2.20
20 Stock3 23/03/2016 17 3.32
21 Stock4 23/03/2016 10 4.24
Expected output
Stock Shares-21 Shares-20
Stock1 15 15
Stock2 22 20
Stock3 17 17
Stock4 10 0
My query against a SQL Server CE database:
Select
DD1.Stock, sum(DD1.Shares) as Shares-21, sum(DD2.shares) as Shares-20
from
DailyData DD1, DailyData DD2
where
DD1.rDate = '21/03/2016' and DD2.rDate = '20/03/2016'
and DD1.Stock = DD2.Stock
group by
DD1.Stock
I am getting 7 rows of data instead of 4.
Please help with the query.
******************************* new modification *********************
i followed as suggested but it seems not to work. this is a actual sql script.
Select P.pName,DD.Stock,
sum(case DD.rDate when '03/21/2016' then DD.Shares else 0 end) as Shares21,
sum(case DD.rDate when '03/20/2016' then DD.Shares else 0 end) as Shares20
from dailyData DD, Portfolios P
where DD.rDate = '03/21/2016' or DD.rDate = '03/20/2016'
and DD.pID = P.pID
and DD.pID=1
group by P.pName,DD.stock
order by P.pName,DD.Stock
now for pID=1 there are 23 records for 20-Mar and 21-Mar
upon running this query, it returns way more than 23. I am expecting 23 records only.
It actually does not need to use JOIN. You could use CASE WHEN statement like this
SELECT stock,
Sum(CASE rdate
WHEN '21/03/2016' THEN shares
ELSE 0
END) AS Shares21,
Sum(CASE rdate
WHEN '20/03/2016' THEN shares
ELSE 0
END) AS Shares20
FROM dailydata
WHERE rdate = '21/03/2016'
OR rdate = '20/03/2016'
GROUP BY stock
You could use PIVOT with DATEPART
SELECT Stock, [21] AS [Shares-21], [20] AS [Shares-20] FROM
(
SELECT s.Stock, Datepart(d,s.rDate) rDate , s.Shares FROM DailyData s
) src
PIVOT
(
MAX(Shares) for rDate in ([21], [20])
) pvt