Update records in a select query with different values - mysql

I have an INSERT INTO query that works great to create child records when a parent record is added. I basically need to run the same thing but instead of adding new child records, I need to update the column that contains a sum value.
As an example, I have the following data. Shift_Roster_ID is the PK for the first table. RosterID and ShiftID are both foreign keys. For ShiftID=1, I want to update the ShiftCount for each unique RosterID. The ShiftCount is the sum of the Response values for any shift for which the PeriodID in the second table matches the PeriodID of ShiftID=1.
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | 0 | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+
+---------+----------+
| ShiftID | PeriodID |
+---------+----------+
| 1 | 1 |
+---------+----------+
| 2 | 1 |
+---------+----------+
| 3 | 2 |
+---------+----------+
The result should be
+-----------------+----------+---------+------------+----------+
| Shift_Roster_ID | RosterID | ShiftID | ShiftCount | Response |
+-----------------+----------+---------+------------+----------+
| 1 | 1 | 1 | **2** | 1 |
+-----------------+----------+---------+------------+----------+
| 2 | 2 | 1 | **11** | 3 |
+-----------------+----------+---------+------------+----------+
| 3 | 3 | 1 | **15** | 8 |
+-----------------+----------+---------+------------+----------+
| 4 | 1 | 2 | 0 | 1 |
+-----------------+----------+---------+------------+----------+
| 5 | 2 | 2 | 0 | 8 |
+-----------------+----------+---------+------------+----------+
| 6 | 3 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 7 | 1 | 2 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 8 | 2 | 3 | 0 | 7 |
+-----------------+----------+---------+------------+----------+
| 9 | 3 | 3 | 0 | 6 |
+-----------------+----------+---------+------------+----------+

Related

MySQL get ID from a table based on email then create a row in another table using ID and more values

I have two tables users and features:
users
+----+-----------------+
| id | email |
+----+-----------------+
| 1 | test1#gmail.com |
| 2 | test2#gmail.com |
| 3 | test3#gmail.com |
| 4 | test4#gmail.com |
| 5 | test5#gmail.com |
+----+-----------------+
features
+------------+---------+---------------------+------------+
| feature_id | user_id | feature_name | can_access |
+------------+---------+---------------------+------------+
| 1 | 1 | automated-investing | 1 |
| 2 | 1 | crypto | 0 |
| 3 | 2 | crypto | 0 |
| 4 | 3 | automated-investing | 0 |
| 5 | 4 | automated-investing | 1 |
| 7 | 1 | financial-tracking | 1 |
| 8 | 2 | financial-tracking | 0 |
| 9 | 3 | financial-tracking | 1 |
| 10 | 4 | financial-tracking | 0 |
+------------+---------+---------------------+------------+
I am trying to get the id from users based on email and then create a new row in features using that id ,feature_name and can_access(feature_name and can_access are from a request).
I am able to do it but it is split into two parts and I am looking to do it with a single query.
Current query:
// Get ID from email
SELECT id FROM users WHERE email="test5#gmail.com";
// Insert values into features
INSERT INTO features(user_id, feature_name, can_access) VALUES(5,"crypto", 1);
Expected output:
+------------+---------+---------------------+------------+
| feature_id | user_id | feature_name | can_access |
+------------+---------+---------------------+------------+
| 1 | 1 | automated-investing | 1 |
| 2 | 1 | crypto | 0 |
| 3 | 2 | crypto | 0 |
| 4 | 3 | automated-investing | 0 |
| 5 | 4 | automated-investing | 1 |
| 7 | 1 | financial-tracking | 1 |
| 8 | 2 | financial-tracking | 0 |
| 9 | 3 | financial-tracking | 1 |
| 10 | 4 | financial-tracking | 0 |
| 11 | 5 | crypto | 1 |
+------------+---------+---------------------+------------+
INSERT INTO features (user_id, feature_name, can_access)
SELECT id, "crypto", 1 FROM users WHERE email="test5#gmail.com";
So instead of specifying the values, you use the select statement.

count repeated row values without breaks

I want to count repeated values in rows one by one without breaks. If it breaks with NULL value, then count it again from zero.
It is a simple table consists from action_id and event_code.
| id | action_id | event_code |
--------------------------------
| 1 | 1 | 100 |
| 2 | 1 | 200 |
| 3 | 1 | 300 |
| 4 | 2 | 100 |
| 5 | 2 | 300 |
| 6 | 3 | 100 |
| 7 | 3 | 200 |
| 8 | 3 | 400 |
Then it groups by action_id (with SQL query) to:
| action_id | c100 | c200 | c300 | c400 |
-----------------------------------------
| 1 | 1 | 1 | 1 | 0 |
| 2 | 1 | 0 | 1 | 0 |
| 3 | 1 | 1 | 0 | 1 |
and as a result:
| action_id | c100 | e100_r | c200 | e200_r | c300 | e300_r | c400 | e400_r |
-----------------------------------------------------------------------------
| 1 | 1 | 3 | 1 | 1 | 1 | 2 | 0 | 0 |
| 2 | 1 | 3 | 0 | 0 | 1 | 2 | 0 | 0 |
| 3 | 1 | 3 | 1 | 1 | 0 | 0 | 1 | 1 |
or
| id | action_id | event_code | rep_count |
--------------------------------------------
| 1 | 1 | 100 | 3 |
| 2 | 1 | 200 | 1 |
| 3 | 1 | 300 | 2 |
| 4 | 2 | 100 | 3 |
| 5 | 2 | 300 | 2 |
| 6 | 3 | 100 | 3 |
| 7 | 3 | 200 | 1 |
| 8 | 3 | 400 | 1 |
Is it possible?
EDIT 1:
c100 - couunter of event_code == 100 and e100_r - repeats of event_code == 100
EDIT 2:
Rows breaks by zero (0)

How to select multiple values for one table "cell" MySQL

For all players, I need to find the player number and a list of the numbers of teams for which they have ever played.
Here is the table "MATCHES":
+---------+--------+----------+-----+------+
| MATCHNO | TEAMNO | PLAYERNO | WON | LOST |
+---------+--------+----------+-----+------+
| 1 | 1 | 6 | 3 | 1 |
| 2 | 1 | 6 | 2 | 3 |
| 3 | 1 | 6 | 3 | 0 |
| 4 | 1 | 44 | 3 | 2 |
| 5 | 1 | 83 | 0 | 3 |
| 6 | 1 | 2 | 1 | 3 |
| 7 | 1 | 57 | 3 | 0 |
| 8 | 1 | 8 | 0 | 3 |
| 9 | 2 | 27 | 3 | 2 |
| 10 | 2 | 104 | 3 | 2 |
| 11 | 2 | 112 | 2 | 3 |
| 12 | 2 | 112 | 1 | 3 |
| 13 | 2 | 8 | 0 | 3 |
+---------+--------+----------+-----+------+
The best I could come up with was:
SELECT DISTINCT playerno, teamno
FROM matches
ORDER BY playerno;
which results in:
+----------+--------+
| playerno | teamno |
+----------+--------+
| 2 | 1 |
| 6 | 1 |
| 8 | 1 |
| 8 | 2 |
| 27 | 2 |
| 44 | 1 |
| 57 | 1 |
| 83 | 1 |
| 104 | 2 |
| 112 | 2 |
+----------+--------+
Notice how player 8 has played on two teams. How can I get the table to show only one row for player 8 and a list of teamno's (1 & 2)?
You could use the group_concat aggregate function:
SELECT playerno, GROUP_CONCAT(DISTINCT teamno)
FROM matches
GROUP BY playerno
ORDER BY playerno;
You could use group_concat
SELECT playerno, group_concat( teamno)
FROM matches
GROUP BY playerno;

Creating a log having the date of purchase

I need to create a log having the purchase date of an item.
Items can be owned by only one buyer at time. So, for example, if item1 was purchased by buyer2 in 2009 and after by buyer1 in 2015, then between 2009 and 2015 was owned by buyer2.
Here is my table:
+--------+------------+-----------+----------+
| id_doc | date | id_item | id_buyer |
+--------+------------+-----------+----------+
| 11 | 2016-06-07 | 1 | 4 |
| 10 | 2016-06-06 | 1 | 4 |
| 1 | 2015-11-30 | 1 | 1 |
| 9 | 2009-01-01 | 1 | 2 |
| 4 | 2001-01-12 | 1 | 2 |
| 8 | 1996-06-06 | 1 | 2 |
| 3 | 1995-05-29 | 1 | 1 |
| 2 | 1998-05-23 | 2 | 2 |
| 7 | 2014-10-10 | 3 | 2 |
| 6 | 2003-12-12 | 3 | 3 |
| 5 | 1991-01-12 | 3 | 2 |
+--------+------------+-----------+----------+
Here is a kind of table/view I need:
+------------+------------+-----------+----------+--------+
| date_from | date_to | id_item | id_buyer | id_doc |
+------------+------------+-----------+----------+--------+
| 2016-06-07 | - | 1 | 4 | 11 |
| 2016-06-06 | 2016-06-07 | 1 | 4 | 10 |
| 2015-11-30 | 2016-06-06 | 1 | 1 | 1 |
| 2009-01-01 | 2015-11-30 | 1 | 2 | 9 |
| 2001-01-12 | 2009-01-01 | 1 | 2 | 4 |
| 1996-06-06 | 2001-01-12 | 1 | 2 | 8 |
| 1995-05-29 | 1996-06-06 | 1 | 1 | 3 |
| 1998-05-23 | - | 2 | 2 | 2 |
| 2014-10-10 | - | 3 | 2 | 7 |
| 2003-12-12 | 2014-10-10 | 3 | 3 | 6 |
| 1991-01-12 | 2003-12-12 | 3 | 2 | 5 |
+------------+------------+-----------+----------+--------+
I've tried a lot with GROUP BY, GROUP_CONCAT, trying to access next record date, etc ... but I can't found out how to solve the problem.
Thanks in advance.
I finally found out the solution only for past purchases.
SELECT
main.id_doc, main.id_item, main.date AS "date_from", bi.date AS "date_to", main.id_buyer
FROM
MyTable main, MyTable bi
WHERE
bi.id_doc =
(
SELECT sub.id_doc
FROM MyTable sub
WHERE sub.id_item = main.id_item AND sub.date > main.date ORDER BY sub.date ASC LIMIT 1
);

how to get duplicate column values in comma separated [duplicate]

This question already has answers here:
Can I concatenate multiple MySQL rows into one field?
(16 answers)
Closed 8 years ago.
I have a table like this
+----+------------+------------+---------+-----+------+------+
| id | is_deleted | sort_order | version | cid | pid | qid |
+----+------------+------------+---------+-----+------+------+
| 1 | | 1 | 0 | 1 | 1 | 1 |
| 2 | | 2 | 0 | 1 | 1 | 2 |
| 3 | | 3 | 0 | 1 | 1 | 3 |
| 4 | | 1 | 0 | 1 | 2 | 7 |
| 5 | | 2 | 0 | 1 | 2 | 1 |
| 6 | ☺ | 1 | 1 | 1 | 6 | 14 |
| 7 | ☺ | 1 | 1 | 1 | 5 | 13 |
| 8 | | 1 | 0 | 1 | 4 | 12 |
| 9 | | 3 | 0 | 1 | 2 | 2 |
| 10 | | 4 | 0 | 1 | 1 | 4 |
| 11 | | 5 | 0 | 1 | 1 | 5 |
+----+------------+------------+---------+-----+------+------+
as you can see pid is repeated.
Is it possible to get like below format
pid qid
1 1,2,3,4,5
2 7,1,2
6 14
5 13
4 12
I tried like this but the output I got is
SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question
------+--------------------------+
pid | GROUP_CONCAT(qid) |
------+--------------------------+
1 | 1,2,3,7,1,14,13,12,2,4,5 |
------+--------------------------+
Use GROUP BY
SELECT pid, GROUP_CONCAT(qid)
FROM client_parent_question
GROUP BY pid
You are missing group by
SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question group by pid
SELECT pid,GROUP_CONCAT(qid) FROM client_parent_question
Group by PID
would do the trick. Output would be as:
pid | qid
1 | 1,2,3,4,5
2 | 7,1,2
6 | 14
5 | 13
4 | 12