Sum of different column in SQL - sql

We have an existing table with columns:
ItemCode nvarchar
Supplier1Price nvarchar
Supplier2Price nvarchar
Supplier3Price nvarchar
SelectedSupplier int (1, 2 or 3)
The table is used for canvassing from different suppliers. What I want to do is to get the sum of same items from selected suppliers.
Example:
ItemCode Supplier1Price Supplier2Price Supplier3Price SelectedSupplier
item-00 100 200 300 1
item-00 200 100 300 2
item-00 200 100 300 2
item-01 200 300 100 3
item-01 200 100 300 2
Result should be:
ItemCode Total
item-00 300
item-01 200
What I did is this:
select
ItemCode,
sum(SupplierPrice) as Total
from
(select
ItemCode,
case SelectedSupplier
when 1 then Supplier1Price
when 2 then Supplier2Price
when 3 then Supplier3Price
end) as SupplierPrice
from CanvassTable)
group by ItemCode
Note: First, code above selects all itemcodes and corresponding price (from selected supplier). The result then will be processed in order to get the sum of prices of each item.
It's working already, the problem is, I used subquery and I worry that when the table data grows the query will have poor performance. My question is is there any way I can do this without subquery?

If your query works, why not just do:
select
ItemCode,
SUM(case SelectedSupplier
when 1 then Supplier1Price
when 2 then Supplier2Price
when 3 then Supplier3Price
end) as SupplierPrice
from CanvassTable
group by ItemCode

Related

How to get first row of each group without using window functions Oracle?

How can i get first row of each group with all attributes without using window functions like row_number etc.
Example Data is:
id amount
1 100
1 200
2 150
2 300
2 250
3 400
What I want as a result:
id amount
1 200
2 300
3 400
No need for a window function:
SELECT id, MAX( amount ) AS amount
FROM your_table
GROUP BY id

How to split column into two columns based on unique ID?

I have two IDs and I want to split those values into two different columns
Here is the example
I want to have one column name Cash for cash values and one column for Card values
id type value
1 cash 1000
2 card 3500
2 card 1600
1 cash 500
1 cash 300
Don't have any query because I don't know where to start from.
Expected results should be
id card cash
2 3500 null
1 null 1000
2 1600 null
1 null 500
1 null 300
Just use case expressions:
select id,
(case when type = 'card' then value end) as card,
(case when type = 'cash' then value end) as cash
from t;
Note: The ordering for the result set is indeterminate. You have not explained if the ordering is important to the question, but you seem to have the highest value for each id, then the second highest, and so on. If that is really desired:
order by row_number() over (partition by id order by value desc),
id desc

Grouping by multiple fields

I have a table of ParentID's which are products made by combining the required amount of the corresponding BaseID product.
Product table:
ParentID BaseID Required UOH
-------------------------------------
1 55 1 400
1 56 .5 400
2 55 1 400
2 57 1 400
3 58 1 0
I need to select the ParentID's where there are enough of each required base product (UOH) to create the Parent.
The Query should return
ParentID
----------------
1
2
The only way I know how to do this is by using a pivot view. Is there another or a better way to accomplish this?
Thanks
You can use group by and having:
select parentid
from table t
group by parentid
having sum(case when uoh < required then 1 else 0 end) = 0
The having clause counts the number of times where uoh is less than required. If the count is zero, then all base ids have sufficient amounts.

How to use subquery to populate column in Access query

I am working on an Access database which is used for forecasting purchases and I am trying to create a query in which would give me list of records with valid prices and row sums.
I am running into problems when I try to combine prices to quantities. I have following tables
Table that contains forecasting data (columns not relevant for this query omitted)
need_rows
ID product_id qty use_date
----------------------------
1 1 100 1.1.2014
2 1 50 15.1.2014
...
And table for prices
prices
ID product_id price valid_from
----------------------------------
1 1 1 1.12.2013
2 1 2 24.12.2013
3 1 5 10.1.2014
...
Query resulst should be something like below:
result of query
product_id use_date qty price sum
---------------------------------------
1 1.1.2014 100 2 200
1 15.1.2014 50 5 250
...
Meaning that I need to fetch valid price to each of the rows based on the use_date from need_rows and valid_from date from prices. Valid prices is the one that has valid_from date equal or most recent to use_date.
Below is one of the approaches I have tried with no luck.
SELECT prices.price
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)=
(SELECT Max(prices.valid_from) AS valid
FROM prices
WHERE (((prices.product_id)=[product_id]) AND ((prices.valid_from)<=[use_date]));).));
Any help is appreciated!
SELECT need_rows.Id
, need_rows.qty
, need_rows.product_id
, (SELECT TOP 1 price
FROM prices
WHERE need_rows.product_id = prices.product_id
AND need_rows.use_date >= prices.valid_from
ORDER BY prices.valid_from DESC) AS currentprice
FROM need_rows;

SQL - choose column if the sum of other columns is above total

I have a table that looks like this:
id , name , price , date
1 a 100 1.3.12
2 b 230 1.3.12
3 a 300 1.3.12
4 c 1000 1.3.12
5 b 160 1.3.12
6 a 400 1.3.12
I want to display the names whose total price is above some value, let's say 500.
So if a has 100, 300, 400 then its total is 800 > 500 -> display.
But I want to do it with just one query. So far, I managed to get this query:
SELECT name SUM (price) AS total FROM table GROUP BY name
But then I need to do one more in order to select total > 500.
How do I do it? thank you in advance.
You should use HAVING clause to apply a condition to an aggregated function:
SELECT name
FROM yourtable
GROUP BY name
HAVING SUM(price)>500
Use having to filter
select name, sum(price) as total_price
from your_table
group by name
having total_price > 500