SQL - Find pairs and update + insert - mysql

i have a table like this
ID | map | status |
===================================
1 | 1 | searching |
2 | 1 | searching |
3 | 2 | searching |
4 | 2 | searching |
5 | 1 | searching |
6 | 3 | searching |
I want to go trough the table and find pairs (only 2) where status is searching and they are having the same map. Then update their status and INSERT some information from the two rows into another table.
EDIT: The values in map are unknown. So i need to get them first and "iterate" to find pairs.

This will pair each ID with the next matching ID; if there are more than 2 you will get some overlap.
Select * from
TableName as t1
inner join
TableName as t2
on
t1.status= 'searching'
and t2.status = 'searching'
and t1.map=t2.map
and t1.id<t2.id

Related

MySql add relationships without creating dupes

I created a table (t_subject) like this
| id | description | enabled |
|----|-------------|---------|
| 1 | a | 1 |
| 2 | b | 1 |
| 3 | c | 1 |
And another table (t_place) like this
| id | description | enabled |
|----|-------------|---------|
| 1 | d | 1 |
| 2 | e | 1 |
| 3 | f | 1 |
Right now data from t_subject is used for each of t_place records, to show HTML dropdowns, with all the results from t_subject.
So I simply do
SELECT * FROM t_subject WHERE enabled = 1
Now just for one of t_place records, one record from t_subject should be hidden.
I don't want to simply delete it with javascript, since I want to be able to customize all of the dropdowns if anything changes.
So the first thing I though was to add a place_id column to t_subject.
But this means I have to duplicate all of t_subject records, I would have 3 of each, except one that would have 2.
Is there any way to avoid this??
I thought adding an id_exclusion column to t_subject so I could duplicate records only whenever a record is excluded from another id from t_place.
How bad would that be?? This way I would have no duplicates, so far.
Hope all of this makes sense.
While you only need to exclude one course, I would still recommend setting up a full 'place-course' association. You essentially have a many-to-many relationship, despite not explicitly linking your tables.
I would recommend an additional 'bridging' or 'associative entity' table to represent which courses are offered at which places. This new table would have two columns - one foreign key for the ID of t_subject, and one for the ID of t_place.
For example (t_place_course):
| place_id | course_id |
|----------|-----------|
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 3 |
As you can see in my example above, place 3 doesn't offer course 2.
From here, you can simply query all of the courses available for a place by querying the place_id:
SELECT * from t_place_course WHERE place_id = 3
The above will return both courses 1 and 3.
You can optionally use a JOIN to get the other information about the course or place, such as the description:
SELECT `t_course`.`description`
FROM `t_course`
INNER JOIN `t_place_course`
ON `t_course`.`id` = `t_place_course`.`course_id`
INNER JOIN `t_place`
ON `t_place`.`id` = `place_id`

Select all values from a table plus a column returning 1/0 whether a record exists in other table [duplicate]

This question already has answers here:
Selecting boolean in MySQL based on contents of another table
(2 answers)
Closed 4 years ago.
I need some help with a MySQL query which is bringing me a headache.
Basically I have two tables which are related. The first table is called 'books' and it contains the basic information about a book. Then I have an other table called 'user_books' which is related to the previous table and other table (which is irrelevant in the question). This is how the books table looks like:
| b_id | b_name | b_description |
---------------------------------------------------
| 1 | Book1 | Description1 |
| 2 | Book2 | Description2 |
The 'user_books' table has this content:
| ub_userid | ub_bookid | ub_rating | ub_default |
------------------------------------------------------
| 10 | 1 | 5 | 1 |
The user_books table has two primary keys: ub_userid and ub_bookid.
Now I need to make a query which returns all books of the books table and for each book the rating of a given user and a column that in case that there is a record for the book in the user_books table return 1 but if there isn't any book with that bookid return 0.
My desired output given the user 10 would be this:
| b_id | b_name | b_description | ub_default | active |
----------------------------------------------------------
| 1 | Book1 | Description1 | 1 | 1 |
| 2 | Book2 | Description2 | 0 | 0 |
----------------------------------------------------------
I'm using MySQL 5.7
Thanks so much in advance for any kind of help.
select
b.b_id,
b.b_name,
b.b_description,
coalesce(ub.ub_default, 0) as ub_default,
case
when ub.ub_userid is null then 0
else 1
end as active
from books b left outer join
user_books ub
on ub.ub_bookid = b.b_id
where
ub.ub_userid = 10;
This doesn't do any aggregation, so if you have multiple user_books records for one books record, then the books record will be duplicated. But, it shows how to join against a missing row (outer join) and test for whether that outer join row is present or missing.
Here's a SQL Fiddle for MySQL 5.6 http://sqlfiddle.com/#!9/b70ff8/4/0

MySQL table order by one column when other column has a particular value

I have two mysql tables record_items,property_values with the following structure.
table : property_values (column REC is foreign key to record_items)
id(PK)|REC(FK)| property | value|
1 | 1 | name | A |
2 | 1 | age | 10 |
3 | 2 | name | B |
4 | 3 | name | C |
5 | 3 | age | 9 |
table: record_items
id(PK) |col1|col2 |col3|
1 | v11| v12 | v13|
2 | v21| v22 | v23|
3 | v31| v32 | v33|
4 | v41| v42 | v43|
5 | v51| v52 | v53|
record_items table contains only basic information about the record, where as property_values table keeps record_item as a foreign key and each property and its value is saved in a separate row.
Now I want to get the record_items sorted based on a particular property, say by age.
My HQL query will be like
Select distinct rec from PropertyValues where property="age" order by value;
But this query will be skipping record 2 since it don't have an entry for property age.
I expect the result to have the records which contains age property in sort order appended by those which don't have age property at all. How can I query that?
Here is a raw MySQL query which should do the trick:
SELECT t1.*
FROM record_items t1
LEFT JOIN property_values t2
ON t1.id = t2.REC AND
t2.property = 'age'
ORDER BY CASE WHEN t2.value IS NULL THEN 1 ELSE 0 END, t2.Value
I notice that your Value column in property_values is mixing numeric and text data. This won't work well for sorting purposes.
Demo here

MySQL Update Based on ID Slow (150,000 records)

I'm trying to update a table based on the id on another table but I'm having some performance issue. I have 150,000 rows on table_to_update, and 400,000 rows on table_to_get_data.
Table to Update
+----+-----------------+
| id | field_to_update |
+----+-----------------+
| 1 | orange |
| 2 | apple |
| 3 | pear |
| 1 | orange |
+----+-----------------+
Table to Get Data
+----+-----------------+
| id | field |
+----+-----------------+
| 1 | orange |
| 2 | apple |
| 3 | pear |
+----+-----------------+
So I've tried 3 different ways:
Method 1:
UPDATE table_to_update t1, table_to_get_data t2
SET t1.field_to_update = t2.field
WHERE t1.id = t2.id
Method 2:
UPDATE table_to_update
JOIN table_to_get_data
ON table_to_update.id = table_to_get_data.id
SET table_to_update.field_to_update = table_to_get_data.field
Method 3:
UPDATE table_to_update
LEFT JOIN table_to_get_data
ON table_to_update.id = table_to_get_data.id
SET table_to_update.field_to_update = table_to_get_data.field
So far, Method 3 seems to be the fastest, however, calculating the time it would take to update 1000 rows, it will take me 12 hours to finish updating the entire table. Is there a more efficient method to update the table?
EDIT:
Added EXPLAIN table
EXPLAIN Table
Create Index on columns you have joined from both the tables.
It will make wonders for you.

MySQL: Matching records from 2 tables with multiple values

I have 2 tables:
table1
id | title | author | url
1 | the-test | james-brown | www.thetest.com
2 | the-house | clancy-brown | www.thehouse.com
3 | the-desk | leanne-brown | www.thedesk.com
4 | the-head | julie-brown | www.thehead.com
table2
id | title | author | url**
1 | the-mouse | john-blue | www.themouse.com
2 | the-house | clancy-brown | www.thehouse.com
3 | the-cups | carrie-blue | www.thecups.com
4 | the-head | clancy-brown | www.thehead.com
I need results to show only where both title and author match, i.e.
2 | the-house | clancy-brown | www.thehouse.com
I've tried this:
select *
from table1
inner join table2 on (table1.title=table2.title) AND (table1.author=table2.author)
But it just runs forever (there are actually several hundred thousands rows in the real tables).
Just to note, this works fine:
select *
from table1
inner join table2 on (table1.title=table2.title)
I just can't get it to match both tables. Is there a smarter way to do this?
Thanks for all help in advance.
I think your SQL is fine, you just need to index table1 and table2 on author. Add those indices and the JOIN will be fast enough. You also have an issue that you call the column author in your sample data and name in your first query.