Combine database queries - mysql

I have a MySQL table that looks like this:
ID / x_id / x_key / x_value
322 / 4 / name / Jack
323 / 5 / name / Mary
324 / 6 / name / John
325 / 4 / hide / 1
326 / 5 / hide / 0
327 / 6 / hide / 0
I would like to select the names from the persons which "hide" key corresponds to the "0" value.
Here these selected "x_values" would then be Mary and John
To do so, I have the x_id that I can compare between records.
Which x_id's correspond to an x_ key="hide" that matches an x_value = "0"?
Both x_id's 5 and 6.
Which "x_values" are corresponding to these two x_id's where the x_key="name"? Mary and John
In other words, I try to get a single query that would mix these two queries in order to get Mary and John only:
Query A:
SELECT
x_id,
x_value
FROM
mytable
WHERE
x_key='name'
Query B:
SELECT
x_id
FROM
mytable
WHERE
x_key='hide'
AND
x_value='0'
I just don't find the correct way to do that.
How can I?
I'm really sorry for the explanation but I'm not english and it is very hard to explain.

If i have understood you correct you want to select the elements that have a specific x_key with x_value = '0' and that are not hidden (x_key != 'hide').
EDIT (according to your edit):
SQL Fiddle
SELECT bb.x_value
FROM mytable AS aa
INNER JOIN mytable AS bb
ON aa.x_id = bb.x_id
WHERE aa.x_key = 'hide' AND aa.x_value = 0 AND bb.x_key = 'name';
OLD ANSWER (before your edit):
SELECT x_id, x_key, x_value
FROM mytable
WHERE x_key='name' AND x_key != 'hide' AND x_value = '0'

You should use join to connect two instances of the table - one for the names and one for the 'hides'
select n.x_id, n.x_value from mytable as h inner join myable as n on
h.x_id = n.x_id where n.x_key = 'name' and h.x_key = 'hide' and H.x_value = 0;
while this will work, I think it's not a good practice to have two types of data in the same table. I'd recommend you to split it to two tables- one for names and one for hides

If I understand you correct you want combine 2 'SELECT' with different 'WHERE' statments. You can use 'OR' statment
SELECT x_id,x_value FROM mytable WHERE x_key='name' OR x_key='hide' AND x_value='0'

Related

SQL query statement Self Join?

new to SQL.
I have the following set of data
A X Y Z
1 Wind 1 1
2 Wind 2 1
3 Hail 1 1
4 Flood 1 1
4 Rain 1 1
4 Fire 1 1
I would like to select all distinct 'A' fields where for all rows that contain A have flood and rain.
So in this example, the query would return only the number 4 since for the set of all rows that contain A = 4 we have Flood and Rain.
I need the values of A where for a given value 'a' in A, there exists rows with 'a' that must contain all of the following fields provided (in the example Flood and Rain).
Please let me know if you need further clarification.
I need the values of A where for a given value 'a' in A, there exists rows with 'a' that must contain all of the following fields provided (in the example Flood and Rain).
You can use aggregation, and filter with a having clause:
select a
from mytable t
where x in ('Flood', 'Rain') -- either one or the other
having count(*) = 2 -- both match
If tuples (a, x) tuples are not unique, then you want having count(distinct x) = 2 instead.
You Shooud use count(distinct X) group by A and having
count(distinct...) avoid situation where you have two time the same value for X
select A
from my_table
WHERE x in ('Flood', 'Rain')
group A
having count(distinct X) = 2

Different entries within 5 seconds

Sorry I don't know how to describe the topic.
i have a database where i store the unixtime of the entries and some other stuff, in this case the column "name" for the user and "type" it can be 1 or 2.
I want to check if there are entries where name is the same and type switches from 1 to 2 and back to 1 or 2 1 2 within 5 seconds.
So it shows me something like this:
Unixtime Name type
1550293559 Peter 2
1550293560 Peter 1
1550293561 Peter 2
Is there a query that can help me do this?
Sorry I really hope you guys understand that, I don't know how to explain the problem properly.
Thanks.
You can do that with a 3x self join on that table and the necessary conditions (All 3 rows have the same name etc.). See http://www.mysqltutorial.org/mysql-self-join/ for more info.
Note that as the join produces all the possible permutations as input material, you don't have to 'permute' the conditions in the where part of the query. E.g. To get the 5 second rule, you can just say
... where e1.unixtime > e2.unixtime and e2.unixtime > e3.unixtime and e3.unixtime+6 > e1.unixtime ...
Edit: since the original answer was downwoted, here is the full query (grumble grumble) assuming the table name 'sotest':
SELECT
*
FROM
sotest e1
JOIN
sotest e2
JOIN
sotest e3
WHERE
(e1.name = e2.name AND e2.name = e3.name
AND e1.unixtime > e2.unixtime
AND e2.unixtime > e3.unixtime
AND e3.unixtime + 6 > e1.unixtime)
AND ((e1.type = 1 AND e2.type = 2
AND e3.type = 1)
OR (e1.type = 2 AND e2.type = 1
AND e3.type = 2))

mysql select while skipping some number of rows

Is there a mysql syntax that can hop some rows?
For example
id value
1 a
2 b
3 c
4 d
5 e
6 f
7 g
8 h
9 i
SELECT * FROM table HOP BY 2
so the result will be
id value
3 c
6 f
9 i
or
id value
1 a
4 d
7 g
Take note: We don't know the actual ID of a row so we can't use a WHERE clause like this
WHERE ID is a multiple of 3 or etc.
I didn't realize you could do math in sql queries. Learned something new. Cool. Here's code that would select 1, 4, and 7.
$stmt = mysqli_prepare($connection, "SELECT * FROM users WHERE (ID+2)%3 = 0 AND ID>1");
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while($row = mysqli_fetch_assoc($result)){
echo $row['username'];
}
I don't see why it wouldn't work if id has gaps, as the man with ?mandarin? symbols for a name said.
Modulus(%), if you don't know, gives the number of decimals given by a division problem. So 3/3=1, with no decimals, so 3%3=0, whereas 4/3=1.333333..., so 4/3 equals infinity(not really in programming, but close enough).
SELECT * FROM hoptable WHERE ID%3 =0 AND ID>1
SET #row_idx := 0;
SELECT *, (#row_idx := #row_idx + 1) AS idx
FROM table
HAVING idx % 3 = 0;
You probably want to include an ORDER BY clause so the row index can actually be meaningful though. You can't rely on the result being ordered by id without specifying it.

Mysql having a table reference itself

What I'd like to do is for a gaming application I need to search for my non player characters and they have a field called target_id that stores the id of whatever they are chasing.
given:
table mobs with fields and some example data
id x y target_id
1 1 1 2
2 3 3 1
I would like to return the following data with a query
id x y target_id target_x target_y
1 1 1 2 3 3
2 3 3 1 1 1
This is what I tried but it has syntax errors
SELECT id,x,y,target_id, target.x, target.y FROM mobs LEFT JOIN mobs AS target ON target_id=id FROM mobs WHERE 1
I don't know why you have a WHERE 1 or the second FROM, but I believe that this is what you want:
SELECT M.id, M.x, M.y, M.target_id, T.x, T.y
FROM mobs AS M
LEFT JOIN mobs AS T
ON M.target_id = T.id
In the future, you should post your table definition, and the expected result so your question is more clear.
Correct syntax as far as I know is:
SELECT mobs.id, mobs.x, mobs.y, mobs.target_id, target.x, target.y
FROM mobs
LEFT JOIN mobs AS target
ON mobs.target_id = target.id
You've already specified the 'FROM' by saying 'JOIN' and you don't need a WHERE when you don't need to filter any rows
Edit: sorry I didn't put the aliases in - you need to make sure the last part (and the fields in the select) have which tables you want to target - remember, saying target_id doesn't mean much if you have two tables in the query with the same column name. You will get an ambiguity error otherwise. I've added the aliases to the query

mysql lookup match

I have a database column like this:
id
50
55
56
62
63
64
65
68
70
72
80
etc...
I want to iterate through the id column with the following formula to find if the result of the formula is an id number in the same column. I want to compute all the possible combinations of the set of basically 3 records in the id column.
First loop:
Does ((second_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
Per the formula, the first loop is
(55-50)*2.00(as an example of variable decimal) + 55 = 65. 65 is in the list => 65 is tagged with the 2 records which equal it
Second loop:
Does ((third_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
(56-50)*2.00(as an example of variable decimal) + 56 = 78. 78 is not in the list => 78 is not tagged
Third loop:
Does ((fourth_id_number - first_id_number) * variable decimal) + second_id_number equal a number in the id column?
etc...
I want the results to show all the tagged records. A tagged record is the set of the 3 records where the third record is the result from the formula.
Anyone got any ideas? Is it possible in mysql?
Thank you
If I'm understanding your requirements properly, it sounds like you'd want to use a self-join on the table, e.g.
SELECT ...
FROM yourtable AS parent
LEFT JOIN yourtable AS child ON
FLOOR((parent.second_id_number - parent.first_id_number) * variable) + parent.second_id) = child.id
You could potentially carry something like this forward, which satisfies your first "loop"
select a.id as first_id_number
, b.id as second_id_number
, ((b.id - a.id) * 2) + b.id as third_id_number
from my_table as a
join my_table as b on a.id = (select max(id) from my_table where id < b.id)
where ((b.id - a.id) * 2) + b.id in (select id from my_table)
According to your description and test data, this would show 65 as "tagged" with first_id_number 50 and 62.
Warning: done on SQL Server using what I think is fairly standard syntax. I would understand if some would rather phrase this as a cross join with the select max... bit in the where clause rather than in the join predicate.