Aggregate data from 2 tables - mysql

I want to aggregate data from table A and B into one output. Problem I am facing is that some single records are needed from table A (where is some ID in a column connected with table B containing multiple records with the same ID). I want to data in one column in table B and add this value to related ID from table A.
I have already tried with joins but it is not working for me still. Can you please take a look at this code?
select r.variable, s.variable_1 s.variable_2, sum(r.sum),
from table1 r
join table2 s on r.variable = s.variable
where some_cirrcumstances
group by r.variable ,s.variable_1
order by r.variable ,s.variable_1;
Regards
Edit: please keep an eye on this translation
Please find an example what results I want:
Data in table A:
ID | variable_1 | variable_2 | Description
There is a lot of unique rows and I want to combine it with data from table B which looks like:
Data in table B:
Week_1 | ID | other_variable_1 | our_variable
Week_1 | ID | other_variable_1 | our_variable
Week_1 | ID | other_variable_1 | our_variable
ID is a connector between but I dont know how to combine these data. We can have multiple rows for one ID and sum of column per ID is needed.

Related

Aggregate data over multiple fields (not records)

id | segment1 |segment2|segment3|segment4|**FREQUENT**
1 | A | B | A | A | A
2 | B | C | C | C | C
Need to find the most frequent letters from segment1 |segment2|segment3|segment4| i.e to find column FREQUENT.
First of all you need to copy all the segments into a single column. One can do it using UNION or a temporary table.
Then you need to count the frequency grouping the result by ID.
Then you need to get the most frequent value in every group. It can be done using self joining over LEFT JOIN or using ordering and row numbering by group. It is the most complicated part. See
Row number per group in mysql
Then you filter by the row number and enjoy the result.

get one record at a time from joint table

I want to get a record from a joint table at a time. But I don't hope the tables are joined as a whole.
The actual tables are as follow.
table contents -- stores content information.
+----+----------+----------+----------+-------------------+
| id | name |status |priority |last_registered_day|
+----+----------+----------+----------+-------------------+
| 1 | content_1|0 |1 |2020/10/10 11:20:20|
| 2 | content_2|2 |1 |2020/10/10 11:21:20|
| 3 | content_3|2 |2 |2020/10/10 11:22:20|
+----+----------+----------+----------+-------------------+
table clusters -- stores cluster information
+----+----------+
| id | name |
+----+----------+
| 1 | cluster_1|
| 2 | cluster_2|
+----+----------+
table content_cluster -- each record indicates that one content is on one cluster
+----------+----------+-------------------+
|content_id|cluster_id| last_update_date|
+----------+----------+-------------------+
| 1 | 1 |2020-10-01T11:30:00|
| 2 | 2 |2020-10-01T11:30:00|
| 3 | 1 |2020-10-01T10:30:00|
| 3 | 2 |2020-10-01T10:30:00|
+----------+----------+-------------------+
By specifying a cluster_id, I want to get one content name at a time where contents.status=2 and (contents name, cluster_id) pair is in content_cluster. The query in sql is something like follow.
SELECT contents.name
FROM contents
JOIN content_cluster
ON contents.content_id = content_cluster.content_id
where contents.status = 2
AND content_cluster.cluster_id = <cluster_id>
ORDER
BY contents.priority
, contents.last_registered_day
, contents.name
LIMIT 1;
However, I don't want the tables to be joined as a whole every time as I have to do it frequently and the tables are large. Is there any efficient way to do this? I can add some indices to the tables. What should I do?
I would try writing the query like this:
SELECT c.name
FROM contents c
WHERE EXISTS (SELECT 1
FROM content_cluster cc
WHERE cc.content_id = c.content_id AND
cc.cluster_id = <cluster_id>
) AND
c.status = 2
ORDER BY c.priority, c.last_registered_day, c.name
LIMIT 1;
Then create the following indexes:
content(status, priority, last_registered_day, name, content_id, name)
content_cluster(content_id, cluster_id).
The goal is for the execution plan to scan the index for context and for each row, look up to see if there is a match in content_cluster. The query stops at the first match.
I can't guarantee that this will generate that plan (avoiding the sort), but it is worth a try.
This query can easily be optimized by applying correct indexes. Apply the alter statements I am mentioning below. And let me know if the performance have considerably increased or not:
alter table contents
add index idx_1 (id),
add index idx_2(status);
alter table content_cluster
add index idx_1 (content_id),
add index idx_2(cluster_id);
If a content can be in multiple clusters and the number of clusters can change, I think that doing a join like this is the best solution.
You could try splitting your contents table into different tables each containing the contents of a specific cluster, but it would need to be updated frequently.

Select column by value in another table column

I have two tables:
Table A:
id | name
Table B:
id | hash | owners_id
owners_id contains the ids from table A.
Example:
Table A:
id | name
1 | James
2 | Jonas
Table B:
id | hash | owners_id
1 | j28sj | 1,2
Expect Result:
James | j28sj
Jonas | j28sj
Because both contain the ownerds_id
I'm trying to make a query that selects all the names from table A associates with table B owners_id column.
SELECT
A.name,
B.hash
FROM
A
left JOIN B ON
B.owners_id LIKE CONCAT('%', A.id, '%')
Note: The database you designed is poorly designed and it may not work it you have owners_id like 1,11,111 .so either you need to make seperate table with many to many relation or put leading zeros like 001,011,111
There are a couple ways to do this. If you want to keep owners_id as a comma-separated string, it's a bit messy. You need to first parse the string into a list of integers to form the join condition:
SELECT A.name, B.hash FROM A
LEFT JOIN B
ON find_in_set(A.id,B.owners_id) <> 0;
You may want to consider letting owners_id be an integer foreign key to Table A, if you can change your schema.
Here's a working SQL fiddle:
http://sqlfiddle.com/#!9/320477/4

mysql - correct approach to relate these tables

So, I have 2 tables
On the first table, lets call it products, lets say I have
product_id, company_id (this is a FK), product_name.
On the second table, lets call it deals, I have
deal_id, company_id (same one as the first table), deal_title.
I need to add products to the deals. if I added a product_id field to the deals table, I would have multiple rows and ids for each deal, which is completely wrong. What is the correct way to do it?
You should add a table for manage the relation between products and deals
eg:
table products_deal
product_id
deal_id
What you want is a pivot table between the two tables you have that have a structure like:
|-deal_id----|-product_id----|
| 10 | 23 |
| 10 | 24 |
| 10 | 32 |
| ...
| ...
If you need to find all products associated with deal #10, you can just use a query like SELECT * FROM pivot_table WHERE deal_id = 10

mysql lookup table

Lookup table - unique row identity
The other lookup tables just do not make sense as from what I have seen giving a row an ID then putting that id in another table which also has a id then adding these id's to some more tables which may reference them and still creating a lookup tables with more id's (this is how all the examples I can find seem) What I have done is this :
product_item - table
------------------------------------------
id | title | supplier | price
1 | title11 | suuplier1 | price1
etc.
it then goes on to include more items (sure you get it)
product_feature - table
--------------------------
id | title | iskeyfeature
1 | feature1 | true
feature_desc - table
-----------------------------
id | title | desc
1 | desc1 | text description
product_lookup - table
item_id | feature_id | feature_desc
1 | 1 | 1
1 | 2 | 2
1 | 3 | 3
1 |64 | 15
(as these only need to be referenced in the lookup the id's can be multiples per item or multiple items per feature)
What I want to do without adding item_id to every feature row or description row is retrieve only the columns from the multiple tables where their id is referenced in the same row of the lookup table. I want to know if it is possible to select all the referenced columns from the lookup row if I only know the item_id eg. Item_id = 1 return all rows where item_id = 1 with the columns referenced in the same row. Every item can have multiple features and also every feature could be attached to multiple items , this will not matter if I can just get the pattern right in how to construct this query from a single known value.
Any assistance or just some direction will be greatly appreciated. I'm using phpmyadmin, and sure this will be easier with some php voodoo I am learning mysql from tutorials ect and would like to know how to do it with sql directly.
Having a NULL value in a column is not the major concern that would lead to this design - it's the problem with adding new attribute columns in the future, at which MySQL is disgracefully bad.
If you want to make a query that returns everything about an item in one row, you need to LEFT OUTER JOIN back to the product_lookup table for each feature_id. This is about every 10th mysql question on Stack Overflow, so you should be able to find tons of examples.