Sql Cleanse to one row - sql

I am struggling with the solution to a query and any help would be greatly appreciated, I end up tying myself In knots with temptables and I'm sure there must be an easier way.
I have a database currently producing the below results - this is as it comes with no joins or production prior.
Acc No | prod No | Product Type | product Cost
12345678 1 Red Toy £100
12345678 2 Blue Toy £150
12345678 3 White Toy £300
12398654 1 White Toy £300
12398765 1 Red Toy £100
I only want one row per account number but don't want to lose the information. I would also like some sums. The below should hopefully show what I mean though there would be more columns:
Acc No | Prod total | cost | Prod1type | Prod1cost |prod2typ
12345678 3 £550 Red Toy £100 BlueToy
12398654 1 £300 White Toy £300 Null
I hope this explains it. I'm aware I would end up with many more columns but it would make my life so much easier.
Any help would be hugely appreciated,
Thanks in advance,

With out considering adding ProdType you could use this query.
Assume also there is only 1 product per line in table.
select acc_no, count(*) as prod_total, sum(cost) as total_cost
from table
group by acc_no
order by acc_no asc
to get all ProdType for a coresponding acc_no you could use
select distinct prodtype
from table
where acc_no='exact_number'

You can use multiple case statements to get your expected output.
Create sample data:
select 12345678 as Accno , 1 as prodno, 'Red Toy' as Producttype , 100 as Cost into #temp union all
select 12345678 as Accno , 2 as prodno, 'Blue Toy' as Producttype , 150 as Cost union all
select 12345678 as Accno , 3 as prodno, 'White Toy' as Producttype , 300 as Cost union all
select 12398654 as Accno , 1 as prodno, 'White Toy' as Producttype , 300 as Cost union all
select 12398765 as Accno , 1 as prodno, 'Red Toy' as Producttype , 100 as Cost
Query:
select accno, count(distinct prodno) Prodtotal, sum(cost) totalCost, max(case when prodno = 1 then Producttype end ) Product1type,
sum (case when prodno = 1 then cost end) Product1cost, max(case when prodno = 2 then Producttype end ) Product2type,
sum (case when prodno = 2 then cost end) Product2cost,max(case when prodno = 3 then Producttype end ) Product3type,
sum (case when prodno = 3 then cost end) Product3cost from #temp
group by accno
Output:
Formatting might be little bit different, but I assume this is your expected output.
accno Prodtotal totalCost Product1type Product1cost Product2type Product2cost Product3type Product3cost
12345678 3 550 Red Toy 100 Blue Toy 150 White Toy 300
12398654 1 300 White Toy 300 NULL NULL NULL NULL
12398765 1 100 Red Toy 100 NULL NULL NULL NULL

Related

How to sum and subtract values using update with group by Sql query?

MyTable:
item_name Qty item_area
Belts 2 India
Shoes 20 US
T-Shirt 10 India
T-Shirt 12 US
T-Shirt 25 US
I get this by select group by query
SELECT item_name, Sum(item_qty) as Qty, item_area
FROM dbo.item_stocks
group by item_area, item_name
and my output is below:
item_name Qty item_area
Belts 2 India
Shoes 20 US
T-Shirt 10 India
T-Shirt 37 US
Now i need to subtract and update .How can i do this ?
For eg. i want to subtract 5 T-Shirt ,it will update in MyTable?
T-shirt=37-5=32
how can i update in MyTable?
You can try to use ROW_NUMBER window function to choose any one row to subtract.
;WITH CTE AS (
SELECT *,ROW_NUMBER() over(PARTITION BY item_name,item_area order by Qty desc)rn
FROM item_stocks
)
update CTE
set Qty = Qty - 5
where rn = 1 and item_name = 'T-Shirt' and item_area = 'US'
SELECT item_name, Sum(Qty) as Qty, item_area
FROM item_stocks
group by item_area, item_name
just add a column which denotes in/Out, say INOUT
don't update row, just add new row for the stock sale.
Here,
INOUT = 1 denotes IN and 2 denotes OUT
table structure like
item_name Qty item_area INOUT
Belts 2 India 1
Shoes 20 US 1
T-Shirt 10 India 1
T-Shirt 12 US 1
T-Shirt 25 US 1
T-Shirt 5 US 2
now your query looks like that
SELECT item_name,
Sum(case when INOUT = 1 then item_qty else (0-item_qty) end) as Qty,
item_area
FROM dbo.item_stocks
group by item_area, item_name

SQL Query to get sums among multiple payments which are greater than or less than 10k

I am trying to write a query to get sums of payments from accounts for a month. I have been able to get it for the most part but I have hit a road block. My challenge is that I need a count of the amount of payments that are either < 10000 or => 10000. The business rules are that a single payment may not exceed 10000 but there can be multiple payments made that can total more than 10000. As a simple mock database it might look like
ID | AccountNo | Payment
1 | 1 | 5000
2 | 1 | 6000
3 | 2 | 5000
4 | 3 | 9000
5 | 3 | 5000
So the results I would expect would be something like
NumberOfPaymentsBelow10K | NumberOfPayments10K+
1 | 2
I would like to avoid doing a function or stored procedure and would prefer a sub query.
Any help with this query would be greatly appreciated!
I suggest avoiding sub-queries as much as possible because it hits the performance, specially if you have a huge amount of data, so, you can use something like Common Table Expression instead. You can do the same by using:
;WITH CTE
AS
(
SELECT AccountNo, SUM(Payment) AS TotalPayment
FROM Payments
GROUP BY AccountNo
)
SELECT
SUM(CASE WHEN TotalPayment < 10000 THEN 1 ELSE 0 END) AS 'NumberOfPaymentsBelow10K',
SUM(CASE WHEN TotalPayment >= 10000 THEN 1 ELSE 0 END) AS 'NumberOfPayments10K+'
FROM CTE
You can get the totals per account using SUM and GROUP BY...
SELECT AccountNo, SUM(Payment) AS TotPay
FROM payments
GROUP BY AccountNo
You can use that result to count the number over 10000
SELECT COUNT(*)
FROM (
SELECT AccountNo, SUM(Payment) AS TotPay
FROM payments
GROUP BY AccountNo
)
WHERE TotPay>10000
You can get the the number over and the number under in a single query if you want but that's a but more complicated:
SELECT
COUNT(CASE WHEN TotPay<=10000 THEN 1 END) AS Below10K,
COUNT(CASE WHEN TotPay> 10000 THEN 1 END) AS Above10K
FROM (
SELECT AccountNo, SUM(Payment) AS TotPay
FROM payments
GROUP BY AccountNo
)

SQL Server SELECT Query to show sum

It ll be great if you guys help me with this
product_no prod_name qty DOA
---------------------------------------------------------------
1 2BL 4 12/12/14
2 CCN 6 14/12/14
3 MNN 7 16/12/14
3 MNN 5 17/12/14
2 CCN 6 02/01/15
3 MNN 7 06/01/15
I need output in single select query if i select DOA between 1/12/14 to 30/12/14
It should show sum (qty) as opening, prod_name and rest of qty and product i.e(02/01/15 to 06/01/15) in another column as purchase (DOA not in 1/12/14 to 30/12/14). Thanks in advance
Assuming, of course, the point rightly raised by Joel in his comment about date formats is taken care of, by you:
Select product_no, prod_name,
Sum(Case When DOA >= '01/12/2014' And DOA <= '30/12/2014' Then Qty Else 0 End) as openingQty,
Sum(Case When DOA < '01/12/2014' Or DOA > '30/12/2014' Then Qty Else 0 End) as purchaseQty
From Table_Name_Here Group By
product_no, prod_name

Group values in to categories with annual break down

I have a table of licence applications I want to display the data by category for each financial year.
For my query, there are 2 key columns.
Firstly, there is a fee column and the values within this column determine the type of licence.
Between 0 and 300 is Minor
between 300 and 600 is Standard
between 600 and 2000 is Major
Secondly, there is a date field which is to be used for the financial year.
I would like the results to look like this.
Category | 2013/14 | 2012/13
Minor | 23 | 21
Standard | 10 | 11
Major | 5 | 3
I have this query below, but i cant get it right for the year part.
Would really appreciate any advice people can give me.
select category.gr as [category],
sum(case when ((year(licence.[start_date]) in ('2010'))
and (month(licence.[start_date]) in (4,5,6,7,8,9,10,11,12)))
or ((year(licence.[start_date]) in ('2011'))
and (month(licence.[start_date]) in (1,2,3))) then 1 else 0 end) AS '10/11 Count',
from ( select case
when [fee_INC] between 0 and 350 then 'Minor'
when [fee_INC] between 350 and 600 then 'Standard'
else 'Major' end as gr
from [L_LICENCE_FIN]) as category,
from [L_LICENCE_FIN] as licence
group by category.gr
SELECT
[category],
[2013/14],
[2012/13]
FROM (
SELECT
[category],
STR(YEAR(DATEADD(month,-3,[start_date])),4)
+'/'
+RIGHT(STR(YEAR(DATEADD(month,-3,[start_date]))+1,4),2)
AS [fiscal_year],
COUNT(*) AS [count]
FROM #L_LICENCE_FIN
INNER JOIN (VALUES
( 0, 300, 'Minor'),
(300, 600, 'Standard'),
(600,2000, 'Major')
) categories([fee_min], [fee_max], [category])
ON ([fee] >= [fee_min] AND [fee] < [fee_max])
GROUP BY [category],[start_date]
) p1
PIVOT(SUM([count]) FOR [fiscal_year] IN ([2013/14],[2012/13])) p2

Compare 2 subsets of data from table?

I'm not sure if this is possible - I'm having real trouble getting my head around it.
This is for a product schedule, showing how much we are expecting to deliver on a given date. Data is imported into this schedule weekly which creates a new entry.
For example, if the schedule for the day currently totals 10, and you import 15, a new row is inserted with Qty 5, bringing the sum to 15.
The data I have is like so:
Product | Delivery Required Date | Qty
Prod1 | 1/1/13 | 10
Prod1 | 1/1/13 | -10
Prod1 | 1/1/13 | 10
Prod1 | 1/1/13 | -10
Prod1 | 1/1/13 | 25
I want to design a query which shows the variance between the previous schedule, and the current schedule.
For example, the query will sum all of the rows "Qty", excluding the last entry - and compare it to the last entry. In the data above, the variance is 25 (Existing total was 0, latest entry is 25, 0+25 =25).
Is this possible?
Thanks
I suspect there'a better answer using Common Table Expressions, but a quick & ugly solution might be
select sum(case when EntryNo <> MAX(EntryNo) then Qty else 0 end) as 'sumLessLast'
from MyTable
If MyTable has a million rows in it you'll want a better solution.
SqlServer 2005 and 2008:
;with r1 as (
select DeliveryReqDate, sum(Qty) as TotalQty
from TableName
group by DeliveryReqDate)
, r2 as (
select DeliveryReqDate, Qty
, row_number() over (partition by DeliveryReqDate order by EntryNo desc) rn
from TableName)
select r1.DeliveryReqDate, r1.TotalQty, r2.Qty as LastQty
, r1.TotalQty - r2.Qty as TotalButLastQty
from r1
join r2 on r2.DeliveryReqDate = r1.DeliveryReqDate and r2.rn = 1
SqlServer 2012
;with r1 as (
select DeliveryReqDate, Qty
, sum(Qty) over (partition by DeliveryReqDate) as TotalQty
, row_number() over (partition by DeliveryReqDate order by EntryNo desc) rn
from TableName)
select DeliveryReqDate, TotalQty, Qty as LastQty
, TotalQty - Qty as TotalButLastQty
from r1
where rn = 1
I'm not sure that I completely understand logic regarding the accounting of product and date, but I hope you can adapt above queries to your needs.