Clearly a newbie to this platform. I've been a long time reader of stack overflow, but first time poster, so do go easy on me please.
I have 2 databases (within same instance), one for each company. Let's call them company A and company B. Both of these databases have the following columns:
ProductID, Warehouse, Quantity
I would like to create a SQL View where it has 3 columns:
ProductID, Quantity A (from database A), Quantity B (from database B)
I would also like to include the following conditions:
It should only return results for products that either have stock in Quantity A or Quantity B or Both. It shouldn't return any results if no stock in any of the databases.
For Quantity A - return results where warehouse = XY and XZ
For Quantity B - return results where warehouse = XY
Any help is much appreciated
If I understand correctly, you have two separate tables for each company that you want to combine at the product level.
One method is union all and group by:
select productid, sum(quantity_a) as quantity_a,
sum(quantity_b) as quantity_b
from ((select productid, quantity as quantity_a, 0 as quantity_b
from a
) union all
(select productid, 0 as quantity_a, quantity as quantity_b
from b
)
) ab
group by productid;
Related
this is an answer to the question : We need a list of customer IDs with the total amount they have ordered. Write a SQL statement to return customer ID (cust_id in the Orders table) and total_ordered using a subquery to return the total of orders for each customer. Sort the results by amount spent from greatest to the least. Hint: you’ve used the SUM() to calculate order totals previously.
SELECT prod_name,
(SELECT Sum(quantity)
FROM OrderItems
WHERE Products.prod_id=OrderItems.prod_id) AS quant_sold
FROM Products
;
So there is this simple code up here, and I know that this WHERE clause is comparing two columns in two different tables. But since We are calculating the SUM of that quantity, why do need that WHERE clause exactly. I really couldn't get it. Why the product_id exactly and not any other column ( p.s: the only shared column between those two tables is prod_id column ) I am still a beginner. Thank you!
First you would want to know the sum for each product - so need to adjust the subquery similar to this:
(SELECT prod_id, Sum(quantity) qty
FROM OrderItems
group by prod_id
) AS quant_sold
then once you know how much for each product, then you can link that
SELECT prod_name,
(SELECT prod_id, Sum(quantity) qty
FROM OrderItems
group by prod_id
) AS quant_sold
FROM Products p
WHERE p.prod_id = quant_sold.prod_id
Run it without the where clause and compare the results. You'll learn a lot that way. specifically focus on two different product Ids ensuring they both have order items and quantities.
You have two different tables involved. There are multiple products. You don't want the sum of all orders on each product; which is what you would get without the where clause. So the where clause correlates the two tables ensuring you only SUM the quantity of each order item for each product between the tables. Personally, I'd use a join, sum, and a group by as I find it easier to read and I'm not a fan of sub selects in the select of another query; but that's me.
SELECT prod_name,
(SELECT Sum(quantity)
FROM OrderItems
WHERE Products.prod_id=OrderItems.prod_id) AS quant_sold
FROM Products
Should be the same as:
SELECT prod_name, Sum(coalesce(P.quantity,0))
FROM Products P
LEFT JOIN orderItems OI
on P.prod_id=OI.prod_id
GROUP BY Prod_Name
'Notes
the above is untested.
a left join is needed because all products should be listed and if a product doesn't have an order, the quantity would be zero.
if we use an inner join, the product would be excluded.
We use coalesce because you'd have a "Null" quantity instead of zero for such lines without an order item.
as to which is "right" well it depends and varies on different cases. each has it's own merits and in different cases, one will perform better than another, and in a different case, vice-versa. See --> Join vs. sub-query
As an example:
Say you have Products A & B
"A" has Order Item Quantities of 1 & 2
"B" has order item Quantities of 10 & 20
If we don't have the where clause every result record would have qty 33
If we have the where product "A" would have 3
product "B" would have qty 30.
I am working on a legacy app, I am still learning SQL and would consider my SQL knowledge as beginner.
I have 2 tables, one is a receipt type structure containing receipt no, a docket number (plus other info regarding total etc) and a car rego number.
there are the potential for multiple receipts for a car ie multiple matches on rego number
The second has a listing of the items related to that receipt (description, partno, time) each of the items are related by docketnumber - the "registerhistory"
multiple items appear as multiple rows (with same docketnumber) in the "registerhistory" and also items of the same type are not stored as a qty but as duplicated rows in the table with the same docket number each have a price stored
I am trying to generate a report based upon a search match on rego number and create a join to the matching tableregister items and list them (with hopefully an end goal of grouping any duplicate items into a qty and subtotal)
This is an access database if that changes the syntax
I am unclear on how I can take the results of one select query and use these results to create a join or there might be a better approach
So I need to firstly locate all receipts with a matching rego number, with those receipts, find the associated items (by docket number) hopefully group the items like so
receipt no 1
Item1 with multiples as qty with subtotal
Item2
Item3
receipt no 2
Item1
Item2 with multiples as qty with subtotal
Item3
Any help greatly appreciated,
(SELECT * from tblreceipts
where vehicle = 'abc123')
join tblregisterhistory on
tblreceipts.docketnum = tblregisterhistory.docketnum
I can even get to linking the results from the select query to a join, let alone get to my desired end result.
Are you trying to simply do a JOIN and GROUP BY? Something like this:
select partno, count(*) as qty
from tblreceipts as r inner join
tblregisterhistory as rh
on rh.docketnum = r.docketnum
where r.vehicle = 'abc123'
group by partno;
Ok with a bit of study and some helpful hints above. I have this (also apologies for the code formatting, still familiarising myself with the stack posting techniques)
SELECT vehicle, tblregisterhistory.date, partnumber, count(partnumber) as qty,
description, sum(price) as subtotal
FROM TBLRECEIPTS INNER JOIN
tblregisterhistory ON tblreceipts.docketnumber =
tblregisterhistory.docketnumber where tblreceipts.vehicle = 'abc123' group by
tblregisterhistory.date, vehicle, partnumber, description, price
Good Evening Stackoverflow team/members
Oracle version: 11g Release 11.1.0.6.0 - 64bit Production
I have two Tables: ORDERS and ITEMS.
ORDERS looks like this
ORDERS
ITEMS looks like this
enter image description here
Table ORDERS has 1 or more Order_Number each assigned to at least one depot or more. the column Total_Value SHOULD store exactly the sum of the item values associated to an order number. the table ITEMS in fact stores via parcel_code items values for a specific order_number/s.
my db has a bug for orders that have more than one depot assigned to an order number (e.g. order number 1 and 4) do not store the actual total value correctly.
in my case I cannot figure out the UPDATE statement that would select order numbers that would take the sum from the table ITEMS and link it via parcel_code and update the column total_value in the table ORDERS.
the result of my update should give this back:
for table orders i should get back for
order number 1:
for both rows total value 1120
order number 4
for both rows total value: 350
order number 2 and 3 as they are single depot order remain the same:
50 and 20
pseudo-code :
update ORDERS
set total_value = (select sum(I.item_value) from ITEMS I, ORDERS O where O.parcel_code = I.parcel_code)
i would update also those orders which have on e depot assigned as they will exactly the same.
i was looking at MERGE statements or INNER select queries. the problem i am facing is that my update must be dynamic. this means not driven by values but by columns joins as i may have to create a process that update this every day.
can someone help me?
You need to join the items and orders tables together, then select the sum of all item_values where your order_number is equal to the row which you are updating (in table o1).
update
Orders o1
set o1.total_value = (
select sum(i.item_value) from Items i
join Orders o2 on o2.parcel_code = i.parcel_code
where o2.Order_number = o1.Order_number
)
I have a large table of orders with 20+ columns. Within this there are ACCOUNT_ID and PAYMENT_TYPE.
I'd like to have three separate tables, based on preferred (most common) payment type.
I can count the payment type for each client easily enough, but have no idea as to the logic behind achieving what I need.
Hoping someone can point me int he right direction?
Please let me know if this is not clear, or an example is needed
Assuming you wanted the tables split as different payment types, use views and not separate tables or each time you insert a row into Orders, you need to also insert into the relevant Order[PaymentType] table through some mechanism (manually, trigger etc).
As W3schools puts it:
In SQL, a view is a virtual table based on the result-set of an SQL
statement.
You define a query that returns a result set, then you can treat that like you would a table. This means as you insert rows into Orders, you can view them in your view if they match the conditions, you do not need to worry about updating another table.
Assuming you wish to split them on payment types, and you had a similar payment type table as the following:
PaymentTypeId PaymentTypeDesc
----------------------------------
1 Cash
2 Cheque
3 Credit Card
then the following might be what you're looking for.
CREATE VIEW vw_OrdersCash AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE = 1
CREATE VIEW vw_OrdersCheque AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE = 2
CREATE VIEW vw_OrdersCreditCard AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE = 3
Just treat them as tables to do whatever you wish.
SELECT * FROM vw_OrdersCash
EDIT:
Reading one of your comments to your question, it sounds like you want it more dynamic than the suggestion above. It's hard to tell without sample output what it is you're trying to achieve, but if you wanted 3 dynamic tables you could extend the above, and rather than the views filtering to a specific payment type, they would filter to the 1st, 2nd and 3rd most common at the time of execution.
An idea of how to do this is below. The lookup view vw_OrdersTopThreePaymentMethods looks at the orders table and returns the top three payment types in descending order of number of orders (ie 1st, 2nd, 3rd). There are then views that will grab all of the orders on that specific type, with all the order information available for you to query as you want.
-- A lookup view that returns the top 3 payment methods of orders
CREATE VIEW vw_OrdersTopThreePaymentMethods AS
SELECT TOP 3
ROW_NUMBER() OVER(ORDER BY a.OrderCount DESC) AS Row,
PAYMENT_TYPE,
OrderCount
FROM (
SELECT PAYMENT_TYPE , COUNT(*) as 'OrderCount'
FROM Orders
GROUP BY PAYMENT_TYPE
) a
ORDER BY a.OrderCount desc
-- 3 views that then get the orders for the top three methods based on output of vw_OrdersTopThreePaymentMethods
CREATE VIEW vw_OrdersPrimaryPayment AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE IN (
SELECT PAYMENT_TYPE
FROM vw_OrdersTopThreePaymentMethods
WHERE Row = 1
)
CREATE VIEW vw_OrdersSecondaryPayment AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE IN (
SELECT PAYMENT_TYPE
FROM vw_OrdersTopThreePaymentMethods
WHERE Row = 2
)
CREATE VIEW vw_OrdersTertiaryPayment AS
SELECT *
FROM Orders
WHERE PAYMENT_TYPE IN (
SELECT PAYMENT_TYPE
FROM vw_OrdersTopThreePaymentMethods
WHERE Row = 3
)
I am joining 2 tables using Cartesian Product as follows.
select p.type, i.amount
FROM products p, invoice i
where (p.account = i.id); -- column headers cant be changed despite having same info
This of course displays 2 columns with the respective values.
However I then want to manipulate the data further using COUNT/GROUP BY and SUM/GROUP BY but have been unable to find any relevant examples which I could get to work using 2 tables. (doing them all separately is ok, just getting them to work together is the problem).
For the end result, I want to show 3 columns showing a grouping of the 4 types, with the count of the entries falling under each type, and the total amount/SUM for each type, eg.
Type - Count of Types - Total Value
A - 5 - 500
B - 6 - 1000
C - 1 - 50
D - 2 - 100
Did you try this?
select p.type, count(p.type) Cnt, sum(i.amoumt) Total
FROM products p, invoice i
where (p.account = i.id)
group by p.type
Bear in mind that the result of a query is logically equivalent to a table or a view -- all of them are a projection of zero or more rows with one or more columns.
In general what you can do to a table in terms of select you can also do to a query or a view. Despite some limitations you can also apply deletes and updates to views and queries just as you can to a table.
If in doubt, create the query that returns the data you want, and then treat it as a table:
select type,
count(type) count_type,
sum(amount) sum(amount)
from (select ... )
group by type
Note also the subquery factoring clause, which has particular appplications if you need to reference the same logical data set multiple times:
with my_data as(
select ... )
select type,
count(type) count_type,
sum(amount) sum(amount)
from my_data
where type in (select ... from my_data)
group by type