Issue with Oracle select query 2 - sql

I have a table report of production, and I want to bridge between minus value and positive value on QTY field.
I want to make a new column with positive value, and another column with negative value selected from the QTY field.
mtl_trx qty uom
1 20 1230 KG
2 39 950 KG
3 45 100 LBR
4 91 250 KG
5 118 -500 KG
6 125 -284 KG
7 137 -120 KG
8 143 -80 KG

If I understand correctly, you want to select two columns, one showing the positiv values, one the negative ones? Use a case construct to decide whether to show a value or not.
select mtl_trx, qty, uom,
case when qty > 0 then qty end as qty_pos,
case when qty < 0 then qty end as qty_neg
from mytable;

select mtl_trx, qty, uom,
case when qty > 0 then qty else 0 end as positive,
case when qty < 0 then qty else 0 end as negative
from production;

Related

Finding Max Price and displaying multiple columns SQL

I have a table that looks like this:
customer_id item price cost
1 Shoe 120 36
1 Bag 180 50
1 Shirt 30 9
2 Shoe 150 40
3 Shirt 30 9
4 Shoe 120 36
5 Shorts 65 14
I am trying to find the most expensive item each customer bought along with the cost of item and the item name.
I'm able to do the first part:
SELECT customer_id, max(price)
FROM sales
GROUP BY customer_id;
Which gives me:
customer_id price
1 180
2 150
3 30
4 120
5 65
How do I get this output to also show me the item and it's cost in the output? So output should look like this...
customer_id price item cost
1 180 Bag 50
2 150 Shoe 40
3 30 Shirt 9
4 120 Shoe 36
5 65 Shorts 14
I'm assuming its a Select statement within a Select? I would appreciate the help as I'm fairly new to SQL.
One method that usually has good performance is a correlated subquery:
select s.*
from sales s
where s.price = (select max(s2.price)
from sales s2
where s2.customer_id = s.customer_id
);

Is it possible to CAST as FLOAT from an IIF statement?

Is it possible to CAST as FLOAT from an IIF statement?
SELECT TOP 100 PeopleID, RateCount, IIF (People.RateCount < 100,
CAST(People.RateCount/100 as FLOAT), 1) as RateWeight
FROM People WHERE People.RateCount > 0 ORDER BY People.DateAdded DESC
The result I'm getting is
PeopleID RateCount RateWeight
8548 674 1
135698 30 0
426755 2 0
336714 106 1
276739 43 0
536577 7 0
57674 81 0
79670 32 0
44674 901 1
146784 16 0
What I want is
PeopleID RateCount RateWeight
8548 674 1
135698 30 .30
426755 2 .02
336714 106 1
276739 43 .43
536577 7 .07
57674 81 .81
79670 32 .32
44674 901 1
146784 16 .16
Is there a better way of doing this?
When performing division, the data types of the numbers being divided control the resulting data type. To get a FLOAT or DECIMAL result, one of the numbers must already be FLOAT or DECIMAL, i.e.:
SELECT TOP 100 PeopleID,
RateCount,
IIF (People.RateCount < 100, People.RateCount/CAST(100 as FLOAT), 1) as RateWeight
FROM People
WHERE People.RateCount > 0
ORDER BY People.DateAdded DESC
Alternately, get rid of the CAST and just make the value 100 into 100.0
SELECT TOP 100 PeopleID,
RateCount,
IIF (People.RateCount < 100, People.RateCount/100.0, 1) as RateWeight
FROM People
WHERE People.RateCount > 0
ORDER BY People.DateAdded DESC

How to use IF Else in SQL Server

I have to use If Else in Sql Server Query.
Lets Consider the Table below
Product Kg Qty Rate
----------------------------
Mango 1 3 70
Orange 0 2 80
Apple 3 4 90
I need to sum Kg, qty and rate(kgQtyrate) as Total. But when kg is 0 i need to sum only qty*rate.
I need a output like,
Product Kg Qty Rate Total
-----------------------------------
Mango 1 3 70 210
Orange 0 2 80 160
Apple 3 4 90 1080
How can I use If Else here???
You could use CASE:
SELECT
*,
(CASE Kg WHEN 0 THEN 1 ELSE Kg END) * Qty * Rate AS Total
FROM Products
Please have a look here.
you can use this query
select *, case when kg > 0
then kg + qty + rate
else
qty + rate
end as "total"
from table3
look at attached image

Calculate fixed Cost/day for multiple services on same date

Desired Output table T with Calculated Cost column:
SvcID Code ID Date Mins Units Cost
1 3000 15 4/4/2016 60 10 70
2 3000 17 4/4/2016 45 10 0
3 3000 15 5/2/2016 30 10 70
4 3000 18 5/2/2016 60 10 0
5 3000 10 5/2/2016 30 10 0
6 4200 16 2/1/2016 60 4 60
7 4200 9 2/1/2016 30 2 30
Query for calculating and displaying:
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ?
END AS Cost
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....;
Cost should be a total of 70 for all services offered on same date for Code 3000, irrespective of number of services offered. No relation between Minutes and Units for this Code for calculating Cost.
One way could be to calculate cost as 70 for any one service and make the remaining services cost 0 for same date. Can this be done in the CASE statement?
Any better way to achieve this?
You need to Investigate Window functions MSDN.
Your case would become something like this:
-- New select statament
SELECT
...
,CASE
WHEN Code=4200 THEN Units*15
WHEN Code=3000 THEN ( CASE WHEN DuplicateNum = 1 THEN 70 ELSE 0 END )?
END AS Cost
FROM(
-- Your current query (with case statement removed) and ROW_NUMBER() function added
SELECT
..., ROW_NUMBER() OVER( PARTITION BY Code, Date ORDER BY ID ) AS DuplicateNum
FROM ...
WHERE Code IN ('3000','4200')
GROUP BY ....
) AS YourCurrentQuery;

Adding values that don't exist in SELECT statement output

I am not sure how to ask this, due to my lack of experience, so please bear with me.
I am using a SELECT statement to extract pending applications (i.e. no completed date) and counting their totals (plus some other counting). There are certain project types that I need to gather from, 8 of them, where only 4 of them currently have a pending application. I still need to show the other project types with a 0 in the count column. If I try to union with a query that will pull all data, pending or not, I get duplicate rows (minus the count columns) for the 4 project types with currently pending applications. If I left join to the project type table, I get a null row. Neither are what I want. Does anyone have any suggestions?
Output of the union:
General Construction 0 0 90 0
General Coverage 0 0 90 0
General Coverage 1 740 90 90
General Renewal 0 0 90 0
Individual Construction 0 0 90 0
Individual Coverage 0 0 180 0
Individual Renewal 0 0 90 0
Individual Renewal 2 1027 90 180
Approval 0 0 90 0
Approval 22 565 90 1980
Other - Renewal 0 0 90 0
Other - Renewal 21 1119 90 1890
Output without the necessary '0' rows:
General Coverage 1 740 90 90
Individual Renewal 2 1027 90 180
Other - Renewal 21 1119 90 1890
Approval 22 566 90 1980
Output that I would like to see is:
General Construction 0 0 90 0
General Coverage 1 740 90 90
General Renewal 0 0 90 0
Individual Construction 0 0 90 0
Individual Coverage 0 0 180 0
Individual Renewal 2 1027 90 180
Approval 22 565 90 1980
Other - Renewal 21 1119 90 1890
Please let me know what else I can provide to help you help me.
You don't provide names of your columns or anything like that.
What you need is a driver table with all valid values. You can then use left outer join to get the result set you want:
select driver.val, coalesce(q.col2, 0), coalesce(q.col3, 0), coalesce(q.col4, 0)
from (select 'General Construction' as val from dual union all
select 'General Coverage' as val from dual union all
select 'General Renewal' as val from dual union all
select 'Individual Construction' as val from dual union all
select 'Individual Coverage' as val from dual union all
select 'Individual Renewal' as val from dual union all
select 'Approval' as val from dual union all
select 'Other - Renewal' as val from dual
) driver left outer join
(query without 0 rows) q
on driver.val = q.col1
If NULLs are okay instead of 0s, then the coalesce() is not needed.