Multiple WHERE OR Expression in query using SQL Server - sql

I have here the Query to Select Multiple Expression
SELECT * FROM tbProducts WHERE
(PRICE BETWEEN 4590 AND 5100) AND RATING = (SELECT MAX(RATING) FROM tbxProducts) AND
(PRICE = (SELECT MAX(PRICE) FROM tbxProducts))
These are the columns from tbProdcts
| PRODUCT_NAME | DESCRIPTION | RATING | PRICE |
but the problem is that the table cannot display any Items with the range of 4590 up to 5100
And after that. I would select also the max rate of an items and max Price with that Range of Price
how can I do it with the right query?
Thanks in Advanced :)

This should do what you're asking for in a somewhat more straight forward manner.
It will return the item with the highest rating. If there are multiple items with the same highest rating, it will use the highest price as a tie breaker.
SELECT TOP 1 *
FROM tbProducts
WHERE price BETWEEN 4590 AND 5100
ORDER BY rating DESC, price DESC

you need to limit the output of
SELECT MAX(PRICE) FROM tbxProducts
so something like
SELECT MAX(PRICE) FROM tbxProducts t where t.PRICE BETWEEN 4590 AND 5100

Related

SQL how to find the product group with highest porportion of expensive items

I have a table with products, product_group and price level. How can I find the product group with the highest porportion of expensive items?
product | product_group | price_level
1 a expensive
2 a low
3 b low
4 b expensive
5 b expensive
6 c expensive
I have tried this query, but it keeps all price_levels, not just the expensive ones.
select product, product_group, price_level,
count(price_level) over (partition by product_group, price_level) as pl,
count(product) over (partition by product_group) as p
from tbl
Essentially, I want to divide the number of expensive items in one product group by the total number of items in the same product group.
Desired output:
Product group | Percentage
c 1
You can use conditional aggregation:
select product_group,
avg( (price_level = 'expensive')::int ) as expensive_ratio
from tbl
group by product_group
order by expensive_ratio desc
limit 1;
The use of avg() is a convenient way to get the ratio you want. A more verbose method would be:
count(*) filter (where price_level = 'expensive') * 1.0 / count(*)

Get related fields from MAX() query

I am trying to write a subquery that will select the highest price as well as the item name associated with that highest price.
For example:
ID | Price | Item Name
1 | 28.99 | Lamp
2 | 13.99 | USB Cable
I am expecting to get "28.99" and "Lamp" with my sub-query. The main query looks something like this:
SELECT
i.id
FROM
inventory i
My sub-query within the main query looks something like this:
SELECT
i.id,
(SELECT MAX(pl.price) FROM price_list pl WHERE pl.id = i.id) AS highest,
(SELECT MAX(pl.item_name) FROM price_list pl WHERE pl.id = i.id) AS highestName
FROM
inventory i
However, using MAX() on an item name is going to return the highest ranked alphabetical name, which is not what I want. I want to get the item name associated with the highest price. What is the most efficient way to do this?
You coudl use a subquery for match the where
select price as highest , item_name highestName
from price
where price = (
select max(Price)
from price_list
)
It can be done with a query like this:
SELECT Price, Name
FROM price_list
WHERE Price = (SELECT MAX(PL.Price) FROM price_list PL)

Find the areaid that sells most number of products but with less discount

I am pretty new to SQL Server.
I have a question on one of the queries that I am trying to come up with
I have a table like this:
pid areaid units discount
-------------------------
1 1 10 10%
2 1 20 10%
3 2 30 5%
4 2 40 15%
5 1 50 10%
6 3 10 0%
I am trying to find the areaid that sells most number of products(units) but with less discount.
I tried some query as below but I couldn't figure out a way to join the below 2 queries.
I was able to find the least discount using the below query
select
min(y.discount)
from
(select
sum(discount) as discount
from
productinfo
group by
areaid) y
but not sure how to get the area id corresponding to that aggregated discount.
Similarly I figured out a query to return maximum number of products aggregated by areaid
select
max(y.uomsum)
from
(select
sum(uom) as uomsum
from
productinfo
group by
areaid) y
It would be great if anyone can help me with this query.
select areaid, MAX(TotalUnits), MIN(TotalDiscount)
FROM
(
select areaid , SUM(units) as TotalUnits, SUM(discount) TotalDiscount
from Table1
group by areaid
)T
group by areaid
May be something like this
SELECT MIN(Y.Discount),MAX(Y.Units)
FROM
(SELECT AreaID,SUM(Discount) AS Discount ,SUM(units) as Units
FROM productinfo
GROUP BY Areaid
) Y
It seems to me, that you need to calculate the average discount per area discount, then sum.
Select
sum(discountedUnits), areaid
from (
select
sum(units) as units,
sum(units) * (1-(convert(float, discount)/100)) as discountedUnits,
convert(float, sum(units) * (1-(convert(float, discount)/100))) / sum(units) as averageUnit,
areaid,
discount
from
productinfo
group by areaid, discount) as g
group by areaid
Here's a fiddle
To get the max, you could do a top 1 and order by descending, or put it all in another subselect

SQL - Only one result per set

I have a SQL problem (MS SQL Server 2012), where I only want one result per set, but have different items in some rows, so a group by doesn't work.
Here is the statement:
Select Deliverer, ItemNumber, min(Price)
From MyTable
Group By Deliverer, ItemNumber
So I want the deliverer with the lowest price for one item.
With this query I get the lowest price for each deliverer.
So a result like:
DelA 12345 1,25
DelB 11111 2,31
And not like
DelA 12345 1,25
DelB 12345 1,35
DelB 11111 2,31
DelC 11111 2,35
I know it is probably a stupid question with an easy solution, but I tried for about three hours now and just can't find a solution. Needles to say, I'm not very experienced with SQL.
Just Add an aggregate function to your deliverer field also, as appropriate (Either min or max). From your data, I guess you need min(deliverer) and hence use the below query to get your desired result.
Select mIN(Deliverer), ItemNumber, min(Price)
From MyTable
Group By ItemNumber;
EDIT:
Below query should help you get the deliverer with the lowest price item-wise:
SELECT TABA.ITEMNUMBER, TABA.MINPRICE, TABB.DELIVERER
FROM
(
SELECT ITEMNUMBER, MIN(PRICE) MINPRICE
FROM MYTABLE GROUP BY
ITEMNUMBER
) TABA JOIN
MYTABLE TABB
ON TABA.ITEMNUMBER=TABB.ITEMNUMBER AND
TABA.MINPRICE = TABB.PRICE
You should be able to do this with the RANK() (or DENSE_RANK()) functions, and a bit of partitioning, so something like:
; With rankings as (
SELECT Deliverer,
rankings.ItemNumber,
rankings.Price
RANK() OVER (PARTITION BY ItemNumber ORDER BY Price ASC) AS Ranking
FROM MyTable (Deliverer, ItemNumber, Price)
)
SELECT rankings.Deliverer,
rankings.ItemNumber,
rankings.Price
FROM rankings
WHERE ranking = 1

Finding the total amount for my query

I have a query that allows me to retrieve customer orders.
Select ID, OrderID, Item, Price from customerOrders
Where Order = 1
is there a way of totalling up the final amount to pay and have it visible below, but still be able to view all details needed in the sql query, for example
ID | OrderID | Item | Price
1 | 1 | Book | 9.99
2 | 1 | DVD | 12.99
total = 22.98
Many thanks in advance
Two steps:
1, To generate the SUM, you need to add it to the result set using UNION ALL. UNION adds a DISTINCT operation which isn't required, even if in your case it won't change the result.
Select ID, OrderID, Item, Price from customerOrders
Where [Order] = 1
UNION ALL
Select NULL, NULL, NULL, SUM(Price) from customerOrders
Where [Order] = 1
ORDER BY CASE WHEN ID IS NULL THEN 2 ELSE 1 END, ID;
2, To sort it in the order you want (sum at the bottom), you can use the NULL ID as an identifier.
You can try COMPUTE
Select ID, OrderID, Item, Price from customerOrders
Where Order = 1
COMPUTE SUM(Price)
Technically, the thing you want is called a roll-up row. SQL Server has a special function for such cases, it's called ROLLUP() and used inside a GROUP BY clause. In your particular situation, the query would basically look like this:
SELECT ID, OrderID, Item, SUM(Price) AS Price
FROM customerOrders
WHERE OrderID = 1
GROUP BY ROLLUP((ID, OrderID, Item))
;
You can see a live demonstration of this query at SQL Fiddle. More information about ROLLUP(), as well as other GROUP BY functions, can be found at MSDN.
This is what you need:
Select ID, OrderID, Item, Price from customerOrders
Where Order = 1
Union
Select NULL, NULL, NULL, (
Select Sum(Price) from customerOrders
Where Order = 1
Group By Order
)
UPDATE
Incase the result was empty, the total should be zero, not empty. Use the updated code.
Cheers