SQL Selecting rows with same value of foreign key - sql

Does anyone know how to select all rows from a table with same value of FK without giving its value ? I have a database with warehouse. It has sectors and items of certain values in each sector . I want to select the sectors where overall value of items bigger than a certain number with a single query . And i want the query to be universal - it should sum up overall values of items in every sector of the warehouse ( without specyfing number of secotrs or how many sectors are there ) Anyone knows how to do it ? I don't need a full query, just a way to say my database that it to sum up all values in certain sectors. SectorID is the Foreign Key and Item is the table ( with ItemID as public key and Value as value of item )

I would make use of a combination of queries. Basically, this problem can be solved as below:
Assuming the presence of ID columns in both the Item and Sector tables. Let the value that acts as the threshold T (a certain number returned by a single query as stated above):
Use an inner query to select sector.sectorid, Item.itemid and Item.value by joining the Sector and Item tables on the Item.SectorID = Sector.SectorID Where Item.value > T
Sum(Item.value) on the result obtained from the inner query above and GROUP BY(SECTORID), GROUPBY(ITEMID).

You seem to want a group by query. This is pretty basic, so I assume you are pretty new to SQL:
select SectorId, sum(itemValue) as TotalItemValue
from warehouse w
group by SectorId
having sum(itemValue) > YOURVALUEHERE;
If you want the items in the sectors, then you can get that with a join or in:
select *
from warehouse w
where SectorId in (select SectorId
from warehouse
group by SectorId
having sum(itemValue) > YOURVALUEHERE
)

Related

Check if multiple values ALL EXIST in a table

SQL, SQL Server 2016
I've got a table "Characteristics" (from a catalog) and for a product (that comes with a list of characteristics). I need to check, if every item of the list is contained in Characteristics.
Only if all items of the list are present in the table, the catalog is considered valid.
The List of characteristics is simply a table with
ID CHARACTERISTIC
1 Blue
1 Yellow
1 Big
2 Pointy
...
For one item I can do a query like:
SELECT CatalogNumber FROM CHARACTERISTICS
WHERE EXISTS (SELECT * FROM CHARACTERISTICS WHERE Item = ID AND CHARACTERISTIC = 'Characteristic1')
AND EXISTS (SELECT * FROM CHARACTERISTICS WHERE Item = ID AND CHARACTERISTIC = 'Characteristic2')
But since the number of characteristics for each item in the list is different for each item, this approach doesn't work.
Is there a way to check, if all characteristics are in the catalog without resorting to a cursor and a loop?
Thank you in advance
Wolfgang
Select id from Characteristics
group by id
having count(*) = (select count(distinct Characteristic) from Characteristics);
DBfiddle demo

SQL-Oracle: Updating table column with sum of values from another table - using common key column/s criteria

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
)

How to use sqlite db functions to set values from calculation

I have an app (its ruby on rails but it shouldn't matter) where I am bulk loading items and quantities per branch.
The database is sqlite.
Say I have a two tables: items and quantities.
items columns:
id
quantity
quantities columns:
id
item_id
branch_id
value
I need to be able to loop through all records in the items table set the item.quantity to the sum of all quantity.value where item_id matches item.id
I would like to know if there is a way to do this all within a sql query (the select and update) so that I don't have to pull the data out of the database, do the calculation and then write the updated quantity back to each item, instead I would like to have it all occur in the database using sql statements and functions.
Is this possible in a sql query function db side?
example:
item[1] = {id=>1,quantity=>0}
quantity[1] = {id=>1,item_id=>1,value=>100,branch_id=>1}
quantity[2] = {id=>2,item_id=>1,value=>200,branch_id=>2}
quantity[3] = {id=>3,item_id=>1,value=>300,branch_id=>3}
item[1].quantity = quantity[1].value + quantity[2].value + quantity[3].value
You can do this with an update query. In this case, you can use a correlated subquery to calculate the sum of the quantities for a given item:
update item
set quantity = (select sum(value) from quantities where item.id = quantities.item_id);
EDIT:
If you want to speed it up putting an index on quantities(item_id, value).
You could also summarize quantities in a temporary table and use this instead. The index, however, however, should be sufficient for performance.
You are duplicating your data! Which means you must always keeping everything in sync.
I would prefer to create a view and get total quantities from there:
CREATE TABLE items(id, ...);
CREATE TABLE quantities(id, item_id, branch_id, value, ...);
CREATE VIEW items_sum AS SELECT items.*, SUM(quantities.value) AS quantity FROM items LEFT JOIN quantities ON items.id=quantities.item_id GROUP BY items.id;
As items_sum is a query, you don't have to update it. SELECT * FROM items_sum;will return desired results for total quantities.

Select average rating from another datatable

I have 3 data tables.
In the entries data table I have entries with ID (entryId as primary key).
I have another table called EntryUsersRatings in there are multiple entries that have entryId field and a rating value (from 1 to 5).
(ratings are stored multiple times for one entryId).
Columns: ratingId (primary key), entryId, rating (integer value).
In the third data table I have translations of entries in the first table (with entryId, languageId and title - translation).
What I would like to do is select all entries from first data table with their titles (by language ID).
On a top of that I want average rating of each entry (which can be stored multiple times) that is stored in EntryUsersRatings.
I have tried this:
SELECT entries.entryId, EntryTranslations.title, AVG(EntryUsersRatings.rating) AS AverageRating
FROM entries
LEFT OUTER JOIN
EntryTranslations ON entries.entryId = EntryTranslations.entryId AND EntryTranslations.languageId = 1
LEFT OUTER JOIN
EntryUsersRatings ON entries.entryId = EntryUsersRatings.entryId
WHERE entries.isDraft=0
GROUP BY title, entries.entryId
isDraft is just something that means that entries are not stored with all information needed (just incomplete data - irrelevant for our case here).
Any help would be greatly appreciated.
EDIT: my solution gives me null values for rating.
Edit1: this query is working perfectly OK, I was looking into wrong database.
We also came to another solution, which gives us the same result (I hope someone will find this useful):
SELECT entries.entryId, COALESCE(x.EntryUsersRatings, 0) as averageRating
FROM entries
LEFT JOIN(
SELECT rr.entryId, AVG(rating) AS entryRating
FROM EntryUsersRatings rr
GROUP BY rr.entryId) x ON x.entryId = entries.entryId
#CyberHawk: as you are using left outer join with entries, your result will give all records from left table and matching record with your join condition from right table. but for unmatching records it will give you a null value .
check out following link for the deta:
http://msdn.microsoft.com/en-us/library/ms187518(v=sql.105).aspx

How can I apply the LIMIT statement in a SQLite query to a specific side of a join?

Here's my requirement:
I have 2 tables, orders and orderContents. For each row in the orders table, there are a certain number of rows that contain description of the order. id column serves as foreign key.
What I want is to get all the details for each order (details from orderContents, including id column from orders table) table, but limit no. of results based on common column (foreign key, id)
Problem is that it limits orderContents rows, instead of limiting order rows.
How can I achieve desired effect?
EDIT: Updating tables and desired result set
Orders table:
OrderContents table:
Desired result on limiting number of records to 2:
I'm assuming you are trying to say that you want the results from both tables but only for the first X orders. If so, try this:
SELECT OC.*, O.* FROM OrderContents OC
INNER JOIN (SELECT *
FROM Orders
ORDER BY ID
LIMIT 2) O ON O.ID=OC.ID