Create groups of items from separate tables - sql

I have multiple models (events, chores, bills, and lists), which each have their own table. I want to be able to group any of these instances together, for example group an event with a list of items to buy for it, and a bill for the cost.
I was thinking each table could have a group id, and I could get other items in a group by merging records from each table where the group_id equals the items group_id.
group = Events.find_by_group_id(self.group_id).concat(Bills.find_by_group_id(self.group_id)) ...
But that seems like a bad way to do it.
Another way I thought to do it was to use a polymorphic relation between two of the items
tag
item_1_id | item_1_type | item_2_id | item_2_type
----------+-------------+-----------+------------
But in the example above (a group of three different items) would require six records, two between each pair, for each item to know of all other items in the group.
Is there a way to do this with joins, should I redesign some of the tables?

Related

Query to identify the parent/child relationship between two big tables

I have two tables. The first one contains laboratory result header records, one for each order. It has about 10 million rows in it that contain one of about 6,000 unique ProcedureIDs...
OrderID
ResultID
ProcedureID
ProcedureName
OrderDate
ResultDate
PatientID
ProviderID
The second table contains the detailed result record(s) for each order in the first table. It has about 80 million rows and contains about 28,000 child components that are associated with the 6,000 procedure IDs from the first table.
ResultComponentID
ResultID (foreign key to first table)
ComponentID
ComponentName
ResultValueType
ResultValue
ResultUnits
ResultingLab
I have a subset (n=135) procedure IDs for which I need a list of associated child component IDs. Here is a simple example...
Table 1
1000|1|CBC|Complete Blood Count|8/1/2019 08:00:00|8/2/2019 09:27:00|9999|8888
1001|2|CA|Calcium|8/1/2019 08:01:00|8/2/2019 09:28:00|9999|8888
Table 2
2543|1|RBC|Red Blood Cell Count|NM|60|Million/uL|OurLab
2544|1|PLT|Platelet Count|NM|60|Thou/cmm|OurLab
2545|2|RBC|Red Blood Cell Count|NM|60|Million/uL|OurLab
2546|1|CA|Calcium|NM|40|g/dl|OurLab
In this example, if CBC was in my subset and CA wasn't, I would expect two rows back...
CBC|Complete Blood Count|RBC|Red Blood Cell Count
CBC|Complete Blood Count|PLT|Platelet Count
Even if I had two million CBCs in the DB, I only need have one set of CBC parent/child rows.
If I were using a scripting tool, I would use a for each loop to iterate through the subset and grab the top 1 of each ProcedureID and use it to get the associated component children.
If I really wanted to go crazy with this, I would not assume that CBC only had two components, as some labs might send us two and some might send us seven.
Any advice on how to get the list of parent/child associations?
For the simple query, sometimes there is no way around just writing out all 135 ids if you can't find a neat way to get that subset out of a query or store it in a temp table.
For the uniqueness requirement, just add a 'group by'
Select t1.ProcedureId, t2.ComponentId
from Table1 t1
join Table2 t2 on t2.ResultId = t1.ResultId
where t1.ProcedureId in (
'CBC',
'etc', -- 135 times...
)
group by t1.ProcedureId, t2.ComponentId

SQL query - select only products ids which was sorted top in another table

Ok, I have situation where I need to create SQL query which will return for me ids from table1 (products) which was ordered by table2 (category) and limited by 10 for each category.
So, what I need. Select product ids which was appeared on "top 10" (limited by 10) results in each category after ordering of those products. Each product has some columns and I order by those columns. The same product can appear on different categories on top 10, for example. So I need use distinct for uniq results.
Is there any relationship between Product and Category? What at the Product columns you're ordering by? Is it ok for there to be duplication between different lists of products? You should really post you models/sql tables and more clearly explain what you're trying to do if you want real help.
Assuming they're many-to-many/the relationships are set up in rails and having the same products in multiple lists is ok I would do something like this
top_products = {}
Category.all.each do |cat|
top_products[cat.name] = cat.products.order("some_product_column DESC").limit(10).map{|p| p.id}
end

Access query/SQL - duplicates in one field with distinct multiple 2nd field

I am working on a database with products and lot numbers. Each entry in the Lots table has a Lot Number and a Product description.
Sometimes there are multiple records of the same lot number, for example when an item is repacked a new record is created, but with the same Lot Number and same product description - this is fine. But other times there are problem cases, namely when two different products share the same Lot Number. I am trying to find those.
In other words, there are 3 possibilities:
Lot numbers for which there is only one record in the table.
Lot numbers for which there are multiple records, but the Product description is the same for all of them
Lot numbers for which there are multiple records, and the product descriptions are not all the same.
I need to return only #3, with a separate record for each instance of that Lot Number and product description.
Any help would be greatly appreciated.
Thanks Juan for the sample data. Using this example, I want to return the data contained in Id 2-8, but not 1, 9, 10, 11.
This wasn't easy because lot of time don't use access.
First select unique values using distinct.
Then count how many diferent product appear on each lotnumber using group by
Last join both result and show only the lots with more than one description where total >1
.
SELECT id, Product.lotnumber, Product.Product, total
FROM
Product Inner join
(
SELECT lotnumber, count(*) as total
FROM
(SELECT distinct lotnumber, product
FROM Product)
GROUP BY lotnumber
) SubT On Product.lotnumber = SubT.lotnumber
WHERE total > 1
ORDER BY id
As you can see :
lot 2 have two products (yy and zz)
lot 3 have thre products (aa, bb, cc)
I include my product table:
Sorry for spanish. Field types are Autonumeric, Short Text, and Number

Query accross a circle of tables

I'm curious about how I could go about getting the data I need out of a "circle" of tables.
I have 5 tables(and a few supporting ones): 3 entities joined by junction tables. So the general model is like this:
Cards have many Budgets, and Accounts have many Budgets, and Accounts have many Cards.
So my relationships make a circle, through the junction tables, form Card to Budget to Account back to Card, This structure works all fine and dandy until today when I tried to construct a query using all 5 tables, and noticed that I know of no way to avoid abiguous joins which this structure in place. I'm thinking it might have been a better idea to create AccountBudget and CardBudget tables, but since they will both define exactly the same type of data, one table seemed more efficient.
The information I'm trying to get is basically the total budget limit for all cards of a certain type, and the total budget limit for all accounts of that same type. Am I just looking at this problem wrong?
// Card Budget_Card Budget Budget_Account Account
// ------- --------- -------- -------------- ---------
// cardId------\ budgetId<---------budgetId------>budgetId -----accountId--(to Card)->
// accountId --->cardId limit accountId<------/ typeId
// (etc) typeId (etc)
// (typeId in Budget is either 1 for an account budget or 2 for a card budget.)
As you can see, it's a circle. What I'm trying to accomplish is return one row with two columns: the sum of Budget.limit for the record in Account where typeId = 1, and the sum of Budget.limit for all rows in Card belonging to Accounts of the same type.
As per suggestion, I can in fact get the data I need from a union, but it's no use to me if the data is not in two separate columns:
SELECT DISTINCTROW Sum(Budget.limit) AS SumOfLimit
FROM (Account RIGHT JOIN Card ON Account.accountId = Card.accountId)
RIGHT JOIN (Budget LEFT JOIN Budget_Card ON Budget.budgetID = Budget_Card.budgetId) ON Card.cardId = Budget_Card.cardId
GROUP BY Budget.typeId, Budget.quarterId, Account.typeId
HAVING (((Budget.typeId)=2) AND ((Budget.quarterId)=[#quarterId]) AND ((Account.typeId)=[#accountType]))
UNION SELECT DISTINCTROW Sum(Budget.limit) AS SumOfLimit
FROM Budget LEFT JOIN (Account RIGHT JOIN Budget_Account ON Account.accountId = Budget_Account.accountId) ON Budget.budgetID = Budget_Account.budgetId
GROUP BY Budget.typeId, Budget.quarterId, Account.typeId
HAVING (((Budget.typeId)=1) AND ((Budget.quarterId)=[#quarterId]) AND ((Account.typeId)=[#accountType]));
So, if I understand you correctly, you've made separate column headers with the same name, and so your data becomes skewed because the information needs to be separated? If this is the case I would suggest changing the column headers as you've proposed, or in linking two queries together. To connect the data by querying the same tagged name will combine results. If you want to designate something, it's always a good idea to create separate names for column headers.
Here is an explanation of using SQL to query multiple tables: http://www.techrepublic.com/article/sql-basics-query-multiple-tables/1050307
First make the query for the Cards, then union with the query for the Accounts
Although it would be easier to relate cards to accounts and then only have budgets for accounts, however i don't know if that would work with your schema

How to count unique records and get number of these uniques in table using SQL?

Imagine I have table like this:
id:Product:shop_id
1:Basketball:41
2:Football:41
3:Rocket:45
4:Car:86
5:Plane:86
Now, this is an example of large internet mall, where there are shops which sell to one customer, so customer can choose more products from each shop and buy it in one basket.
However, I am not sure if there is any SQL syntax which allows me to simply get unique shop_ids and total number of those shops' products in customer basket. So I'd get something like:
Shop 41 has 2 products
Shop 45 one product
Shop 86 two product
I can make SQL queries to scoop through table to make some kind of ['shop_id']['number_of_products'] array variable that would store all products' shop_ids, then "unique them" - up and count how many times I had to cut one more shop_id out to have some remaining but that just seems as a lot of useless scripting.
If you got some nice and neat idea, please, let me know.
This is exactly the sort of thing that aggregate functions are for. You make one row of output for each group of rows in the table. Group them by shop_id and count how many rows are in each group.
select shop_id, count(1) from TABLE_NAME
group by shop_id