In my SQL Server 2014, I have this SQL query :
SELECT
MIN (dbo.GetActualValue(Price_Value, Discount)) AS ActualPrice,
IDHOTEL
FROM
HotelRoom
GROUP BY
IDHOTEL
dbo.GetActualValue => return #Price_Value - ((#Discount * #Price_Value) / 100)
How I can select Price_Value, Discount at the MIN value ?
I need to calculate the price after discount (actual price), find out the minimum price after calculation (min actual price) I need to select the original price, discount at the place with the smallest actual price
what you need is Subquery and Max or Min function
SELECT H.IDHOTEL,H.Price_Value,H.Discount,B.ActualPrice
FROM
(SELECT dbo.GetActualValue(Price_Value, Discount) AS ActualPrice,Discount,Price_Value
IDHOTEL FROM HotelRoom) H
JOIN
(SELECT Min(dbo.GetActualValue(Price_Value, Discount)) AS ActualPrice,
IDHOTEL FROM HotelRoom
GROUP BY IDHOTEL) B
H.IDHOTEL=B.IDHOTEL AND B.ActualPrice=H.ActualPrice
Related
There are 100 suppliers, each with between 50 and 1000 items. Each supplier may have items close to their office or spread across an entire country or continent.
As LatLngs are input by a human, some mistakes happen. With lots of data and constant 'churn', mistakes are difficult to identify.
To improve data quality, I want to identify outliers for each supplier so that they can be fixed. If a supplier's items are mostly near New York, one in California would be an outlier.
SUPPLIERS
SupplierID int
Latitude DECIMAL(12,9)
Longitude DECIMAL(12,9)
ITEMS
ItemID int
SupplierID int
LatLng geography
I assume I need to use standard deviation for this, but putting it into T-SQL is giving me a headache.
I'd like to output a list of outliers for each supplier, based on each supplier's specific deviation.
This code outputs Items and the distance between each item and the supplier's office.
WITH cte AS
(
SELECT
ItemID,
SupplierID,
LatLng,
LatLng.STDistance(GEOGRAPHY::Point(a.Latitude, a.Longitude, 4326))/1000 As Distance
FROM
Items v
JOIN
Suppliers a ON v.SupplierID = a.SupplierID
)
SELECT
ItemID, SupplierID, Distance
FROM cte
Here's the SQL functionality for standard deviation (from a blog post):
DECLARE #StdDev DECIMAL(5,2)
DECLARE #Avg DECIMAL(5,2)
SELECT
#StdDev = STDEV(Qty),
#Avg = AVG(Qty)
FROM Sales
SELECT
*
FROM
Sales
WHERE
Qty > #Avg - #StdDev AND
Qty < #Avg + #StdDev
STEPS I NEED TO DO
Calculate STDEV and AVG for distance, GROUP BY SupplierID
Output items where the distance is greater than AVG + STDEV for the item's supplier
This is where I'm scratching my head as this is multiple steps AFTER the multiple steps I've already performed. I guess I could insert what I have into a TEMP table and go from there, but is that really the best way?
You can use window functions for this. Both AVG and STDEV are available as window functions
WITH Distances AS
(
SELECT
i.ItemID,
s.SupplierID,
i.LatLng,
v.SupplierLocation,
i.LatLng.STDistance(v.SupplierLocation)/1000 As Distance
FROM
Items i
JOIN
Suppliers s ON i.SupplierID = s.SupplierID
CROSS APPLY (VALUES (
GEOGRAPHY::Point(s.Latitude, s.Longitude, 4326)
)) v(SupplierLocation)
),
Averages AS (
SELECT
ItemID,
SupplierID,
LatLng,
SupplierLocation
Distance,
AVG(Distance) OVER (PARTITION BY SupplierID) AS Avg,
STDEV(Distance) OVER (PARTITION BY SupplierID) AS StDev
FROM
Distances
)
SELECT
ItemID,
SupplierID,
Distance,
Avg,
StDev
FROM
Averages
WHERE
Distance > Avg - StdDev AND
Distance < Avg + StdDev;
I want to find the minimum and maximum date on which a given product had a maximum unit cost, but only of the unit cost had a value of more than 10.
The result that I should get should be something like this:
If the date is the minimum date_type is MIN, and vice-versa.
This is the script that I tried, but I only get two records:
select MIN(dt) as min_date, MAX(dt) as max_date
from products
WHERE price = (SELECT max(price) FROM products where unit_id =1)
Products table:
Unit table:
I have just started experimenting how to calculate the percentage of a row. This is the code I write.
SELECT DISTINCT
ServiceName
COUNT(serviceID) AS Services
FROM Tester_DW
WHERE DateToday=20150410
GROUP BY ServiceName
How can calculate the percentage of the column Services above, and have the percentage in integer? Is it easier to calculate the percentage of the code example if I put my query result in a #temp table and calculate the percentage from the #temp or is it possible to calculate the percentage in integer% on the fly?
ADDED:Output sketch
ServiceName|Services| % of Total
--------------------------------
TV-cable | 4500 | 40%
--------------------------------
Mobile BB | 3000 | 10%
--------------------------------
MOBILE wifi| 20 | 5%
--------------------------------
It is hard to get it right, because you should deal with the sum of rounded integer percentage to get it 100% in total.
Using Largest Remainder Method
;WITH x AS
(
SELECT
ServiceName,
COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () AS [Percent],
FLOOR(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER ()) AS [IntPercent],
COUNT(*) * 100.0 / SUM(COUNT(*)) OVER () % 1 AS [Remainder]
FROM Tester_DW
GROUP BY ServiceName
)
SELECT ServiceName, IntPercent + CASE WHEN Priority <= Gap THEN 1 ELSE 0 END AS IntPercent
FROM
(
SELECT *, ROW_NUMBER() OVER (ORDER BY Remainder DESC) AS Priority, 100 - SUM(IntPercent) OVER () AS Gap FROM x
) data
Percentage is a count divided by the overall (reference) count. You have to use an inner query to get that overall count:
SELECT ServiceName, COUNT(serviceID) AS Services,
FLOOR(COUNT(serviceID) / (SELECT COUNT(serviceID) FROM Tester_DW)) AS percent
FROM Tester_DW WHERE...
Depending on the output you want (that is, what your reference count is), you may have to add the WHERE clause (or parts of it) in the inner query as well.
Select
ServiceName,
Count(ServiceName) as Services,
(Count(ServiceName)* 100 / (Select Count(*) From Tester_DW)) as [% of total]
From Tester_DW
Group By ServiceName
You simply divide the count of a single service by the amount of all services.
Try with window functions:
Create table t(id int)
Insert into t values
(1),(1),(2)
Select * from (Select id,
100.0*count(*) over(partition by id)/ count(*) over() p
from t) t
Group by id, p
I am using SQL Server 2012. I have two tables that contain dates. I want to query the max and min dates from both tables. I know the line below will give me the max and min dates for one table.
select max(dtTime), min(dtTime) from tableOne
What I want to do is get the min of the two max dates from table one and two & the max of the two min dates from the table. Please see the example below.
TableOne TableTwo
Max Date 6-June-2000 23-June-2002
Min Date 10-Jan-1980 15-Feb-1982
Result I would like returned,
Max Date = 6-June-2000
Min Date = 15-Feb-1982
You can use UNION, and then select minimum from max values and max from minimum values:
SELECT min(mx), max(mn)
FROM (
SELECT max(dtTime) AS `mx`, min(dtTime) AS `mn` FROM tableOne
UNION
SELECT max(dtTime) AS `mx`, min(dtTime) AS `mn` FROM tablTow
) AS t1
select max(t1.dtTime), min(t2.dtTime) from tableOne as t1, tableTwo as t2
I'd like to do some statistics on a row in a oracle table.
select totaltime from server_metrics;
gives me a list of numeric values.
What I now want is to know is how many percentage of the values in the table are higher than 100?
I can easily do via two queries and calculate my self:
select count(*) from server_metrics;
select count(*) from server_metrics where totaltime > 100;
But is it possible to do this via one query?
select 100
* sum(case when totaltime > 100 then 1 else 0 end)
/ Nullif(count(*),0)
from server_metrics;