mysql select while skipping some number of rows - mysql

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.

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

Combine database queries

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'

Mysql recursive substracting and multiplying grouped values

Couldn't really explain my problem with words, but with an example I can show it clearly:
I have a table like this:
id num val flag
0 3 10 1
1 5 12 2
2 7 12 1
3 11 15 2
And I want to go through all the rows, and calculate the increase of the "num", and multiply that difference with the "val" value. And when I calculated all of these, I want to add these results together, but grouped based on the "flag" values.
This is the mathematical equation, that I want to run on the table:
Result_1 = (3-0)*10 + (7-3)*12
Result_2 = (5-0)*12 + (11-5)*15
78 = Result_1
150 = Result_2
Thank you.
Interesting question. Unfortunately MYSQL doesn't support recursive queries, so you'll need to be a little creative here. Something like this could work:
select flag,
sum(calc)
from (
select flag,
(num-if(#prevflag=flag,#prevnum,0))*val calc,
#prevnum:=num prevnum,
#prevflag:=flag prevflag
from yourtable
join (select #prevnum := 0, #prevflag := 0) t
order by flag
) t
group by flag
SQL Fiddle Demo

MySQL fetch results, sum it up

i'm trying to sum up values from one record (A) then add it to the sum values from another record (B), am wondering if this is possible?
ID ValueA ValueB ValueC
1 5 5 5
2 1 2 3
3 6 3 3
So what i'm trying to do here is to take ValueA, ValueB and ValueC of each record, adds it up so i can make an average.
So for
ID 1, i'll have 15 divide by 3 = 5
ID 2 i'll have 6 divide by 3 = 2
ID 3 i'll have 12 divide by 3 = 4
then i will have to add all 3 of these up
i'll get 11
and divide it by 3 and get an average of 3.67.
My Query
$result = mysql_query('SELECT * FROM teams WHERE UPPER(team)=UPPER("'.$team.'")');
while($row = mysql_fetch_array($result))
{
$ValueA = $row['ValueA'];
$ValueB = $row['ValueB'];
$ValueC = $row['ValueC'];
$All = $ValueA + $ValueB + $ValueC;
}
I know how to get the sum of 1 record, but not sure how can i do it with all 3 records. any help?
Edit : Sorry i forgot to add that i'll have to do average on each record first.
SELECT AVG(valueA + valueB + valueC)
FROM teams
should do the trick. Since you're selecting all records from the table, there's on grouping required.
Note that by default MySQL uses case-insensitive collations on tables, so your UPPER(team) business might not be required - removing the function calls would allow indexes (if any) to be applied to that particular match.
You can sum SQL functions together:
SELECT
(sum(ValueA) + sum(ValueB) + sum(ValueC)) / 3 as average
FROM
<your table>
WHERE
<your conditions>
SELECT SUM(ValueA + ValueB + ValueC) / (SELECT COUNT(*) FROM Teams)
FROM Teams
That will you the average you are looking for.

mysql query with AND, OR and NOT

Lets say I have a table of articles with as many to many relationship with topics. Each topic assigned to an article has a type field which can contain 1 of 3 values AND, NOT, and OR.
Articles
id
....
Topics
id
....
ArticleTopics
article_id
topic_id
type
I want to create a query that says returns all articles that have:
ALL of the following topics: 1, 2, 3 (AND association)
AND
ANY of the following topics: 4, 5, 6 (OR association)
AND
NONE of the following topics 7, 8 (NOT association)
How do I go about creating this query?
Thanks in advance!
The ALL and NOT parts are very simple, you just chain them with ANDs:
SELECT X FROM Y WHERE a AND b AND c AND NOT d AND e AND NOT e.
And the ORs go between:
SELECT X FROM Y WHERE ((a AND b AND c) AND (d OR e OR f)) AND NOT g AND NOT h
replace small numbers with comparisons and you're done.
So if you want to do this in code, sort your conditions and then just chain them together as a String. Be careful to avoid SQL-Insertions.
If I get this correctly
SELECT * FROM ArticleTopics where type = 'AND'
UNION
SELECT * FROM ArticleTopics where type = 'OR' limit 1
I assume by 'any' you mean 'any one'. You can join the articles to topics yourself, that's trivial.
SELECT a.id, a.name
FROM Articles a, ArticleTopics arto
WHERE arto.article_id = a.id
AND
((arto.topic_id = 1 AND arto.type like 'AND') AND (arto.topic_id = 2 AND arto.type like 'AND') AND (arto.topic_id = 3 AND arto.type like 'AND'))
AND
((arto.topic_id = 4 AND arto.type like 'OR') AND (arto.topic_id = 5 AND arto.type like 'OR') AND (arto.topic_id = 6 AND arto.type like 'OR'))
AND
((arto.topic_id = 7 AND arto.type like 'NOT') AND (arto.topic_id = 8 AND arto.type like 'NOT'))