I have data in mysql table like this
no code
1 03
2 (null)
3 (null)
4 02
5 (null)
6 (null)
7 05
8 (null)
9 (null)
what's query i must type that the data like this
no code
1 03
2 03
3 03
4 02
5 02
6 02
7 05
8 05
9 05
Try this:-
SELECT no, code = (#n := COALESCE(code, #n))
FROM MY_TABLE
ORDER BY no;
Related
Imagine I have the following tables:
Numbers PK
1
2
3
4
5
6
7
8
9
10
Numbers FK 1
Numbers FK 2
1
1
2
1
3
1
4
1
5
1
6
1
7
1
8
1
9
1
10
1
8
8
10
4
7
3
4
9
1
6
3
9
4
6
5
6
I have the following tables: "Numbers PK" as Primary key and another 2 tables that are related one with each other that are foreign keys of Numbers.
I am trying to make a query to select the number(s) from the table "NumbersFK2" that are related with all the numbers of "Numbers PK".
As you can see in this example the solution would be 1 as 1 is related with 1-10 in the tables "Numbers FK1" and "Numbers FK2"
I have tried to solve and after some days I need some help as I don't know how could I do it. I appreciate the help. Thanks
We use dense_rank() to count the Numbers_PK in case they're not consecutive. Then we left join, group by and count(distinct Numbers_PK).
with t3 as (
select Numbers_PK
,dense_rank() over(order by Numbers_PK) as dns_rnk
from t
)
select Numbers_FK_2
from t3 left join t2 on t2.Numbers_FK_1 = t3.Numbers_PK
group by Numbers_FK_2
having count(distinct Numbers_PK) = max(dns_rnk)
Numbers_FK_2
1
Fiddle
So i have this table:
req_num
number
status
order
1254
5
7
1
1254
4
7
2
1254
6
7
3
1246
7
8
1
1246
5
8
2
1246
3
8
3
1253
1
9
1
1253
4
7
2
1253
7
4
3
1321
7
4
1
1321
8
4
2
1321
7
4
3
1321
8
4
4
and i need to know if theres a way to generate a query that get a column like this based on the highest value in the "order" column.
req_num
number
status
order
last_req
1254
5
7
1
not_last
1254
4
7
2
not_last
1254
6
7
3
last
1246
7
8
1
not_last
1246
5
8
2
not_last
1246
3
8
3
last
1253
1
9
1
not_last
1253
4
7
2
not_last
1253
7
4
3
last
1321
7
4
1
not_last
1321
8
4
2
not_last
1321
7
4
3
not_last
1321
8
4
4
last
this table doesnt have any ids and i can't do inserts on it, any ideas?
You can use window functions to accomplish this - you can partition your data by req_num and then take the item in each partition with the highest order.
The docs: https://dev.mysql.com/doc/refman/8.0/en/window-functions-frames.html
The result will be something like (untested):
SELECT rec_num, number, status, LAST_VAL(order) OVER w AS 'last',
FROM my_table
WINDOW w AS (PARTITION BY req_num ORDER BY order);
That won't give you exactly what you want as all the rows will now include the highest order num for that rec_num. But you can then easily compare the order and last columns to create your last and not_last identifiers.
SELECT rec_num, number, status, LAST_VAL(order) OVER w AS 'last',
IF(`order` = `last`, 'last', 'not_last') AS last_req
FROM my_table
WINDOW w AS (PARTITION BY req_num ORDER BY order);
The window functions are remarkably powerful for situations like this.
In order to solve this problem, you need to look for the maximum value in the order field, grouped by req_num.
If your version is MySQL 8.0, you can use the ROW_NUMBER window function to assign an ordinal value to that column in a descendent way, so that your max value has ranking = 1. Afterwards you check with an IF statement if your column has the value 1 or not, and replace with 'last' and 'not_last' accordingly.
SELECT *,
IF(ROW_NUMBER() OVER(PARTITION BY req_num_ ORDER BY order_ DESC) = 1,
'last',
'not_last') AS last_req
FROM tab
Demo here.
If your version is MySQL 5.X, you can first use the MAX aggregation function in a subquery containing only req_num and order, by grouping on the former field and aggregating on the latter one. Then you can LEFT JOIN the original table with this result set, and the order values who will have assigned NULL will be the ones that are 'not_last'.
SELECT tab.req_num,
tab.status,
tab.order,
IF(max_values.max_order, 'last', 'not_last') AS last_req
FROM tab
LEFT JOIN (SELECT req_num_,
MAX(order) AS max_order
FROM tab
GROUP BY req_num ) max_values
ON tab.req_num = max_values.req_num
AND tab.order = max_values.max_order
Demo here.
This question already has an answer here:
How to write these complex MySQL queries?
(1 answer)
Closed 1 year ago.
I am a beginner at databases. I need to write some SQL queries.
The tables are:
Expedition(id, number, id_captain, id_ship, id_heros)
City(id, name)
Heros(id, family_name, first_name)
Step(id, index, id_expedition, id_city)
sample data :
'Table expedition'
id
number
id_captain
id_ship
id_hero
1
1
1
10
8
2
2
2
1
5
3
3
1
8
3
4
4
10
9
6
5
5
5
7
4
6
6
6
5
4
7
7
7
3
7
8
8
8
2
8
9
9
9
1
3
10
10
1
4
2
11
11
6
3
1
12
12
8
6
1
13
13
5
8
6
14
14
4
9
9
15
15
3
10
4
16
16
10
2
2
17
17
9
3
3
18
18
8
7
7
19
19
9
8
10
20
20
7
2
2
table 'heros'
id
family_name
first_name
1
familyname1
firstname1
2
familyname2
firstname2
3
familyname3
firstname3
4
familyname4
firstname4
5
familyname5
firstname5
6
familyname6
firstname6
7
familyname7
firstname7
8
familyname8
firstname8
9
familyname9
firstname9
10
familyname10
firstname10
query1: The family (based on the family name) with the least travelling (the fewest cities different crossings).
i have done this for the first query:
select expedition.id, id_hero, heros.family_name as Famille_expedition, count(distinct id_city) as city_count
from expedition, step, heros
where expedition.id=step.id and expedition.id_hero=heros.id
group by id_hero
having city_count =
(select count(distinct id_city) as min_city_count
from expedition, step
where expedition.id=step.id
group by id_hero
order by min_city_count asc
limit 1);
query2: The average of cities crossed by an expedition
I have no idea how to answer the second one.
Well, first ask yourself what information do you need to answer your question?
From your question, I'd say the average number of crossings is just the sum of all entries in the steps table, divided by the number of expeditions, since in each step, one city is visited and the average of all visits is what you are looking for:
SELECT (
(SELECT COUNT(s.id_city)
FROM step AS s) /
(SELECT COUNT(e.id)
FROM expedition AS e) ) AS total_average__cities
That being said, it depends on how exactly you define number of cities and crossing. Imagine the following example data for the table step:
id
idx
id_expedition
id_city
1
1
1
1
2
2
1
5
3
3
1
3
4
1
2
5
5
2
2
9
6
1
3
8
7
2
3
5
8
3
3
9
9
4
3
5
10
5
3
8
The table lists the steps for three expeditions. Expedition 1 goes from one city via another to a third. Expedition 2 goes directly from one city to another. And expedition 3 goes through several cities and visits one city twice along the way and also returns to the city that it started in.
The average number of cities over all these steps is (3 + 2 + 5 [cities in all steps]) / 3 [expeditions] = 3.3333. That is the result of the above query.
Now, if you define number of cities as meaning unique cities for each expedition, expedition 3 only visits 3 cities instead of 5. Then your average calculates as (3 + 2 + 3 [unique cities/expedition in all steps]) / 3 [expeditions] = 2.6666. The according query needs to count the distinct cities within each expedition before building the average:
SELECT (
(SELECT SUM(cnt) FROM (SELECT COUNT(DISTINCT s.id_city) AS cnt
FROM step AS s
GROUP BY s.id_expedition) t) /
(SELECT COUNT(e.id)
FROM expedition AS e) ) AS total_average__cities
Now, if you define crossing as only covering cities along the way, expedition 1 only crosses 1 city and expedition 2 crosses none at all.
Then your query also needs to look differently. You need to filter the all cities to exclude the first and the last for each expedition. The subquery could look like this:
SELECT s.* FROM step s
JOIN ( SELECT id_expedition,
MAX(idx) AS max_idx,
MIN(idx) AS min_idx
FROM step s
GROUP BY id_expedition) minmax
ON s.id_expedition = minmax.id_expedition
AND s.idx > minmax.min_idx
AND s.idx < minmax.max_idx
So for the case that you want the number of cities crossed excluding start and stop, your average would be computed as (1 + 0 + 3 [intermediate cities in all steps]) / 3 [expeditions] = 1.3333. The according query would be
SELECT (
(SELECT COUNT(s.id_city)
FROM step s
JOIN ( SELECT id_expedition,
MAX(idx) as max_idx,
MIN(idx) as min_idx
FROM step s
GROUP BY id_expedition) minmax
ON s.id_expedition = minmax.id_expedition
AND s.idx > minmax.min_idx
AND s.idx < minmax.max_idx) /
(SELECT COUNT(e.id)
FROM expedition AS e) ) AS total_average__cities
Finally, in case you want to both exclude start and stop and only want to count unique cities, your average would be computed as (1 + 0 + 2 [unique intermediate cities in all steps]) / 3 [expeditions] = 1. The following query combines the two approaches from above:
SELECT (
(SELECT SUM(cnt) FROM (SELECT COUNT(DISTINCT id_city) AS cnt
FROM step s
JOIN ( SELECT id_expedition,
MAX(idx) AS max_idx,
MIN(idx) AS min_idx
FROM step s
GROUP BY id_expedition) minmax
ON s.id_expedition = minmax.id_expedition
AND s.idx > minmax.min_idx
AND s.idx < minmax.max_idx
GROUP BY s.id_expedition) t) /
(SELECT COUNT(e.id)
FROM expedition AS e) ) AS total_average_cities
You can test all these queries in this db<>fiddle.
I have these three tables below. I want to join them using a MySQL query. Below the tables I've provided also how my output should look like.
GameTable:
GameID GameName
1 NvsA
2 NvsB
3 DvsA
4 NvsE
PlayerOnGame:
GameID PlayerName PlayerNumber PlayerID
1 Clement 7 10
1 Niyoyita 8 11
2 Clement 8 10
2 David 6 5
PlayerdataTable:
GameID Action PlayerNumber
1 kick 7
1 pass 8
1 Run 7
1 Kick 7
2 Kick 8
2 Pass 6
2 Run 8
2 Run 8
Output for only PlayerName = Clement:
GameName Action ActionCount
NvsA Kick 2
NvsA Run 1
NvsB Kick 1
NvsB Run 2
Please can someone help me with the query to get this output?
You can use this query to count
SELECT
gt.GameName,
pdt.Action,
count(pdt.Action) AS ActionCount
FROM GameTable AS gt
INNER JOIN PlayerdataTable AS pdt ON pdt.GameID = gt.GameID
INNER JOIN PlayerOnGame AS pg ON pg.GameID = pdt.GameID AND pg.PlayerNumber = pdt.PlayerNumber
WHERE pg.PlayerName = 'Clement'
GROUP BY gt.GameID , pdt.Action
I'm wondering if there is a way to do a numeric sort when the number is a string. Take a look at example:
The query:
SELECT * FROM t_tables t order by id_string asc
This is the list from DB:
13
4
6
8
10
1
3
2
5
12
7
9
11
I need to extract it in this way:
1
2
3
4
5
6
7
8
9
10
11
12
13
But as result I get this:
1
10
11
12
13
2
3
4
5
6
7
8
9
If you know that you always have numeric values in the column you can use the CAST() operator. Also have a look at this question.
SELECT * FROM t_tables t ORDER BY CAST(id_string AS UNSIGNED) ASC
SELECT * FROM t_tables t order by cast(id_string as signed integer) asc;
Hope it helps:
SELECT * FROM t_tables t order by cast(id_string as unsigned)