SQL - randomizing existing values with a specific list of values - mysql

I have 3 tables involved in this issue :
[person_attribute_type]
+--------------------------+-------------+
| person_attribute_type_id | foreign_key |
+--------------------------+-------------+
| 16 | 694 |
| 25 | 178 |
| 27 | 177 |
| 28 | 163 |
+--------------------------+-------------+
[concept_answer]
+------------+----------------+
| concept_id | answer_concept |
+------------+----------------+
| 163 | 342 |
| 163 | 343 |
| 163 | 251 |
| 163 | 253 |
| 163 | 320 |
| 163 | 322 |
| 163 | 408 |
| 177 | 408 |
| 177 | 254 |
| 177 | 255 |
| 177 | 256 |
| 177 | 344 |
| 177 | 257 |
| 178 | 229 |
| 178 | 345 |
| 178 | 346 |
| 178 | 347 |
| 178 | 348 |
| 694 | 692 |
| 694 | 685 |
| 694 | 689 |
| 694 | 690 |
| 694 | 687 |
| 694 | 684 |
| 694 | 693 |
| 694 | 686 |
| 694 | 688 |
| 694 | 691 |
+------------+----------------+
(concept_id: it's the same value contained in person_attribute_type.foreign_key)
[person_attribute]
+--------------------------+-------+
| person_attribute_type_id | value |
+--------------------------+-------+
| 16 | 688 |
| 25 | 348 |
| 27 | 256 |
| 28 | 251 |
| 16 | 687 |
| 25 | 348 |
| 27 | 408 |
| 28 | 342 |
| 16 | 684 |
| 25 | 345 |
| 27 | 408 |
| 28 | 343 |
| 16 | 687 |
| 25 | 347 |
| 27 | 344 |
| 28 | 342 |
| 16 | 684 |
| 25 | 346 |
| 27 | 254 |
| 28 | 320 |
| 16 | 693 |
| 25 | 347 |
| 27 | 344 |
| 28 | 342 |
| 16 | 687 |
| 25 | 345 |
| 27 | 254 |
| 28 | 251 |
| 16 | 690 |
| 25 | 347 |
| 27 | 408 |
| 28 | 251 |
| 16 | 687 |
| 25 | 229 |
| 27 | 257 |
| 28 | 342 |
| 16 | 689 |
| 25 | 348 |
| 27 | 408 |
| 28 | 322 |
| 16 | 688 |
| 25 | 347 |
| 27 | 256 |
| 28 | 342 |
| 16 | 684 |
| 25 | 345 |
| 27 | 344 |
| 28 | 343 |
| 16 | 689 |
| 25 | 348 |
(value: it's the same value contained in concept_answer.answer_concept)
--
I want to randomize person_attribute.value with concept_answer.answer_concept and its person_attribute_type_id, within its acceptable list of answers.
I hope it's understandable..
So this is what I did:
-- Getting the variables for each line of person_attribute_type_id & foreign key
SELECT person_attribute_type_id, foreign_key INTO #pati1, #fk1 FROM person_attribute_type LIMIT 0,1;
SELECT person_attribute_type_id, foreign_key INTO #pati2, #fk2 FROM person_attribute_type LIMIT 1,1;
SELECT person_attribute_type_id, foreign_key INTO #pati3, #fk3 FROM person_attribute_type LIMIT 2,1;
SELECT person_attribute_type_id, foreign_key INTO #pati4, #fk4 FROM person_attribute_typeLIMIT 3,1;
-- Getting manually all the answers linked to the foreign_key
SET #answers1:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 0,1);
SET #answers2:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 1,1);
SET #answers3:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 2,1);
SET #answers4:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 3,1);
SET #answers5:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 4,1);
SET #answers6:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 5,1);
SET #answers7:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 6,1);
SET #answers8:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 7,1);
SET #answers9:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 8,1);
SET #answers10:=(select answer_concept FROM concept_answer WHERE concept_id = #fk1 LIMIT 9,1);
SET #2answers1:=(select answer_concept FROM concept_answer WHERE concept_id = #fk2 LIMIT 0,1);
SET #2answers2:=(select answer_concept FROM concept_answer WHERE concept_id = #fk2 LIMIT 1,1);
SET #2answers3:=(select answer_concept FROM concept_answer WHERE concept_id = #fk2 LIMIT 2,1);
SET #2answers4:=(select answer_concept FROM concept_answer WHERE concept_id = #fk2 LIMIT 3,1);
SET #2answers5:=(select answer_concept FROM concept_answer WHERE concept_id = #fk2 LIMIT 4,1);
SET #3answers1:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 0,1);
SET #3answers2:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 1,1);
SET #3answers3:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 2,1);
SET #3answers4:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 3,1);
SET #3answers5:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 4,1);
SET #3answers6:=(select answer_concept FROM concept_answer WHERE concept_id = #fk3 LIMIT 5,1);
SET #4answers1:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 0,1);
SET #4answers2:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 1,1);
SET #4answers3:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 2,1);
SET #4answers4:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 3,1);
SET #4answers5:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 4,1);
SET #4answers6:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 5,1);
SET #4answers7:=(select answer_concept FROM concept_answer WHERE concept_id = #fk4 LIMIT 6,1);
-- Randomize and update the values for person_attribute.value according to the "possible list of answers" for each concept_id
UPDATE person_attribute SET value = ELT(FLOOR(1 + RAND() * 10), #answers1, #answers2, #answers3, #answers4, #answers5, #answers6, #answers7, #answers8, #answers9, #answers10) WHERE person_attribute_type_id = #pati1;
UPDATE person_attribute SET value = ELT(FLOOR(1 + RAND() * 5), #2answers1, #2answers2, #2answers3, #2answers4, #2answers5) WHERE person_attribute_type_id = #pati2;
UPDATE person_attribute SET value = ELT(FLOOR(1 + RAND() * 6), #3answers1, #3answers2, #3answers3, #3answers4, #3answers5, #3answers6) WHERE person_attribute_type_id = #pati3;
UPDATE person_attribute SET value = ELT(FLOOR(1 + RAND() * 7), #4answers1, #4answers2, #4answers3, #4answers4, #4answers5, #4answers6, #4answers7) WHERE person_attribute_type_id = #pati4;
The question is: I'm sure there's an easier non manual and shorter way to reach the same result. Does anybody know ?
Thanks a lot

The easiest way to achieve what you want in MySQL is to SELECT rand_val FROM tbl WHERE conditions ORDER BY RAND() LIMIT 1. This gives you a single random value based on a given set of values. From there you can build more complex queries as needed.
Applied to your example it would be something like
UPDATE person_attribute t
SET value =
(SELECT answer_concept
FROM person_attribute_type t2
LEFT JOIN concept_answer t3
ON t2.foreign_key=t3.concept_id
WHERE t2.person_attribute_type_id = t.person_attribute_type_id
ORDER BY RAND() LIMIT 1);
which should replace your entire SQL script and update all the rows in one go.

Related

Percentage Query in MySQL

I have 2 tables as shown below :
Tabel_1
|idUnit | Budget |
|112 | 1000 |
|112 | 2000 |
|113 | 4000 |
Tabel_2
|idUnit | Real2 |
|112 | 500 |
|112 | 100 |
|113 | 200 |
My Question, how to make the table as below with percentage:
| idUnit | TotalBudget | TotalReal2 | Percentage
| 112 | 3000 | 600 | ? (15%) |
| 113 | 4000 | 200 | ? (5%) |
My query before :
SELECT t1.idUnit, SUM(Budget) AS TotalBudget, t2.TotalReal2
FROM Tabel_1 AS t1
JOIN (SELECT idUnit, SUM(Real2) AS TotalReal2
FROM Tabel_2 GROUP BY idUnit
) AS t2 ON t1.idUnit = t2.idUnit
GROUP BY t1.idUnit;
You can try to use two subqueries then do JOIN, calculating your column by TotalBudget and totalbudget
Query 1:
SELECT t1.idUnit,
t1.TotalBudget,
t2.TotalReal2,
CONCAT((TotalReal2/totalbudget)*100,'%') Percentage
FROM (
SELECT idUnit,SUM(Budget) TotalBudget
FROM Tabel_1
GROUP BY idUnit
) AS t1
INNER JOIN (
SELECT idUnit,
SUM(Real2) AS TotalReal2
FROM Tabel_2
GROUP BY idUnit
) AS t2 ON t1.idUnit = t2.idUnit
Results:
| idUnit | TotalBudget | TotalReal2 | Percentage |
|--------|-------------|------------|------------|
| 112 | 3000 | 600 | 20.0000% |
| 113 | 4000 | 200 | 5.0000% |

How can I get the last row from each given row value in a column through date? [duplicate]

This question already has answers here:
Retrieving the last record in each group - MySQL
(33 answers)
Closed 4 years ago.
I have the following table.
+--------------------+--------------+-------+
Date | SymbolNumber | Value
+--------------------+--------------+-------+
2018-08-31 15:00:00 | 123 | data
2018-09-31 15:00:00 | 456 | data
2018-09-31 15:00:00 | 123 | data
2018-09-31 15:00:00 | 555 | data
2018-10-31 15:00:00 | 555 | data
2018-10-31 15:00:00 | 231 | data
2018-10-31 15:00:00 | 123 | data
2018-11-31 15:00:00 | 123 | data
2018-11-31 15:00:00 | 555 | data
2018-12-31 15:00:00 | 123 | data
2018-12-31 15:00:00 | 555 | data
I need a query that can select the last row of each SymbolNumber stated in the query.
SELECT
*
FROM
MyTable
WHERE
symbolNumber IN (123, 555)
AND
**lastOfRow ordered by latest-date**
Expected results:
2018-12-31 15:00:00 | 123 | data
2018-12-31 15:00:00 | 555 | data
How can I do this?
First, you will need a query that get the latest date for each symbolNumber. Second, you can inner join to this table (using date) for get the rest of the columns. Like this:
SELECT
t.*
FROM
<table_name> AS t
INNER JOIN
(SELECT
symbolNumber,
MAX(date) AS maxDate
FROM
<table_name>
GROUP BY
symbolNumber) AS latest_date ON latest_date.symbolNumber = t.symbolNumber AND latest_date.maxDate = t.date
The previous query will get latest data for each existing symbolNumber on the table. If you want to restrict to symbolNumbers: 123 and 555, you will need to made next modification:
SELECT
t.*
FROM
<table_name> AS t
INNER JOIN
(SELECT
symbolNumber,
MAX(date) AS maxDate
FROM
<table_name>
WHERE
symbolNumber IN (123, 555)
GROUP BY
symbolNumber) AS latest_date ON latest_date.symbolNumber = t.symbolNumber AND latest_date.maxDate = t.date
We can do a "self-left-join" on symbolNumber, and match to other rows in the same group with higher Date value on the right side.
We will eventually consider only those rows, where higher date could not be found (meaning the current row belongs to highest date in the group).
Here is a solution avoiding subquery, and utilizing Left Join:
SELECT t1.*
FROM MyTable AS t1
LEFT JOIN MyTable AS t2
ON t2.symbolNumber = t1.symbolNumber AND
t2.Date > t1.Date -- Joining to a row in same group with higher date
WHERE t1.symbolNumber IN (123, 555) AND
t2.symbolNumber IS NULL -- Higher date not found; so this is highest row
EDIT:
Benchmarking studies comparing Left Join method v/s Derived Table (Subquery)
#Strawberry ran a little benchmark test in 5.6.21. Here's what he found...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(id SERIAL PRIMARY KEY
,dense_user INT NOT NULL
,sparse_user INT NOT NULL
);
INSERT INTO my_table (dense_user,sparse_user)
SELECT RAND()*100,RAND()*100000;
INSERT INTO my_table (dense_user,sparse_user)
SELECT RAND()*100,RAND()*100000 FROM my_table;
-- REPEAT THIS LINE A FEW TIMES !!!
SELECT COUNT(DISTINCT dense_user) dense
, COUNT(DISTINCT sparse_user) sparse
, COUNT(*) total
FROM my_table;
+-------+--------+---------+
| dense | sparse | total |
+-------+--------+---------+
| 101 | 99999 | 1048576 |
+-------+--------+---------+
ALTER TABLE my_table ADD INDEX(dense_user);
ALTER TABLE my_table ADD INDEX(sparse_user);
--dense_test
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.dense_user = x.dense_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY dense_user
LIMIT 10;
+------+------------+-------------+
| id | dense_user | sparse_user |
+------+------------+-------------+
| 1212 | 0 | 1950 |
| 153 | 1 | 23193 |
| 255 | 2 | 27472 |
| 28 | 3 | 86440 |
| 18 | 4 | 47886 |
| 291 | 5 | 76563 |
| 15 | 6 | 85049 |
| 16 | 7 | 78384 |
| 135 | 8 | 52304 |
| 62 | 9 | 40930 |
+------+------------+-------------+
10 rows in set (2.64 sec)
SELECT x.*
FROM my_table x
JOIN
( SELECT dense_user, MIN(id) id FROM my_table GROUP BY dense_user ) y
ON y.dense_user = x.dense_user
AND y.id = x.id
ORDER
BY dense_user
LIMIT 10;
+------+------------+-------------+
| id | dense_user | sparse_user |
+------+------------+-------------+
| 1212 | 0 | 1950 |
| 153 | 1 | 23193 |
| 255 | 2 | 27472 |
| 28 | 3 | 86440 |
| 18 | 4 | 47886 |
| 291 | 5 | 76563 |
| 15 | 6 | 85049 |
| 16 | 7 | 78384 |
| 135 | 8 | 52304 |
| 62 | 9 | 40930 |
+------+------------+-------------+
10 rows in set (0.05 sec)
Uncorrelated query is 50 times faster.
--sparse test
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.sparse_user = x.sparse_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY sparse_user
LIMIT 10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 165055 | 75 | 0 |
| 37598 | 63 | 1 |
| 170596 | 70 | 2 |
| 46142 | 87 | 3 |
| 33546 | 21 | 4 |
| 323114 | 87 | 5 |
| 86592 | 96 | 6 |
| 156711 | 36 | 7 |
| 17148 | 62 | 8 |
| 139965 | 71 | 9 |
+--------+------------+-------------+
10 rows in set (0.03 sec)
SELECT x.*
FROM my_table x
JOIN ( SELECT sparse_user, MIN(id) id FROM my_table GROUP BY sparse_user ) y
ON y.sparse_user = x.sparse_user
AND y.id = x.id
ORDER
BY sparse_user
LIMIT 10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 165055 | 75 | 0 |
| 37598 | 63 | 1 |
| 170596 | 70 | 2 |
| 46142 | 87 | 3 |
| 33546 | 21 | 4 |
| 323114 | 87 | 5 |
| 86592 | 96 | 6 |
| 156711 | 36 | 7 |
| 17148 | 62 | 8 |
| 139965 | 71 | 9 |
+--------+------------+-------------+
10 rows in set (4.73 sec)
Exclusion Join is 150 times faster
However, as you move further up the result set, the picture begins to change very dramatically...
SELECT x.*
FROM my_table x
JOIN ( SELECT sparse_user, MIN(id) id FROM my_table GROUP BY sparse_user ) y
ON y.sparse_user = x.sparse_user
AND y.id = x.id
ORDER
BY sparse_user
LIMIT 10000,10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 9810 | 93 | 10000 |
| 162438 | 4 | 10001 |
| 467371 | 62 | 10002 |
| 8258 | 13 | 10003 |
| 297049 | 17 | 10004 |
| 68354 | 23 | 10005 |
| 192701 | 64 | 10006 |
| 176225 | 92 | 10007 |
| 156595 | 37 | 10008 |
| 318266 | 1 | 10009 |
+--------+------------+-------------+
10 rows in set (9.17 sec)
SELECT x.*
FROM my_table x
LEFT
JOIN my_table y
ON y.sparse_user = x.sparse_user
AND y.id < x.id
WHERE y.id IS NULL
ORDER
BY sparse_user
LIMIT 10000,10;
+--------+------------+-------------+
| id | dense_user | sparse_user |
+--------+------------+-------------+
| 9810 | 93 | 10000 |
| 162438 | 4 | 10001 |
| 467371 | 62 | 10002 |
| 8258 | 13 | 10003 |
| 297049 | 17 | 10004 |
| 68354 | 23 | 10005 |
| 192701 | 64 | 10006 |
| 176225 | 92 | 10007 |
| 156595 | 37 | 10008 |
| 318266 | 1 | 10009 |
+--------+------------+-------------+
10 rows in set (32.19 sec) -- !!!
In summary, the exclusion join (the so-called 'strawberry query' can be (significantly) faster in certain, limited situations. More generally, an uncorrelated query will be faster.

UPDATE table values (SET min value) on the columns with the same id

id | price
100 | 12.5
101 | 15.8
100 | 20.8
99 | 45.2
101 | 11.7
79 | 10.4
100 | 14.7
101 | 18.8
I am searching a solution for this problem.
I want a result like this using MySQL UPDATE command ...
id | price
100 | 12.5
101 | 11.7
100 | 12.5
99 | 45.2
101 | 11.7
79 | 10.4
100 | 12.5
101 | 11.7
Any solutions please ?
Try an update join to a subquery which finds the minimum price for each id group:
UPDATE yourTable t1
INNER JOIN
(
SELECT id, MIN(price) AS min_price
FROM yourTable
GROUP BY id
) t2
ON t1.id = t2.id
SET t1.price = t2.min_price;
Try Simple subquery which will update the values of table
update myTable t1,
(select * from (select * from myTable order by price) x group by id) t2
set t1.price = t2.price where t1.id = t2.id;
Before execution of query, data is like:
+------+-------+
| id | price |
+------+-------+
| 100 | 12.5 |
| 101 | 15.8 |
| 100 | 20.8 |
| 90 | 45.2 |
| 101 | 11.7 |
| 79 | 10.4 |
| 100 | 14.7 |
| 101 | 18.8 |
+------+-------+
After execution:
+------+-------+
| id | price |
+------+-------+
| 100 | 12.5 |
| 101 | 11.7 |
| 100 | 12.5 |
| 90 | 45.2 |
| 101 | 11.7 |
| 79 | 10.4 |
| 100 | 12.5 |
| 101 | 11.7 |
+------+-------+
UPDATE t
SET t.Price= o.MinPrice
FROM yourTable t
INNER JOIN (select id , min(price) MinPrice from yourTable group by id ) o ON o.id= t.id

Calculate difference between one column over multiple rows using coalesce and join

I have following table
+-----+--------+-----------+-----------+-------+
| id | job_id | source_id | target_id | value |
+-----+--------+-----------+-----------+-------+
| 204 | 5283 | 247 | 228 | 1201 |
| 349 | 4006 | 247 | 228 | 100 |
| 350 | 4007 | 247 | 228 | 500 |
| 351 | 4008 | 247 | 228 | 1000 |
| 352 | 4009 | 1 | 100 | 100 |
| 353 | 4010 | 1 | 100 | 500 |
| 354 | 4011 | 1 | 100 | 50 |
+-----+--------+-----------+-----------+-------+
I want to create a diff between the column value groupped by source_id and target_id. The older one (smaller id) should be compared with the newer one
I have searched a little bit and found coalesce. I have written a small query and it works in "general", but not as expexted:
SELECT
c.id, c.source_id, c.target_id, c.value, COALESCE(c1.value - c.value, -1) AS diff
FROM
changes c LEFT JOIN changes c1 ON (c1.source_id = c.source_id AND c1.target_id = c.target_id)
GROUP BY c.source_id, c.target_id, c.job_id
ORDER BY c.id
I got following result:
+-----+-----------+-----------+-------+------+
| id | source_id | target_id | value | diff |
+-----+-----------+-----------+-------+------+
| 204 | 247 | 228 | 1201 | 0 |
| 349 | 247 | 228 | 100 | 1101 |
| 350 | 247 | 228 | 500 | 701 |
| 351 | 247 | 228 | 1000 | 201 |
| 352 | 1 | 100 | 100 | 0 |
| 353 | 1 | 100 | 500 | -400 |
| 354 | 1 | 100 | 50 | 50 |
+-----+-----------+-----------+-------+------+
You can see the diff work for id 349 and 353, I want this for all rows like the following expected result:
+-----+-----------+-----------+-------+------+
| id | source_id | target_id | value | diff |
+-----+-----------+-----------+-------+------+
| 204 | 247 | 228 | 1201 | 1201 |
| 349 | 247 | 228 | 100 | 1101 |
| 350 | 247 | 228 | 500 | -400 |
| 351 | 247 | 228 | 1000 | -500 |
| 352 | 1 | 100 | 100 | 100 |
| 353 | 1 | 100 | 500 | -400 |
| 354 | 1 | 100 | 50 | 450 |
+-----+-----------+-----------+-------+------+
It would be no problem if the diff result is inverted.
What did I miss?
Thanks for any hints.
if you use user defined variables you don't need to join the table to itself. just do a row by row comparrision like so
SELECT
id,
job_id,
target_id,
if(#a = source_id, #b - value, value) as diff,
#b := value as value,
#a := source_id as source_id
FROM changes
CROSS JOIN (SELECT #a:=0, #b:=0)t
DEMO
I suspect that you're looking for something like this - although the COALESCE bit seems misleading to me...
SELECT a.*, COALESCE(b.value-a.value,a.value) diff
FROM
( SELECT x.* , COUNT(*) rank FROM changes x JOIN changes y ON y.id <= x.id GROUP BY x.id ) a
LEFT
JOIN
( SELECT x.* , COUNT(*) rank FROM changes x JOIN changes y ON y.id <= x.id GROUP BY x.id ) b
ON b.source_id = a.source_id
AND b.rank = a.rank - 1;
I think you want:
SELECT c.id,
c.source_id,
c.target_id,
c.value,
c.value - COALESCE(co.value, 0) delta
FROM changes c
LEFT JOIN (
SELECT ci.id, MAX(cio.id) prev_id
FROM changes ci
JOIN changes cio
ON cio.source_id = ci.source_id
AND cio.target_id = ci.target_id
AND cio.id < ci.id
GROUP BY ci.id
) link
ON link.id = c.id
LEFT JOIN changes co
ON co.id = link.prev_id
ORDER BY c.id
I have changed the logic slightly.
In your expected results, the first diff has gone from unknown (0?) to 1201 and is reported as a positive diff, but the second has gone from 1201 to 100 and is still reported as positive.
I have changed the name to delta, and given you the number required to move from the previous value to the new value. Obviously you can change this if you want to:
COALESCE(co.value-c.value, c.value) diff
which will get you the results you provided (with the diff 500 changed to -500, which I believe was a typo).

Add columns of two rows based on a condition in mysql

I have the following table structure:
+------+-------+-------+--------+
| mid | a | b | points |
+------+-------+-------+--------+
| 69 | 3137 | 13316 | 210 |
| 70 | 13316 | 3137 | 350 |
| 71 | 3497 | 13316 | 200 |
| 72 | 13316 | 3497 | 25 |
| 73 | 3605 | 13316 | 205 |
| 74 | 13316 | 3605 | 290 |
+------+-------+-------+--------+
I want to add the "points" values of two rows when "a" of row 1 = "b" of row 2 and "a" of row 2 = "b" of row 1.
The output needs to be something like this:
+------+-------+-------+--------+
| mid | a | b | points |
+------+-------+-------+--------+
| 69 | 3137 | 13316 | 560 |
| 71 | 3497 | 13316 | 225 |
| 73 | 3605 | 13316 | 495 |
+------+-------+-------+--------+
You can try it this way
SELECT t1.mid, t1.a, t1.b, t1.points + t2.points points
FROM table1 t1 JOIN table1 t2
ON t1.a = t2.b
AND t1.b = t2.a
AND t1.mid < t2.mid
or leveraging MySQL non-standard GROUP BY extension
SELECT mid, a, b, SUM(points) points
FROM
(
SELECT mid, a, b, points
FROM table1
ORDER BY mid
) q
GROUP BY LEAST(a, b), GREATEST(a, b)
Output:
| MID | A | B | POINTS |
|-----|------|-------|--------|
| 69 | 3137 | 13316 | 560 |
| 71 | 3497 | 13316 | 225 |
| 73 | 3605 | 13316 | 495 |
Here is SQLFiddle demo
If I've understood correctly then you want:
SELECT p1.mid, p1.a, p1.b, p1.points + p2.points points
FROM points p1
INNER JOIN points p2 ON p1.a = p2.b AND p1.b = p2.a
WHERE p1.mid < p2.mid
I have knocked it up in sql fiddle and gives the output that you want.