Using 2 fields in ORDER BY clause - sql

I have a page that show "special offers", and i need to order the results by discount value. Besides i want that products with quantity=0 are shown at the end of the list (regardless of the discount value).
So, there is any way to do that using only SQL? I mean... if i set "ORDER BY discount, quantity DESC" the list show products ordered by discount, and each groups of discout is ordered by the quantity value... this isn't what i want.
Thanks in advance...

ORDER BY CASE Quantity WHEN 0 THEN 99999999 ELSE Discount END, Quantity DESC

SELECT * FROM `products` ORDER BY discount WHERE quantity > 0
UNION SELECT * FROM `products` WHERE quantity <= 0;
Like this?

Related

Determining if a sample contains 0 rows for multiple ID's

So I've created a simple query that will pass all OrdID's that have orders of 2 or more apples:
SELECT ordid
FROM results
WHERE ordid IN (12,24,53,21,41,51)
AND product = 'apples'
GROUP BY ordid
HAVING COUNT(ordid) > 1
How can I do this for OrdID's that contain 0 apples?(This doesn't work as there is no product on the OrdID by apples, so it passes 0 rows.) I'd like it to list all OrdID's that have < 1 products for Apples.
SELECT ordid
FROM results
WHERE ordid IN (12,24,53,21,41,51)
AND product = 'apples'
GROUP BY ordid
HAVING COUNT(ordid) < 1
I cannot reproduce in my machine but I hope that this query should work:
SELECT ordid
FROM results
WHERE ordid in (12,24,53,21,41,51)
GROUP BY ordid
HAVING SUM(CASE WHEN product = 'apples' THEN 1 ELSE 0 END) < 1
I switched the HAVING with a COUNT() of the products instead of the orderid since youre trying to count the number of products.
SELECT ordid
FROM results
WHERE ordid in (12,24,53,21,41,51) and product = 'apples'
GROUP BY ordid
HAVING COUNT(product) = 0
The problem you're running into is that you're selecting FROM a table (i.e., limiting to those rows) where what you want to match is what's not in the table (i.e., excluding those rows). These are opposites.
Instead, flip that around so you're selecting FROM the set of values and then excluding those that match:
SELECT ordid FROM (VALUES (12),(24),(53),(21),(41),(51)) AS ordids(ordid)
WHERE NOT EXISTS (
SELECT * FROM results
WHERE results.ordid = ordids.ordid
AND results.product = 'apples'
)
This will return a result for an ordid even if that value never appears in the results table at all.
Use the EXISTS() function to get all OrdIDs WHERE there does NOT EXIST a correlated row with product = 'apples'

Getting Max Value From Joined Table With Certain Logic

This is my table relation :
tbl_product
-----------
product_id
tbl_product_price
-----------------
price_id
price_product_id (FK)
price_normal
price_discount
price_disc_valid_from_date
price_disc_valid_to_date
I'd like to query tbl_product, ordered by its max price DESC, which must be validated first. If the the discount date is still valid (current date between price_disc_valid_from_date AND price_disc_valid_to_date), then get the price_discount. If not valid, then get price_normal. After that I need to get max price ( either from the price_discount or price_normal), then order by that max price.
Most of the questions like this are just how to select the max column, no validation needed first on the joined table.
My question is , what is the postgres sql statement for that query ? Thanks
[EDIT]
I stuck in selecting max price from table tbl_product_price but no idea how to join with tbl_product :
SELECT
pr.price_id, pr.product_price_id,
CASE WHEN current_date BETWEEN pr.price_disc_valid_from_date AND pr.price_disc_valid_to_date
THEN pr.price_discount
ELSE pr.price_normal END AS price
FROM tbl_product_price pr
WHERE pr.price_product_id = 316
GROUP BY pr.price_id, pr.price_product_id
ORDER BY price DESC
LIMIT 1;
Can you do something like this:
SELECT
tbl_tbl_product.price_product_id,
tblMax.MaxPrice
FROM
tbl_tbl_product
JOIN
(
SELECT
tbl_product_price.price_product_id,
MAX(
CASE
WHEN now() BETWEEN
tbl_product_price.price_disc_valid_from_date
AND tbl_product_price.price_disc_valid_to_date
THEN tbl_product_price.price_discount
ELSE tbl_product_price.price_normal
END
) AS MaxPrice
FROM
tbl_product_price
GROUP BY
tbl_product_price.price_product_id
) as tblMax
ON tblMax.price_product_id=tbl_tbl_product.product_id
ORDER BY
tblMax.MaxPrice DESC
If I understand your logic correctly, this query should return products ordered by the maximum price for the product:
SELECT
tp.product_id
FROM
tbl_product tp INNER JOIN tbl_product_price tpp
ON tb.product_id = tpp.price_product_id
GROUP BY
tp.product_id
ORDER BY
MAX(CASE WHEN current_date BETWEEN tpp.price_disc_valid_from_date
AND tpp.price_disc_valid_to_date THEN
tpp.price_discount
ELSE
tpp.price_normal END) DESC

sql where clause but not for some records

I have a table where I store some items with prices and others items without prices.
I want to select all the items with price but in the otherhand I want to select some items without prices at the same time. Is there any choice to do this?
Right now I have this select statement:
SELECT DISTINCT TOP 100 PERCENT idItem, itemDescription, price
FROM myTable
WHERE price > 0 and idItem = '000228'
Try to add price is null condition as below
SELECT DISTINCT TOP 100 PERCENT idItem, itemDescription, price
FROM myTable
WHERE (price > 0 or price is null) and idItem = '000228'
If you want to select all items with price > 0 plus the ine with id 000228, the where clause needs to be "price > 0 OR idItem = '000228'"
I assume you want to select item 000228 as well...
WHERE ISNULL(price,1) > 0 and IdItem = '000228'
Try this one -
SELECT DISTINCT idItem, itemDescription, price
FROM myTable
WHERE ISNULL(price, 0) > 0
AND idItem = '000228'

Search Invoice Tablle to find Invoices with Quantity >0 and <0

I am searching Invoice Itemized Table for Invoices with Quantity having >0 and <0. Invoice Itemized table contains details of all the items in an Invoice. How can I write a query that gives all the invoices that have Quantity of items >0 and <0.
How about something like this? This uses two queries. The first finds all the invoices with Negative Quantities. Then it APPLY's the second query to find from that list of invoices only those that also have positive quantities.
SELECT DISTINCT
PosNegInvoices.InvoiceID
FROM ItemizedInvoice AS NegInvoices
CROSS APPLY
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE InvoiceID = NegInvoices.InvoiceID
AND Quantity > 0
) AS PosNegInvoices
WHERE NegInvoices.Quantity < 0
Here is another version that uses CTEs:
WITH NegInvoices AS
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE Quantity < 0
),
PosInvoices AS
(
SELECT
InvoiceID
FROM ItemizedInvoice
WHERE Quantity > 0
)
SELECT DISTINCT
PosInvoices.InvoiceID
FROM NegInvoices
JOIN PosInvoices
ON NegInvoices.InvoiceID = PosInvoices.InvoiceID

SQL SUM, Group by and Having query

I have a pretty standard query that will get me a list of products that have stock above 0.
This works fine, however I now need to ADD the SUM of all negative numbers for BranchID 31 for the given SKU.
SELECT * FROM Products WHERE
PrimaryPLU IN
(select SKU FROM Stock
WHERE BranchID IN (2,12,1,11,0,96,32,13,14,15)
AND ApplicationID = #site
GROUP BY SKU HAVING(SUM(Stock)) > 0))
SO BranchID 31 can have positive and negative numbers, however I just need to get the sum of the negative ones for the SKU, this then needs to be added to the check to see if it's over 0.
Not a clue where to start, was hoping for support from a SQL master!
Thanks in advance!
Dave
Try this:
SELECT * FROM Products WHERE
PrimaryPLU IN
(select SKU FROM Stock
WHERE BranchID IN (2,12,1,11,0,96,31,32,13,14,15)
AND ApplicationID = #site
GROUP BY SKU HAVING(SUM(CASE WHEN Stock < 0 AND BranchID = 31
THEN Stock ELSE 0 END)) > 0))
Take the sum of absolute value of the negative numbers (stock) to see if they are non-zero.