I'm trying to get the following information from two tables in one row, but when i use group by i always get two rows:
Doc Headers
Section Doc Year Nr
SEC1 PATAG 2017 7386
Doc Lines
Section Doc Year Nr Line Type Quantity
SEC1 PATAG 2017 7386 0 1.000000
SEC1 PATAG 2017 7386 4 2.000000
Query
SELECT
cab.strCodSeccao as [Section], cab.strAbrevTpDoc as [Doc], cab.strCodExercicio
as [Year], cab.intNumero as [Nr],
Cast (SUM (lin.fltQuantidade) as NUMERIC (15,2) ) as [Quantity],
CASE WHEN lin.intTpEntPagador = 0 THEN Cast (SUM (lin.fltQuantidade) as
NUMERIC (15,2) ) ELSE 0 END as [Qtd Client],
CASE WHEN lin.intTpEntPagador = 4 THEN Cast (SUM (lin.fltQuantidade) as
NUMERIC (15,2) ) ELSE 0 END as [Qtd Warranty]
FROM
Mov_Apv_Reparacao_Lin as lin WITH (NOLOCK)
LEFT OUTER JOIN Mov_Apv_Reparacao_Cab as cab ON
(lin.strCodseccao=cab.strCodSeccao AND Cab.strAbrevTpDoc=Lin.strAbrevTpDoc AND
Cab.strCodExercicio=Lin.strCodExercicio AND Cab.intNumero=Lin.intNumero)
WHERE
cab.strAbrevTpDoc='PATAG' AND cab.strcodexercicio =
2017 and cab.intnumero = 7386
GROUP BY
cab.strCodSeccao, cab.strAbrevTpDoc, cab.strCodExercicio, cab.intNumero,
lin.intTpEntPagador
Result from Query
Section Doc Year Nr Quantity Qtd Client Qtd Warranty
SEC1 PATAG 2017 7386 1.00 1.00 0.00
SEC1 PATAG 2017 7386 2.00 0.00 2.00
Desired result
Section Doc Year Nr Quantity Qtd Client Qtd Warranty
SEC1 PATAG 2017 7386 3.00 1.00 2.00
Thanks in advance.
You have an attribute too much in your group by: you should remove lin.intTpEntPagador. That also means you have to change your case/summations:
Cast(SUM(CASE WHEN lin.intTpEntPagador = 0 THEN lin.fltQuantidade ELSE 0 END) as
NUMERIC (15,2) ) as [Qtd Client]
You should also remove the distinct, it has no function if you also group by
Try moving your SUM() outside of your CASE:
SELECT cab.strCodSeccao as [Section],
cab.strAbrevTpDoc as [Doc],
cab.strCodExercicio as [Year],
cab.intNumero as [Nr],
CAST(SUM(lin.fltQuantidade) as NUMERIC (15,2)) as [Quantity],
CAST(SUM(CASE WHEN lin.intTpEntPagador = 0
THEN lin.fltQuantidade
ELSE 0
END) AS NUMERIC (15,2)) as [Qtd Client],
CAST(SUM(CASE WHEN lin.intTpEntPagador = 4
THEN lin.fltQuantidade
ELSE 0
END) AS NUMERIC (15,2)) as [Qtd Warranty]
Side note, no need for DISTINCT here when you already have a GROUP BY
Related
I am having trouble using an alias in my SQL:
SELECT
InvoiceDate,
BillingAddress,
BillingCity,
Total,
CASE
WHEN Total < 2.00 THEN 'Baseline Purchase'
WHEN Total BETWEEN 2.00 AND 6.99 THEN 'Low Purchase'
WHEN Total BETWEEN 7.00 AND 15.00 THEN 'Target Purchase'
ELSE 'Top Performer'
END AS PurchaseType
FROM
invoices
WHERE
PurchaseType = 'Top Performer'
ORDER BY
BillingCity
I get the following error:
Invalid column name 'PurchaseType'.
I have two table with primary key and foreign key (MaterialId)
Material Table (Multiple Material)
MaterialId MaterialName OpeningStock
1 Pen 100
2 Pencil 50
Material Stock (Multiple Material Entry)
MaterialId PurchaseQty SalesQty Date
1 500 0 2016-12-15
1 0 0 2016-12-16
1 300 0 2016-12-17
1 0 400 2016-12-18
1 0 0 2016-12-19
1 0 0 2016-12-20
1 0 400 2016-12-21
1 200 100 2016-12-22
Now When I Pass #FromDate and #Todate
I want to output like below:
Date MaterialName OpeningStock PurchaseQty SalesQty ClosingStock
2016-12-15 Pen 100 500 0 600
2016-12-16 Pen 600 0 0 600
2016-12-17 Pen 600 300 0 900
2016-12-18 Pen 900 0 400 500
2016-12-19 Pen 500 0 0 500
2016-12-20 Pen 500 0 0 500
2016-12-21 Pen 500 0 400 100
2016-12-22 Pen 100 200 100 200
Note :
1. If Something is wrong on database tables so, please guide me how to handle this situation.
2. And Also find Current Date Stock From Two Tables
You are looking for a rolling sum of the various quantity values. One way to do this is using correlated subqueries:
SELECT
t1.Date,
mt.MaterialName,
(SELECT OpeningStock FROM [Material Table] WHERE MaterialId = t1.MaterialId) +
COALESCE((SELECT SUM(t2.PurchaseQty - t2.SalesQty) FROM [Material Stock] t2
WHERE t2.Date < t1.Date AND t1.MaterialId = t2.MaterialId), 0) AS OpeningStock,
t1.PurchaseQty,
t1.SalesQty,
(SELECT OpeningStock FROM [Material Table] WHERE MaterialId = t1.MaterialId) +
COALESCE((SELECT SUM(t2.PurchaseQty - t2.SalesQty) FROM [Material Stock] t2
WHERE t2.Date <= t1.Date AND t1.MaterialId = t2.MaterialId), 0) AS ClosingStock
FROM [Material Stock] t1
INNER JOIN [Material Table] mt
ON t1.MaterialId = mt.MaterialId
ORDER BY
mt.MaterialName,
t1.Date;
Note that it is bad table design to be storing the opening stock values in a separate table from the material stock table. This means the above query would return no pencil records. A better approach would be to insert a seed record into material stock, for each material, with the amount being the initial stock.
Output:
Demo here:
Rextester
Simply do as below :
SELECT S.DATE, M.MaterialName, M.OpeningStock, S.PurchaseQty, S.SalesQty, SUM((M.OpeningStock+S.PurchaseQty)-S.SalesQty)ClosingStock FROM #TABLE
(
SELECT * FROM MaterialTABLE
) M
INNER JOIN Material S ON S.MaterialId = M.MaterialId where s.date between #FromDate and #Todate
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.
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,
...
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;