I have a table with the following data in it:
Account number Amount
13 40
34 30
14 30
13 60
14 10
I would like to know how I can write a query to return the following results
Account number Total amount
13 100
14 40
34 30
The query should calculate the sum of all of the amounts in the amount column that share the same account number.
Any help would be much appreciated!
Use Group By + SUM
SELECT [Account number],
SUM(Amount) As [Total Amount]
FROM dbo.Table1
GROUP BY [Account Number]
ORDER BY SUM(Amount) DESC
Demo
Please try:
select
[Account Number],
sum(Amount) Amount
from
YourTable
Group by [Account Number]
Related
In order to generate running total of Sales Qty in MS Access, I used below query, it is working as expected
SELECT ID, [Product Line], DSUM("[Qty]","[SalesData]","[Product Line] like '*Electronics*' AND [ID] <=" & [ID]) AS RunningTotal, FROM SalesData WHERE ([Product Line]) Like '*Electronics*';
Now, I need to filter all the record with RunningTotal < 100,
I ran the below sub query
SELECT * FROM(
SELECT ID, [Product Line], DSUM("[Qty]","[SalesData]","[Product Line] like '*Electronics*' AND [ID] <=" & [ID]) AS RunningTotal, FROM SalesData WHERE ([Product Line]) Like '*Electronics*')
DSUM("[Qty]","[","[Product Line] like '*Electronics*' AND [ID] <=" & [ID]) < 100;
It is not working and table is freezed many times while running this query
Data Table
ID Product Line Qty RunningTotal
1 Electronics 15 15
2 R.K. Electricals 20 20
3 Samsung Electronics 10 25
4 Electricals 30 50
5 Electricals 45 95
6 Electronics Components 18 43
7 Electricals 25 120
8 Electronics 50 93
9 Electricals Machines 65 185
10 Electronics 15 108
11 ABC Electronics Ltd 52 160
12 Electricals 15 200
Here RunningTotal is calculated field (not table field)
Electricals RunningTotal is different and Electronics RunningTotal is different
Expected output for Product Line like Electronics with RunningTotal < 100
ID Product Line Qty RunningTotal
1 Electronics 15 15
3 Samsung Electronics 10 25
6 Electronics Components 18 43
8 Electronics 50 93
Could you please help me to rectify the above query?
Thanks in advance.
Rather than using domain aggregate functions (such as DSum) which are known to be notoriously slow, I would suggest using a correlated subquery, such as the following:
select q.* from
(
select t.id, t.[product line], t.qty,
(
select sum(u.qty)
from salesdata u
where u.[product line] = t.[product line] and u.id <= t.id
) as runningtotal
from salesdata t
where t.[product line] like "*Electronics*"
) q
where q.runningtotal < 100
EDIT:
select t.*, q.runningtotal from salesdata t inner join
(
select t.id,
(
select sum(u.qty)
from salesdata u
where u.[product line] like "*Electronics*" and u.id <= t.id
) as runningtotal
from salesdata t
) q on t.id = q.id
where q.runningtotal < 100 and t.[product line] like "*Electronics*"
here is my data,
Table 1:
STORAGE HANDLING TOTAL BILLING
--------------------------------------
1300 10900
0 10950
0 6000
0 5950
Table 2:
LINER REVENUE
---------------
1300
250
3000
200
I need to calculate Total Billing:
Total Billing = Storage+Handling+Liner Revenue.
Can someone guide me a query for this.
Hope this helps,
SELECT h.Storage+h.Handling+j.[Liner Revenue]
From(SELECT
STORAGE
,HANDLING
,[TOTAL BILLING]
,ROW_NUMBER () over(order by rand()) as p
FROM [Table 1] )h
INNER JOIN
(SELECT
[LINER REVENUE]
,ROW_NUMBER () over(order by rand()) as p
FROM [Table 2] )j
on h.p=j.p
I Have a table of Monthly Sales
Quarter Month Monthly Sales
1 Jan 586
1 Feb 204
1 Mar 465
2 Apr 684
2 May 756
2 Jun 97
Now I want a result a below
Quarter Month Monthly Sales Total Sales% Quarterly Sales%
1 Jan 586 20.98% 45.25%
1 Feb 204 7.30% 16.25%
1 Mar 465 16.65% 37.05%
2 Apr 684 24.49% 44.50%
2 May 756 27.07% 49.18%
2 Jun 97 3.47 6.31%
Total Sales% = Monthly Sales/Sum (Monthly Sales)
Quarterly Sales% = Monthly Sales/ Quarterly Sales
How Do i Get this output in SQL?
Using CROSS APPLY:
SELECT
s.*,
[Total Sales %] = CAST(CAST(s.MonthlySales/t.Total * 100.00 AS DECIMAL(5, 2)) AS VARCHAR(5)) +'%',
[Quarterly Sales %] = CAST(CAST(s.MonthlySales/q.QtrTotal* 100.00 AS DECIMAL(5, 2)) AS VARCHAR(5)) +'%'
FROM Sales s
CROSS APPLY(
SELECT Total = SUM(MonthlySales) * 1.0
FROM Sales
) t
CROSS APPLY(
SELECT QtrTotal = SUM(MonthlySales) * 1.0
FROM Sales
WHERE Quarter = s.Quarter
GROUP BY Quarter
)q
If you are using Oracle you should be using the ratio_to_report analytic function. (http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions124.htm)
select quarter,
month,
monthly_sales,
round(ratio_to_report(monthly_sales) over() * 100, 2) as total_sales_pct,
round(ratio_to_report(monthly_sales) over(partition by quarter) * 100, 2) as qtr_sales_pct
from monthly_sales;
Fiddle: http://sqlfiddle.com/#!4/71aeb7/1/0
The above assumes you're selecting data for just one year as the analytic function will interpret the given result set. If your query spans multiple years you need to additionally partition by whatever column represents the year in your real table.
Today my issue has to do with marking continuous periods of time where a given criteria is met. My raw data of interest looks like this.
Salesman ID Pay Period ID Total Commissionable Sales (US dollars)
1 101 525
1 102 473
1 103 672
1 104 766
2 101 630
2 101 625
.....
I want to mark continous periods of time where a salesman has achieved $500 of sales or more. My ideal result should look like this.
[Salesman ID] [Start time] [End time] [# Periods] [Average Sales]
1 101 101 1 525
1 103 107 5 621
2 101 103 3 635
3 104 106 3 538
I know how to everything else, but I cannot figure out a non-super expensive way to identify start and end dates. Help!
Try something like this. The innermost select-statement basically adds a new column to the original table with a flag determining when a new group begins. Outside this statement, we use this flag in a running total, that then enumerates the groups - we call this column [Group ID]. All that is left, is then to filter out the rows where [Sales] < 500, and group by [Salesman ID] and [Group ID].
SELECT [Salesman ID], MIN([Pay Period ID]) AS [Start time],
MAX([Pay Period ID]) AS [End time], COUNT(*) AS [# of periods],
AVG([Sales]) AS [Average Sales]
FROM (
SELECT [Salesman ID], [Pay Period ID], [Sales],
SUM(NewGroup) OVER (PARTITION BY [Salesman ID] ORDER BY [Pay Period ID]
ROWS UNBOUNDED PRECEDING) AS [Group ID]
FROM (
SELECT T1.*,
CASE WHEN T1.[Sales] >= 500 AND (Prev.[Sales] < 500 OR Prev.[Sales] IS NULL)
THEN 1 ELSE 0 END AS [NewGroup]
FROM MyTable T1
LEFT JOIN MyTable Prev ON Prev.[Salesman ID] = T1.[Salesman ID]
AND Prev.[Pay Period ID] = T1.[Pay Period ID] - 1
) AS InnerQ
) AS MiddleQ
WHERE [Sales] >= 500
GROUP BY [Salesman ID], [Group ID]
Table 1
2 columns
pack no 20 20 20 20 20 20 30 30 30 30 30
Serial no 12 13 14 15 16 17 18 19 20 21 22
Result I need is
pack no 20 30
serial no 12-17 18-22
if these fields are all numbers,
SELECT packNo,
CAST(min_serial AS VARCHAR(12)) + '-' + CAST(min_serial AS VARCHAR(12)) serial_no
FROM
(
SELECT packNo,
MIN(serialNo) min_serial,
MAX(serialNo) max_serial
FROM TableName
GROUP BY packNo
) subtable
Please try:
select
[pack no],
CAST(MIN([Serial no]) AS NVARCHAR(10))+'-'+CAST(MAX([Serial no]) AS NVARCHAR(10)) as [Serial no]
from
YourTable
group by [pack no]
You could use min() and max() functions to do that. It would be better if you use underscore in column names instead space.
FIDDLE DEMO
select [pack no], convert(varchar(10),min([Serial no])) + '-' +
convert(varchar(10),max([Serial no])) as [Serial no]
from yourTable
group by [pack no]