MySQL super query - mysql

I am trying to get information from table_a and auto apply to table_b while increasing pointsA by 5 pointsB by 8 and pointsC by 10
Basically looking for a single script that takes the IDs from table_a ONLY in category 1 while selecting UNIQUE numbers in PlayerAmmount (like for example if 2 (or more) ID's in Category 1 have a PlayerAmmount of 555 it only lists the first one (aka ID 5 in this example) then ignores the rest after it sorts that it gets the ID from those similar then gets other IDs from that same category but with different PlayerAmmounts.
After it does all that and have a list of a few IDs (for example 5, 77, 553, 23523, 53223) it then takes those ID's and places them in table_b with unique entry's incrimented by 1 (like normal counting) and puts those id's into its own entry (like 1 is ID 5 from table_a) and then it takes the base numbers 5 8 10 and adds itself.
So for example row 1:
entry = 1 ID = 5 pointsA = 5, pointsB = 8, and pointsC = 10
then row 2 MUST be adding itself like here:
entry = 2 ID = 77, pointsA = 10, pointsB = 16, pointsC = 20
then row 3 is this:
entry = 3, ID = 553, pointsA = 15, pointsB = 24, pointsC = 30
and so forth as all the IDs from table_a are input into table_b
So far my only attempts to anything in this is the following of different styles but this is all I can come up with. Anyone got a better working way that could work?
INSERT INTO table_b
(entry, ID, pointsA, pointsB, pointsC)
VALUES
((SELECT max(entry) FROM table_b C) + 1,
(SELECT max(ID) FROM table_a in(SELECT DISTINCT PlayerAmmount FROM table_a WHERE Category=1)),
(SELECT max(pointsA) FROM table_b C) + 5,
(SELECT max(pointsB) FROM table_b C) + 8,
(SELECT max(pointsC) FROM table_b C) + 10;
Images:
Table_A
Table_B
Setup

Related

SELECT where with multiple conditions in ONE query

There are two things I want to achieve.
This is my database table called "table".
id | friend
---|--------
1 | null
2 | 1
3 | 0
4 | 3
5 | 3
6 | null
There are two SELECT queries I want to do.
$id = 3;
SELECT * FROM table WHERE id = $id; // Not sql injection safe, just an example
This should select row id = 3. If that row's friend column = 0, then:
SELECT rows WHERE friend = $id.
If that row's friend column is something other than 0, then just return that row, row 3. But since my table above shows that row id 3's friend column = 0, this should altogether return rows: 3, 4, 5.
Also, another scenario a something a little different:
$id = 5;
SELECT * FROM table WHERE id = $id;
If that row's friend column <> (does NOT equal) 0 AND IS NOT NULL, then use the friend number and:
SELECT * WHERE id = friend from previous table.
In this example, it will return rows 3, 4, 5 because ID = 5 and the friend ID of 5 is 3. So we search columns id AND friend for 3 and we select it.
I want to combine all of those together into one MySQL SELECT query. How can I do that?
Any help will be appreciated!
In the first scenario, I don't understand exactly why a zero value for friend returns 3, 4, and 5. Why not 2? I'm assuming that if the friend value is zero, then add the rows which have you as a friend.
So, before this first example, I cannot stand a table named "table", so I will use friends as the name of the table.
SELECT FF.id
FROM friends FF
INNER JOIN friends FID on FF.friend = FID.id
WHERE FID.friend = 0 AND FID = $id
UNION
SELECT F2.id FROM friends F2 WHERE F2.id = $id AND F2.friend IS NOT NULL
The inner join, takes the id of friends (FID.id) and joins on the the friends table again to get all the records with that as a friend (FF.friend) value.
Then UNION will include the original id. Both sides of the UNION will return no results if the friend field is NULL.
Similarly for the second scenario, use the given value, ($id = 5), find that record's friend value, and query for all records with that as a friend, then union its record.
SELECT FF.id
FROM friends FF
WHERE FF.friend = (SELECT FIN.friend FROM friends FIN where FIN.id = $id)
UNION
SELECT FIN.friend FROM friends FIN where FIN.id = $id

How to chain a series of numbers together in a MySQL DB with two columns defining the series connections?

I have a MySQL DB that defines series of numbers within sets as such:
set item1 item2
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
I want to write a query (or queries) that returns to me the fact that set 1 is a series of numbers that spans from 1 to 6. Is this possible?
Please note that the real DB I'm dealing with contains hundreds of sets and that each set can contain a series of items that can be somewhat long as well (up to 50 items per set, I'm guessing). Also, I'm not totally sure, but the DB might also have cases where the series of numbers split. Using the example above, there may be instances like the following:
set item1 item2
1 1 2
1 2 3
1 3 4
1 4 5
1 5 6
1 3 7
1 7 8
1 8 9
In which case, I'd want to know that set 1 has two series of numbers: [1, 2, 3, 4, 5, 6] and [1, 2, 3, 7, 8, 9]. Is this possible with hopefully one query (or if necessary, multiple queries)?
Edit: Please note that I used the numbers 1-9 in sequential order to make the question easier to understand. The real data is much more mixed up and not that orderly.
As you are aware, MySQL cannot handle recursion 'out-of-the-box', so options include:
writing a stored procedure
switching from an adjacency list to an alternative model (e.g. nested set)
joining the table to itself as often as could be required
handling the recursion in application level code (e.g. a bit of PHP)
Here is an example using option 3, but it could be easily adapted to suit option 4...
DROP TABLE IF EXISTS my_table;
CREATE TABLE my_table
(
family_id INT NOT NULL,
item_id INT NOT NULL,
parent_id INT NULL,
PRIMARY KEY(family_id, item_id)
);
INSERT INTO my_table
VALUES (101, 1, null), (101, 2, 1), (101, 3, 2), (101, 4, 3),
(101, 5, 4), (101, 6, 5), (101, 7, 3), (101, 8, 7), (101, 9, 8);
SELECT CONCAT_WS(','
, a.item_id
, b.item_id
, c.item_id
, d.item_id
, e.item_id
, f.item_id
, g.item_id
, h.item_id
, i.item_id
) series
FROM
my_table a
LEFT JOIN
my_table b ON b.parent_id = a.item_id AND b.family_id = a.family_id
LEFT JOIN
my_table c ON c.parent_id = b.item_id AND c.family_id = b.family_id
LEFT JOIN
my_table d ON d.parent_id = c.item_id AND d.family_id = c.family_id
LEFT JOIN
my_table e ON e.parent_id = d.item_id AND e.family_id = d.family_id
LEFT JOIN
my_table f ON f.parent_id = e.item_id AND f.family_id = e.family_id
LEFT JOIN
my_table g ON g.parent_id = f.item_id AND g.family_id = f.family_id
LEFT JOIN
my_table h ON h.parent_id = g.item_id AND h.family_id = g.family_id
LEFT JOIN
my_table i ON i.parent_id = h.item_id AND i.family_id = h.family_id
WHERE
a.parent_id IS NULL;
+-------------+
| series |
+-------------+
| 1,2,3,4,5,6 |
| 1,2,3,7,8,9 |
+-------------+
I can solve the first problem.
Note that "set" is a keyword, so I renamed the first column to "sset"
You can see the result in http://sqlfiddle.com/#!9/ef6360/5
Create table and insert data:
create table test
(
sset int not null
, item1 int not null
, item2 int not null
) engine=InnoDB;
insert into test
values
(1, 1, 2)
, (1, 2, 3)
, (1, 3, 4)
, (1, 4, 5)
, (1, 5, 6)
Run the query:
select
sset
, group_concat(distinct item1or2 order by item1or2 asc)
from
(
select
sset
, item1 as item1or2
from test
union all
select
sset
, item2 as item1or2
from test
) u;
The output is:
1,2,3,4,5,6

MySQL query to find ids that do not exist in table

I have a list of ids pre-generated that I need to check if exist in a table. My table has two columns, id, name, where id is an auto increment integer and name is a varchar(255).
I basically want to get a count of how many ids do not exist in table foo from my pre-generated list. So say my list has the numbers 5 and 10 in it, what's the best way to write something to the extent of:
select count(*) from foo where id does not exist in ( 5, 10 )
The idea here is that if 5 and 10 do not exist, I need the response 2, and not the number of rows in foo that do not have the id 5 or 10.
TL; DR sample data and queries at rextester
The idea here is that if 5 and 10 do not exist, I need the response 2, and not the number of rows in foo that do not have the id 5 or 10.
You should have provided a little more information to avoid confusion.
Example
id | name
1 | tom
2 | joe
3 | mae
4 | goku
5 | vegeta
If your list contains (1, 2, 3) then your answer should be 0 (since all three are in the table )
If your list contains (1, 2, 6) then your answer should be 1. ( since 1 and 2 are in the table but 6 is in't )
If your list contains (1, 6, 7) then your answer should be 2.
If your list contains (6, 7, 8) then your answer should be 3.
assuming this was your question
If you know the length of your list
select 2 - count(*) as my_count from foo where id in (5, 10)
The following query tells you how many are present in foo.
select count(*) from foo where id in (5,10)
So if you want to find those that do not exist, subtract this result from the length of your list.
select n - count(*) as my_count from foo where id in (5, 10,....)
You could use on fly table using union and the a left join
select count(*)
from my_table as m
left join (
select 5 as id from dual
union
select 10 from dual ) t on t.id = m.id
where t.id is null
otherwise you can populate a tempo table with the value you need and use left join
where the value is null

MySQL query that find matches that are ecual [duplicate]

This question already has answers here:
How to return rows that have the same column values in MySql
(3 answers)
Closed 6 years ago.
I have the following MySQL table called "MyTable"
ID--- a --- b
10---20---42
11---20---43
12---20---44
13---21---44
14---20---45
14---22---44
14---22---43
14---24---45
14---22---42
I am trying to write a query that gets me into the following results.
Examples.
SELECT b FROM mytable WHERE a=(20, 21, 22)
This returns 44 as it is the only number that is common.
SELECT b FROM mytable WHERE a=(20, 22) AND b is the same
This returns 42 and also 43 because both match
SELECT b FROM mytable WHERE a=(22, 24) AND b is the same
This returns nothing because the b value is different between the numbers in column a.
Thanks for your help
(found an answer I guess)
select b
from MyTable
group by b
having sum(a = 20) > 0 and // -- has id = 20
sum(a = 21) > 0 // -- has id = 21
For queries like that where you want to narrow down by a set you can do it one of two ways, the long way:
SELECT b FROM mytable WHERE a=20 OR a=21 OR a=22
Or the short way, by using the IN keyword:
SELECT b FROM mytable WHERE a IN (20, 21, 22)
for your query 'SELECT b FROM mytable WHERE a=(20, 22) AND b is the same' you can still use the same idea, but do:
SELECT b FROM mytable WHERE a IN(20, 22) AND b=a

join with union of multiple tables in SQL

I have the following data structure:
a table entries with a column entry_id
a table data_int with columns entry_id, question and data
a table data_text with columns entry_id, question and data
a table questions with columns question_id
Now I would like to make a MySQL query that does the following: for a given entry_id (say 222) it should select all question_id q from that table for which there is no row with (entry_id=222 AND question_id=q) in data_int, and also no such row in data_text. Is this possible in a single query, and if so how should I do this?
A sample data set would be
entries:
1
2
data_int:
1, 1, 4
1, 2, 56
1, 6, 43
1, 7, -1
data_text:
1, 3, 'hello'
1, 5, 'world'
questions:
1
2
3
4
5
6
7
8
9
10
Then for entry_id=1, the return value should be 4, 8, 9, 10, since these don't appear in either data_ table for entry_id=1.
For entry_id=2, the return value should be 1,2,3,4,5,6,7,8,9,10 since nothing appears in any of the data_ tables.
There are a couple ways to do this. The more efficient way with mysql is probably using multiple outer join / null checks.
select q.*
from questions q
left join data_int di on q.questionid = di.questionid and di.entryid = 1
left join data_text dt on q.questionid = dt.questionid and dt.entryid = 1
where di.entryid is null and dt.entryid is null