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

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

Related

SQL Pivot column values

I have tried following this and this(SQL Server specific solution) but were not helpful.
I have two tables, Product and Sale and I want to find how many products are sold on each day. But I want to pivot the table so that columns become the products name and each row will contain the amount of products sold for each day ordered by the day.
Simplified schema is as following
CREATE TABLE product (
id integer,
name varchar(40),
price float(2)
);
CREATE TABLE sale(
id integer,
product_id integer,
transaction_time timestamp
);
This is what I want
I only managed to aggregate the total sales per day per product but I am not able to pivot the product names.
select date(sale.transaction_date)
, product.id
, product.name
, count(product_id)
from sale inner join
product on sale.product_id = product.id
group by date(sale.transaction_date)
, product.id
, product.name
This is the situation so far
Please suggest.
You need pivoting logic, e.g.
select
s.transaction_date::date,
count(case when p.name = 'intelligent_rubber_clock' then 1 end) as intelligent_rubber_clock,
count(case when p.name = 'intelligent_iron_wallet' then 1 end) as intelligent_iron_wallet,
count(case when p.name = 'practical_marble_car' then 1 end) as practical_marble_car
from sale s
inner join product p
on s.product_id = p.id
group by
s.transaction_date::date;
Since your expected output aggregates by date alone, then only the transaction date should be in your GROUP BY clause. The trick used here is to take the count of a CASE expression which returns 1 when the record is from a given product, and 0 otherwise. This generates conditional counts for each product, all in separate columns. To add more columns, just add more conditional counts.

Subtract two SUM GROUP BY fields

I have two tables itemOrders and itemUsage.
itemOrders has two fields: item_number and qty_ordered
itemUsage has two fields: item_number and qty_used
I'm trying to word my SQL query so that it sums up the quantity of each item number in both tables then subtracts the totals in itemUsage from itemOrders
I've come up with this so far:
SELECT itemOrders.item_number
,(
SELECT sum(qty_ordered)
FROM itemOrders
GROUP BY itemOrders.item_number
) - (
SELECT sum(qty_used)
FROM itemUsage
GROUP BY itemUsage.item_number
) AS item_total
FROM itemOrders
INNER JOIN itemUsage
ON itemOrders.item_number = itemUsage.item_number
GROUP BY itemOrders.item_number
What happens here is that all fields come out to 0.
Example if item number "A" was showing a total quantity of 3 ordered across all instances of "A" in the itemOrders table, and only a total quantity used of 1 across all instances of "A" in the itemUsage table. The sql should show the number one in the item_total field next to 1 instance of "A" in the item_number field.
The problem is you are creating a CARTESIAN PRODUCT and repeting the values on the SUM just calculate each value separated and then LEFT JOIN both. In case no item are used COALESCE will convert NULL to 0
SELECT io_total.item_number,
order_total - COALESCE(used_total, 0) as item_total
FROM (SELECT io.item_number, sum(io.qty_ordered) as order_total
FROM itemOrders io
GROUP BY io.item_number
) io_total
LEFT JOIN (SELECT iu.item_number, sum(iu.qty_used) as used_total
FROM itemUsage iu
GROUP BY iu.item_number
) as iutotal
ON io_total.item_number = iutotal.item_number
Well it looks like you are making three queries, two separate ones, one for each sum, and one with an inner join that isn't being used.
Try
Select itemOrders.item_number, sum(itemOrders.qty_ordered - itemUsage.qty_used) as item_total
from itemOrders INNER JOIN itemUsage
On itemOrders.item_number = itemUsage.item_number
GROUP BY itemOrders.item_number

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'

select least row per group in SQL

I am trying to select the min price of each condition category. I did some search and wrote the code below. However, it shows null for the selected fields. Any solution?
SELECT Sales.Sale_ID, Sales.Sale_Price, Sales.Condition
FROM Items
LEFT JOIN Sales ON ( Items.Item_ID = Sales.Item_ID
AND Sales.Expires_DateTime > NOW( )
AND Sales.Sale_Price = (
SELECT MIN( s2.Sale_Price )
FROM Sales s2
WHERE Sales.`Condition` = s2.`Condition` ) )
WHERE Items.ISBN =9780077225957
A little more complicated solution, but one that includes your Sale_ID is below.
SELECT TOP 1 Sale_Price, Sale_ID, Condition
FROM Sales
WHERE Sale_Price IN (SELECT MIN(Sale_Price)
FROM Sales
WHERE
Expires_DateTime > NOW()
AND
Item_ID IN
(SELECT Item_ID FROM Items WHERE ISBN = 9780077225957)
GROUP BY Condition )
The 'TOP 1' is there in case more than 1 sale had the same minimum price and you only wanted one returned.
(internal query taken directly from #Michael Ames answer)
If you don't need Sales.Sale_ID, this solution is simpler:
SELECT MIN(Sale_Price), Condition
FROM Sales
WHERE Expires_DateTime > NOW()
AND Item_ID IN
(SELECT Item_ID FROM Items WHERE ISBN = 9780077225957)
GROUP BY Condition
Good luck!

Using 2 fields in ORDER BY clause

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?