Count rows to end - mysql

id date group n1 n2 n3 n4 n5
18853 1945-01-05 BA 87 34 1 59 50
18854 1945-01-13 BA 6 66 1 16 48 <= the last 16, 7 rows to the end
18855 1945-01-20 BA 38 14 24 78 36
18856 1945-01-27 BA 49 30 87 15 65 <= the last 49, 5 rows to the end
18857 1945-02-03 BA 30 64 36 5 32
18858 1945-02-10 BA 15 36 37 86 31 <= the last 36, 3 rows to the end
18859 1945-02-17 BA 86 78 69 7 60 <= the last 86, 2 rows to the end
18860 1945-02-24 BA 83 7 72 88 19 <= the last 7, 1 row to the end
18861 1945-03-03 BA 47 20 77 73 30 <= the last 47, 0 rows to the end
I have the above table (it's ordered by id, however I plan to order it by date). Is there a way to get the number of rows between a specified number and the last row in mySql?
Note that some numbers are repeated twice or more times. The script should use the lowest rows.
Here is the table that mySQL should output:
Number|Rows count to the end
16|7
7|1
86|2
49|5
47|0
36|3
The query should search columns n1, n2, n3, n4, n5 and pick the value most nearly to the end and count the remaining rows to the end.
Thanks ;)

Assuming your unnamed columns are named as follows:
c1 c2 c3 c4 c5 c6 c7 c8
18853 1945-01-05 BA 87 34 1 59 50
18854 1945-01-13 BA 6 66 1 16 48
18855 1945-01-20 BA 38 14 24 78 36
18856 1945-01-27 BA 49 30 87 15 65
18857 1945-02-03 BA 30 64 36 5 32
18858 1945-02-10 BA 15 36 37 86 31
18859 1945-02-17 BA 86 78 69 7 60
18860 1945-02-24 BA 83 7 72 88 19
18861 1945-03-03 BA 47 20 77 73 30
Furthermore assuming c1 is you PK index column and column c7 is the one you're interested in, following might give you what you want:
select t1.c7, MAX(t1.c1), (select count(*)
from table t2
where MAX(t1.c1) < t2.c1) as rowsToEnd
from table t1
group by t1.c7
Ok, after having supposedly understood what you want, the following should give you what you want:
EDIT: After having read Imre L's answer i realized i totally forgot about the IN operator, so this is the more elegant solution:
EDIT AGAIN: After having read your question update.
This is assuming that one of c4, c5, c6, c7, c8 contains all numbers that are occur in any one of those rows:
select distinct t3.c4, ( select count(*) AS RowsToEnd
from table t1
where t1.c1 > ( select max(t2.c1)
from table t2
where t3.c4 IN
(t2.c4, t2.c5, t2.c6, t2.c7, t2.c8)
)
from table t3

assuming the columns of numbers are names n1..n6
using 16 as the example number
select count(1)
from tablename
where date > (select date
from tablename
where 16 in (n1,n2,n3,n4,n5,n6)
order by date desc
limit 1)
what about reoccuring dates?

Related

mysql find closest list of numbers in multi column

here is the table and values
ID c1 c2 c3 c4 c5
______________________
1 60 11 29 50 90
2 59 12 32 51 81
3 61 16 30 53 92
4 66 13 34 55 91
5 57 14 28 49 73
and this is the list of numbers [59,13,33,56,94] (I mean 59 for c1 , 13 for c2 and ..)
now how to select top 3 closest record base on list
I suspect that you may mean closest by something like Euclidean distance.
The idea is order by and limit:
select t.*
from t
order by pow(c1 - 59, 2) + pow(c2 - 13, 2) + pow(c3 - 33, 2) +
pow(c4 - 56, 2) + pow(c5 - 94, 2)
limit 3;
You could use:
SELECT *, ABS(c1-a1) + ABS(c2-a2) + ABS(c3-a3) + ABS(c4 - a4) + ABS(c5-a5) AS total
FROM tab
CROSS JOIN (SELECT 59 a1,13 a2,33 a3,56 a4,94 a5) l
ORDER BY total LIMIT 3

Mysql group by customer and get last 3 records

Sql Table
Sales Date order Id customer_id medium
07-07-2018 WP241530914666620 26 4
21-07-2018 WP241532133344497 26 4
29-07-2018 WP241532821589511 26 4
01-07-2018 1100070191 61 3
05-07-2018 1100071337 61 3
11-07-2018 1100073077 61 3
15-07-2018 1100074754 61 3
21-07-2018 1100075959 61 3
25-07-2018 1100077484 61 3
01-07-2018 100207654 64 3
07-07-2018 100210077 64 3
08-07-2018 WP241531004708220 64 4
Result:-
Sales Date order Id customer_id medium
07-07-2018 WP241530914666620 26 4
21-07-2018 WP241532133344497 26 4
29-07-2018 WP241532821589511 26 4
01-07-2018 1100070191 61 3
05-07-2018 1100071337 61 3
11-07-2018 1100073077 61 3
i need mysql query for above result .
last 3 orders for each customers in above table . i am trying some codes but unable to get results for the above
You could using correlated subqueries like:
select Sales_Date,order_Id,customer_id,medium
from
(select y1.Sales_Date,y1.order_Id,y1.customer_id,y1.medium,
(select count(*)
from 'yourtable' y2
where y2.customer_id=y1.customer_id
and (y2.Sales_Date < y1.Sales_Date or y2.Sales_Date = y1.Sales_Date)
) rn
from 'yourtable' y1
) finalresult
where rn<=3
Reference:
correlated subqueries
Example

Selecting and deleting duplicated rows for particular columns SQL

I have an sql table that saves Locations,
ID Name X Y Z
-------------------------
1 Loc1 12 24 45
2 Loc2 12 24 60
3 Loc3 54 32 33
4 Loc4 54 32 64
5 Loc5 98 66 90
6 Loc6 98 66 77
7 Loc7 44 50 98
Some Location coordinates (x and y) are duplicated by mistake
I want to select and delete one of them.
ID Name X Y Z
-------------------------
1 Loc1 12 24 45
2 Loc3 54 32 33
3 Loc5 98 66 90
4 Loc7 44 50 98
Is this possible with sql query?
I think you can use the alter-table command and just drop the whole column.
ALTER TABLE table_name
DROP COLUMN column_name
with cte
as
(
select *,row_number() over (partition by x,y order by x) as rn
)
delete from cte where rn>1
As seen pointed out in comments,this deletes a random row (undeterministic),to make it deterministic order by name in your case
For MySQL you can use:
DELETE mytable
FROM mytable
JOIN (SELECT MIN(ID) AS ID, X, Y
FROM mytable
GROUP BY X, Y
) AS t ON mytable.X = t.X AND mytable.Y = t.Y AND mytable.ID > t.ID
Demo here
Its easy:
Add an INDEX over the 2 Columns with IGNORE:
ALTER IGNORE TABLE YOUR_TABLE
ADD KEY (X,Y);
Thats all

MySQL calculate difference in count column between two queries

I have two different queries. One for "plus" and one for "minus". I want to find the difference in the count value for each player.
I tried union all and got some very weird numbers.
Here are the results of each query which I ned to find the difference of:
fk_plus_player1_id cnt
90 71
65 68
79 66
45 59
64 57
27 56
55 56
93 55
37 55
40 44
1 36
84 33
20 31
24 28
8 23
fk_minus_player1_id cnt
93 44
64 42
79 40
37 35
90 33
20 31
84 31
27 30
65 30
40 26
1 26
24 25
45 25
55 22
8 10
How would I accomplish this? Thanks in advance for your help. I am a noob...
UGH...Trying to do the join method. Having issues, getting no results, just 4 empty columns. This is what I am trying
SELECT
*
FROM
(
SELECT
statement for plus results here
) AS tp
JOIN (
SELECT
statement for minus results here
) AS tm ON tp.fk_plus_player1_id = tm.fk_minus_player1_id
GROUP BY
fk_plus_player1_id
suggestions??
You have two tables.
You want for each player, the difference of the counts.
So :
SELECT t1.fk_minus_player1_id AS player, ABS(t1.cnt - t2.cnt) AS difference
FROM table1 t1, table2 t2
WHERE t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id;
Maybe this is what you're looking for ?
WITH query1 AS
(SELECT t1.fk_minus_player1_id AS player, (t1.cnt - IFNULL(t2.cnt,0)) AS difference
FROM table1 t1 LEFT OUTER JOIN table2 t2 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t1.fk_minus_player1_id),
query2 AS (SELECT t2.fk_plus_player1_id AS player, (IFNULL(t1.cnt,0) - t2.cnt) AS difference
FROM table2 t2 LEFT OUTER JOIN table1 t1 ON t1.fk_minus_player1_id = t2.fk_plus_player1_id
GROUP BY t2.fk_plus_player1_id)
(SELECT player, difference
FROM query1)
UNION
(SELECT player, difference
FROM query2 WHERE player NOT IN (SELECT player FROM query1))
You run the risk that the same players are not in both lists. The solution is union all with group by:
select player1id, sum(pluscnt) as pluscnt, sum(minuscnt) as minuscnt,
(sum(pluscnt) - sum(minuscnt)) as diff
from ((select player1id, cnt as pluscnt, 0 as minuscnt
from plustable
) union all
(select player1id, 0, cnt
from minustable
)
) t
group by player1id;

Find repeated battles

I have one table with the following fields:
battle_id, winner, looser
1 200 44
2 55 366
3 44 200
4 123 200
5 200 44
6 55 366
7 177 205
8 188 211
9 366 55
10 55 366
right now it has about 1300 records (its small), and there are about 400 players, in each battle there can only be a winner and a looser (there are no draws)
how can i find all the repeated battles? i do not want to find all the repeated battles of one player, i do want to know all the repeated battles of all the players...i know that i cam make a recursive function in php that iterates over all the battles and assign them to a matrix, but just for fun...is there a way to do it only on mysql?
And how can i optimize the table to find the repeated battles more quickly?
regards
EDIT:
For example i want the query to show:
battle_id, winner, looser
1 200 44
2 55 366
3 44 200
5 200 44
6 55 366
9 366 55
10 55 366
This should work, using a self-join could result in many duplicated entries
SQLFIDDLE
SELECT
t1.battle_id,
t1.winner,
t1.loser
FROM
your_table t1
WHERE
EXISTS (
SELECT
1
FROM
your_table t2
WHERE
( ( t1.winner = t2.winner
AND t1.loser = t2.loser )
OR ( t1.loser = t2.winner
AND t1.winner = t2.loser ) )
AND t1.battle_id <> t2.battle_id
)
try this:
SELECT b1.battle_id,
b1.winner,
b1.looser
FROM battles as b1
group by b1.battle_id, b1.winner, b1.looser
having count(*)>=2