Create a summarized table using data from table. - sql

I have a table which displays the following information:
order# orderdate Company Itemno itemdesc sales qty price location ref# dept. discount approvedstatus ordertype subrent
AH123 01/23/2013 HRV T1456286 dog leash T 50 10.00 LA NR ACESSORIES 0.00 APPROV
AH123 01/23/2013 HRV T1456286 dog bone T 10 10.00 LA AF ACESSORIES 0.00 APPROV O F
TV1245 05/25/2013 T&T T54895 staples 5 10.00 AB ARC SUPPLIES 0.00 APPROV O F
TV1645 05/25/2013 T&T T54895 paper 10 20.00 AB ARC SUPPLIES 0.00 APPROV O F
Given this table I would like to get a summarized table which would give me the following information:
Location Rev Non-Rev
LA 100.00 500.00
AB 250.00 0.00
In Order words, the total_Price based on the location will only go into Non-Rev if the ref# says 'NR' otherwise it will go into REV column.
I have tried this by inserting everything to a temp table and then using a case statement but I can't use CASE WHEN ref#<>'NR' SUM(price_qty) as it requires me to group it by ref# as well which creates more column than I actually need.
Any help!!!

You were really close:
SELECT Location,
SUM(CASE WHEN [ref#] = 'NR' THEN price_qty END) Rev,
SUM(CASE WHEN [ref#] <> 'NR' THEN price_qty END) [Non-Rev]
FROM YourTable
GROUP BY Location

Not sure I follow, but I think you can use a derived table, which would be your detail plus your derived rev and non-rev columns, and then summarize from that.
Something like:
select
col1,
...
sum(NonRev),
sum(rev)
from
(
select Col1,
...,
case when ref# <> 'NR' then price_qty else 0 end as NonRev,
case when ref# = 'NR' then price_qty else 0 end as rev
from
yourtable
) t1
group by
col1,
...

Related

Calculate column amount and get total with order number?

How to calculate each order number amount and total amount with SQL status
Order_no Status Amount
9008258656 P 50.00
9008258656 P 0.00
9008510713 P 50.00
9008510713 P 0.00
Well, it looks like you want a simple aggregated query :
SELECT order_no, count(*) number_of_orders, sum(amount) total_amount
FROM orders
GROUP BY order_no
If you need to filter on a specific status :
SELECT order_no, count(*) number_of_orders, sum(amount) total_amount
FROM orders
WHERE status = 'P'
GROUP BY order_no
If you are looking to keep your individual line numbers (i.e. 4 total records) and not have aggregates (i.e. 2 total records), you can use the sum window function.
SELECT ord.Order_no
, ord.Status
, ord.Amount
, TotalSum = SUM(ord.Amount)OVER(PARTITION BY ord.Order_no, ord.Status)
FROM Orders ord
This would produce the following result:
Order_no Status Amount TotalAmount
9008258656 P 50.00 50.00
9008258656 P 0.00 50.00
9008510713 P 50.00 50.00
9008510713 P 0.00 50.00
Based off the example you provided, there probably is not much value in doing the sum over in this scenario. #GMB's response should suffice. However, there are a lot of cool things you can do with the sum window function such as running totals. For example, if you had an order date column, you can include after the PARTITION BY ord.Order_no, ord.Status ORDER BY ord.Order_date and this would give you a running sum of the amount that increments by each order. I.E:
Order_no Order_date Status Amount RunningTotal
9008258656 1/2/2019 P 50.00 50.00
9008258656 1/3/2019 P 0.00 50.00
9008258656 1/4/2019 P 50.00 100.00
9008258656 1/5/2019 P 0.00 100.00

Join two 2 tables to get sum of each year - SQL Server

I have 2 tables below. Common column is ObjectId.
Table 1:
Year ObjectId G_Amount
===== ======== ========-
2010 1234 5.00
2010 1234 5.00
2010 5678 10.00
2010 5678 20.00
2010 5678 50.00
2012 9101 0.00
2012 1122 70.00
2012 1122 100.00
Table 2:
ObjectId I_Amount
========= ===========-
1234 10.00
1234 30.00
5678 15.00
5678 20.00
9101 25.00
9101 35.00
1122 10.00
1122 0.00
I want to join above 2 table such that the resultset becomes like below. G_Amount (total of g_amount for each year from Table 1) & I_Amount (total of i_amount for each year from Table 2) should be displayed year wise.
Result set:
Year G_Amount I_Amount
===== ======== ========-
2010 90.00 75.00
2012 170.00 70.00
Can anyone please help?
Your datamodel allows for an object ID to appear in multiple years. The related table2 entries would thus be multiplied, i.e. added to every of these years. If you don't want this, then you need a separate table with one record per object.
As is you'd aggregate the first table by year and object ID and the second by object ID only. Then join and aggregate again to get years.
select
t1.year,
sum(t1.totalg) as total_g_amount,
coalesce(sum(t2.totali), 0) as total_i_amount
from
(
select Year, ObjectId, sum(G_Amount) as totalg
from table1
group by Year, ObjectId
) t1
left join
(
select ObjectId, sum(i_Amount) as totali
from table2
group by ObjectId
) t2 on t2.ObjectId = t1.ObjectId
group by t1.year
order by t1.year;
Something like this will work for your dataset. I've included a LEFT JOIN for any values in Table1 that aren't in Table2:
SELECT
T1.[Year]
, SUM(T1.G_Amount_Total) G_Amount
, ISNULL(SUM(T2.I_Amount_Total), 0) I_Amount
FROM
(
SELECT
[Year]
, ObjectId
, SUM(G_Amount) G_Amount_Total
FROM Table1
GROUP BY
[Year]
, ObjectId
) T1
LEFT JOIN
(
SELECT
ObjectId
, SUM(I_Amount) I_Amount_Total
FROM Table2
GROUP BY ObjectId
) T2
ON T1.ObjectId = T2.ObjectId
GROUP BY T1.[Year]
I do see some potential problems with your data structure, e.g, there is no Year reference in Table2, however, if your data is under control, it should all work out.
Try this , anyway i am new to T-SQL so it can be wrong .
Select DISTINCT T1.Year
SUM (T1.G_Amount) as G_Amount,
SUM (T2.I_Amount) AS I_Amount
from table1 T1 join Table2 T2 on T1.ObjectID = T2.ObjectID

SQL nvarchar is invalid for sum operator

I am learning SQL and I have table that looks like this:
Id Name Payd Note
1 John 5.00 R:8days;U:5$
2 Adam 5.00 R:8days;
3 John 10.00 R:8days;
4 John 10.00 R:8days;
5 Adam 15.00 R:30days;
I want to make something like this:
Id Name Usage 5.00 10.00 15.00 Sum
1 John 5 5.00 20.00 0 25.00
2 Adam 5.00 0 15.00 20.00
I want to check that note column if there is 'U:5$' in it and then add a 5 to that customer that has 'U:5$' in note column, if it doesnt it doesnt add anything.
My code looks like this:
;with cte as (
select Customer, PaydAmount, PaydAmount as Payd, Note as Usage
from t1
)
select
Customer, Usage
,[4.00] = ISNULL([4.00],0)
,[5.00] = ISNULL([5.00],0)
,[9.00] = ISNULL([9.00],0)
,[10.00] = ISNULL([10.00],0)
,[15.00] = ISNULL([15.00],0)
,[18.00] = ISNULL([18.00],0)
,[20.00] = ISNULL([20.00],0)
,[25.00] = ISNULL([25.00],0)
,[50.00] = ISNULL([50.00],0)
,[Payd] =ISNULL([4.00],0) + ISNULL([5.00],0) + ISNULL([9.00],0) + ISNULL([10.00],0) + ISNULL([15.00],0) + ISNULL([18.00],0) + ISNULL([20.00],0) + ISNULL([25.00],0) + ISNULL([50.00],0)
from cte
pivot (
sum(PaydAmount) for Payd in ([4.00],[5.00],[9.00], [10.00], [15.00],[18.00], [20.00], [25.00], [50.00]))pvt
order by Customer;
I am not sure what your full output represents. But the first three columns are easy to get using conditional aggregation:
select row_number() over (order by (select null)) as id,
name,
max(case when note like '%U:5$' then 5 end) as usage,
sum(case when payd = 5.00 then payd else 0 end) as [5.00],
sum(case when payd = 10.00 then payd else 0 end) as [10.00],
sum(case when payd = 15.00 then payd else 0 end) as [15.00],
sum(payd) as total
from cte
group by name;
Note that the columns for 5, 10, and 15 sort of assume that the value in payd is a decimal/numeric type. Equality comparisons on floats are not recommended.

Select entire row with more than one distinct column

I have a table based on invoice items where I am trying to use SQL to detect at what dates the price or currency for the combination of material/customer has changed. The table contains invoices for several customers although the materials can be common.
My SQL skills are quite basic and I have tried several different approaches using GROUP BY and DISTINCT that I have found in other threads but I always seem to get stuck somewhere along the way.
This is basically what the data looks like:
Invoice Inv. Date Material Price Currency Per/Qty Customer
SE100 20140901 111111 1 EUR 1 840006
SE100 20140901 222222 2 EUR 1000 840006
SE100 20140901 333333 3 USD 1 840006
SE101 20140902 111111 1 EUR 1 840006
SE101 20140902 222222 2 EUR 1000 840006
SE101 20140902 333333 3 USD 1 840006
SE102 20140903 111111 2 EUR 1 840006
SE102 20140903 222222 2 USD 1000 840006
SE102 20140903 333333 3 USD 1 840006
SE103 20140904 111111 1 EUR 1 840006
SE103 20140904 222222 2 USD 1000 840006
SE103 20140904 333333 3 USD 1 840006
What I want to accomplish is basically to select the first row datewise for all distinct combinations of Customer/Material/Currency/Price and then subselect the entire rows (sorted by material) for those materials that occur more than once in the selection, thus indicating the price or currency has changed from the initial value.
The expected output from the query using the data in the table above would then look something like this:
Invoice Inv. Date Material Price Currency Per/Qty Customer
SE100 20140901 111111 1 EUR 1 840006
SE102 20140903 111111 2 EUR 1 840006
SE103 20140904 111111 1 EUR 1 840006
SE100 20140901 222222 2 EUR 1000 840006
SE102 20140903 222222 2 USD 1000 840006
I hope I managed to explain the problem in an understandable way. The database engine is SQL Server 2005 Express.
Any help would be appreciated...
The key word DISTINCT in SQL has the meaning of "unique value". When applied to a column in a query it will return as many rows from the result set as there are unique, different values for that column. As a consequence it creates a grouped result set, and values of other columns are random unless defined by other functions (such as max, min, average, etc.)
If you meant to say you want to return all rows for which Col 06 has a specific value, then use the "where Col 06 = value" clause
SELECT mt.*
FROM (
SELECT DISTINCT col6
FROM mytable
) mto
JOIN mytable mt
ON mt.id =
(
SELECT TOP 1 id
FROM mytable mti
WHERE mti.col6 = mto.col6
-- ORDER BY
-- id
-- Uncomment the lines above if the order matters
)
I think this is a direct translation of what you want:
select t.*
from mydata t join
(select Customer, Material, count(distinct price) as numprices
from mydata
group by Customer, Material
having count(distinct price) > 1
) cmcp
on t.customer = cmcp.customer and t.material = cmcp.material;
This leaves out the currency. Unfortunately, SQL Server doesn't support multiple arguments to distinct. You can include it this way:
select t.*
from mydata t join
(select Customer, Material,
count(distinct cast(price as varchar(255)) + ':' + currency) as numprices
from mydata
group by Customer, Material
having count(distinct cast(price as varchar(255)) + ':' + currency) > 1
) cmcp
on t.customer = cmcp.customer and t.material = cmcp.material;
Most databases support window/analytic functions, so you can also phrase this as:
select t.*
from (select t.*,
min(cast(price as varchar(255)) + ':' + currency)) over (partition by Customer, Material) as minprice,
max(cast(price as varchar(255)) + ':' + currency)) over (partition by Customer, Material) as maxprice
from mydata t
) t
where minprice <> maxprice
order by Material, Inv_Date;

How to calculate

I have a table like this:
Item Qty Price A Price B
abc 5 36.00 0
qwe 8 0 48.00
zxc 6 12.00 0
poi 4 10.00 0
lkj 9 12.00 0
mnb 3 0 14.00
vfr 7 0 6.00
How can I sum the value using SQL ie. if Price A is zero, it will pick Price B. The expected results will be as follows :-
Item Value
abc 180.00
qwe 384.00
zxc 72.00
poi 40.00
lkj 36.00
mnb 42.00
vfr 42.00
SELECT
ITEM
, (Qty * [Price A]) + (Qty * [Price B]) AS Value
FROM
TableName
Use the following if A and B could be non-zero, and you only want to use price A when this occurs:
SELECT Item, CASE WHEN `Price A` != 0 THEN `Price A` * Qty
ELSE `Price B` * Qty
END AS Value
FROM table;
Why not do something like
SELECT SUM(Price A) FROM table; SELECT SUM(Price B) FROM table WHERE Price A = 0;
And then add the results together...
from the example above you could really just select priceA + priceB, since one or the other is always zero, otherwise... I am not quite sure this can be done in pure SQL...
Assuming both can be not null:
SELECT item, QTY * IF(PriceA!=0, PriceA, PriceB) AS VALUE from tableName;