i'm working on an advanced search functionality on my website.
Basically data I'm working on is stored within two tables.
First table contains basic information about the product (1 row = 1 product so it's unique).
Table structure may look like this:
id, title, description
The second table contains more information about the product. The product may but don't have to have any rows here. However, one product may store in the second table a few rows. What's more - data in the second table should be used to the advanced search functionality. Table structure may looks like this:
id, item_id (from table 1), value_id (from another table), value
I want to select only these products (table 1) which has specified value_id (from column 2):
... WHERE table1.item_id = 5 AND table2.value_id = 1000
As I mentioned before - table 2 may but doesn't have to contains any rows connected by item_id with the table 1.
I've tried to use JOIN/LEFT JOIN function in SQL but in this case when the product has 3 rows in the table 2 - a query result returns 3 rows instead of 1 or 0 (if not found any results).
How can I handle that?
You want to select products. So select from the product table. You want to select only those for which exists a certain attribute. So create an approriate WHERE clause. As you want to look up data in another table, you could use EXISTS or IN.
select *
from items
where id in (select item_id from item_values where value_id = 1000);
I have two tables roughly designed like this
id | title | price
&
id | title | price | description
I am trying to use a LEFT JOIN to match the results by "id".
This works if I state exactly which table the title should come from i.e a.title. But what I need to do is list the title and price from the second table if it has results. If there are no result from the second table then the first tables results for title a price should be used. When I do any combination of results using select all for both tables it just gives NULL values for the columns that are present in both tables, i.e all but description.
try left join with
coalesce(secondTable.price,firstTable.price) as price,
coalesce(secondTable.title,firstTable.title) as title
I am Using CI with hmvc..
I have 3 tables:
Table 1:
s_id | s_name | s_date
Table 2:
n_id | n_name | n_date
Table 3 contains the relation between table 1 and table 2:
s_id | n_id
I want to fetch values in table 1 or table 2 by ids.
Once I have n_id of table 2, I want to find and to fetch the related values in table 3 and table 1. The related values match by having the same ids.
Please help.
I think this might work for you. I have done something similar in the past while using CI. This is an Active Records query that should be in your model. This query can be shortened but I made it verbose so you see what is going on.
public function get_ids($n1_id){
$this->db->select('*');
$this->db->from('table_3');
$this->db->join('table_2', 'table_2.n1_id = table_3.n1_id');
$this->db->join('table_1', 'table.s1_id = table_3.s1_id');
$this->db->where('n1_id', $n1_id);
$query = $this->db->get();
return $query;
}
Basically once you have one of the id's you can pass it in as a parameter and select all the rows from table 3 that matches the id. Then join table 1 and table 2 on the matching rows in table 3.
Let me know if this works. I have not make the tables to test it.
I have a table with this structure
(int)id | (text)title | (text)description | (int)related
and a query which joins the table with itself
SELECT t1.*, t2.title as relatedTitle
FROM mytable t1 LEFT JOIN mytable t2 ON t2.related=t1.id
to produce in one SELECT list like this
title: Hi, description: informal greetings, see also: Hello
When a new record is stored into the table, only one other record can be referenced
What I try to achieve is cross reference
which can be among 2-5 objects
All objects should be cross referenced in every combination. I want this feature: if related is set, the script should automagically create cross reference in the related records. If record is deleted, the script should update the reference in the related records.
For 3+ records cross referenced, I am considering this joining table
(int)id | (int)related
but it would be 20 records for 5 cross referenced objects. I could also create one-column table
(varchar)relatedList
but how to create the left join and how to delete relations in this structure? Or should I try some other approach like triggers, views or temporary tables? I want to avoid redundance and keep it as simple as possible and just can't figure this out.
If your groups are typically bigger than 2, then you should create a list of groups - if A is connected to B and C it makes a group A,B,C.
So, as soon as a relation is inserted, you check if the related item is already in a group. If it is set, then the "new" related entry is also in that group.
If not, you just created a new group which contains those two Items.
So if from your Example "Hi" is alone, and "Ho" gets connected to "Hi", then both form a new group.
When "Ahoi" also gets into connection to "Hi", it just needs to copy the group_id from Hi.
EDIT: according to the comment asking for the select:
The structure:
table groups: group_id int not null primary key auto_increment, created_tmstmp timestamp
table items: item_id int, group_id int default null
The select:
select * from items i1
inner join items i2 on i2.item_id != i1.item_id
and i2.group_id = i1.group_id
where i1.id = <given item>.
The insert of a relation may be connected to insert of one of the Items, this depends on the scenario of the Thread Owner. If it is a new relation for both entries then a new group is inserted.
Other questions are: is an item only in one group? Otherwise one needs a item_group table to connect a item to more then one group.
No join on strings, sorry for the possibility to be understood so cruelly. ;-)
As mzedeler said a many-to-many relation is usually realized using a join table. Please consider using a separate id column so you'd get
Id,rel1,rel2
That way frameworks like hibernate would know what to do. This makes even more sense considering the fact that you are talking about a transitive and symmetric relation. So for 4 related items 3 entries could suffice if your script does some basic inference. Of course you would need to fill the gap in a given relation chain if a connecting entry where removed.
Go with this one:
(int)id | (int)related
It is a very common approach.
If you use the list approach, your SQL queries will be extremely complicated.
Generally, SQL engines are very good at optimizing queries against tables with very large numbers of rows, so at most reasonable hardware, you shouldn't have to worry about millions of rows in such table. (Depending on what you are going to use it for, of course.)
To model non-directed edges, always insert the lowest id in the id column (you can add a CHECK constraint to enforce this). By doing this, you'll eliminate half of the tuples.
If you run into performance issues because you want to model a complete graph, consider only using the table above for "neighbor" connections, calculate the completion of the graph and insert it into a table that contains partitions of all items, one partition for each complete subgraph:
(int)partition | (int)id
Lets take a look at an example. Given the items (1 .. 8) and the edges (1, 2), (1, 3), (4, 3), (6, 5), (6, 7) - not including the edges that are required to complete the graph, you get
(int)id | (int)related
1 | 2
1 | 3
3 | 4
5 | 6
6 | 7
(And no records with the item 8.)
And then in the partition table:
(int)partition | (int)id
1 | 1
1 | 2
1 | 3
1 | 4
2 | 5
2 | 6
2 | 7
3 | 8
To check if an item is related to another item will only be a self-join on the partition table, but changing the graph requires manipulation of both tables.
I have one table with unique IDs and second table where these IDs have stored different values. Second table might have several rows with the ID from first table. I want to get print out complete content of table #one and have one more additional column containing only if one of ID matching ID from table one has * (star) character stored.
First Table
|id1|value1|value2|value3|value4|
Second table
|id2|value1|value2|id1|value4|
| | | | | *|
Desired output
|id1|value1|value2|value3|value4|value5 with * or empty
What would be the mysql syntax?
select *, s.value4
from first_table f
left outer join second_table s
on f.id1 = s.id1
and s.value4 = "*"