How to use limit and group by together in mysql - mysql

With these sample tables
table_a table_b
column_1 column_1 column_2
1 1 A
2 1 B
3 2 C
4 3 D
5 4 E
the query below
SELECT table_a.column1,table_b.column2
FROM table_a
INNER JOIN table_b ON table_a.column1 = table_b.column_1
GROUP BY table_a.column1 LIMIT 3
gives only 2 results (limit is 3) since the value 1 is duplicating in table_b. How can i get 3 results with unique table_a.column1 values. In general how can i use group by and limit together with group by having no impact on the limit

After minor adjustments with columns names (changing column1 into column_1 and column2 into column_2) your query gives me exactly 3 rows of results.
1 A
2 C
3 D

Related

Get count of all types of values in a column obtained in the same SELECT SQL query

MySQL Version: 5.7.36
I'm attempting to minimize the amount of queries I have to execute.
Right now, I'm executing a query similar to this:
SELECT
TABLE 1.column1 as "A",
TABLE 1.column2 as "B"
FROM
TABLE 1
WHERE
CONDITION
I can obtain the results I need from this query, however I would also like to obtain the count of what type of values show up in the same query.
For example, if the following query retrieves this table
A B
- -
1 a
1 b
1 c
2 d
3 e
4 f
4 g
I would also like to, for each row, obtain the count of all rows retrieved with its column "A" that matches its value.
Would it be more efficient to execute another query to get that result or can I modify my obtaining query to get this statistic?
Desired result:
A B C
- - -
1 a 3 # 3 rows with "1" in Column "A"
1 b 3
1 c 3
2 d 1
3 e 1
4 f 2
4 g 2
UPDATE:
The closest query I could find goes like this:
SELECT
TABLE 1.column1 as "A",
COUNT(TABLE 1.column1)
FROM
TABLE 1
WHERE
TABLE 1.column1 = "foo"
GROUP BY
TABLE 1.column1
Results in this:
A B C
- - -
1 a 3
2 d 1
3 e 1
4 f 2
However, it removes any other rows with the same value in column "A". Even if it has different values in column "B". I would like to have all rows present in my SQL query with its corresponding row count.
The next closest query I found goes like this:
SELECT
TABLE 1.column1 as "A",
COUNT(TABLE 1.column1)
FROM
TABLE 1
WHERE
TABLE 1.column1 = "foo"
GROUP BY
TABLE 1.column2
Results in this:
A B C
- - -
1 a 1
1 b 1
1 c 1
2 d 1
3 e 1
4 f 1
4 g 1
Which also isn't achieving the desired result.
You have to join with the subquery that gets the counts.
SELECT t1.column1 AS A, t1.column2 AS B, t2.count
FROM Table1 AS t1
JOIN (
SELECT column1 AS A, COUNT(*) AS count
FROM Table1
GROUP BY column1
) AS t2 ON t1.A = t2.A
SELECT
c,
COUNT(*) OVER (PARTITION BY c)
FROM t
ORDER BY c

How can I get the result from mysql after group and order

I have the following tables
t1
id
stage
1
1,2,3
2
2,3,4
t2
id
t_id
stage_id
1
1
2
2
1
1
3
1
3
4
2
2
5
2
4
6
2
3
I hope the result can first order by t2.t_id and then order by the value of t1.stage
like the following result
t_id
stage_id
1
1
1
2
1
3
2
2
2
3
2
4
I have the following sql ,but it do not work.So what should I do?
SELECT
t2.t_id,
t2.stage_id
FROM
t2
LEFT JOIN t1 ON t1.id = t2.t_id
GROUP BY
t2.t_id,
t2.stage_id
ORDER BY
t2.t_id,
field(t2.stage_id, t1.stage)
FIELD() requires each value to sort by to be a separate argument.
FIND_IN_SET() returns the index in a comma-separated string.
SELECT
t2.t_id,
t2.stage_id
FROM
t2
LEFT JOIN t1 ON t1.id = t2.t_id
GROUP BY
t2.t_id,
t2.stage_id
ORDER BY
t2.t_id,
find_in_set(t2.stage_id, t1.stage)
Note that this only corrects the ordering criteria in your SQL. This won't necessarily return the first row in each group by that ordering (and will get an error if the ONLY_FULL_GROUP_BY SQL mode is enabled). See SQL Selecting from two Tables with inner join and limit for the correct way to do that.

Joining tables and getting a count of specific record

I am having two tables say table_a and table_b with following structure.
table_a : ID(primary key), value_one
table_b: ID, value_two
Note that id in table_b is not primary and contains multiple records to same id.
now i want a third table which displays a record for every id in table_a with columns being
id column_count
the column _count will display number of records (count) in table_b with value_two = 'c'. and i want to iterate this to all records of table_a.
For example lets say our table_a is like this:
id value_one
1 20
2 40
3 50
table_b
id value_two
1 10
1 20
1 10
2 40
2 10
3 40
3 10
I want records with value_two = 10 so my new table would look like
id count
1 2
2 1
3 1
Since id 1 has two records with value_two = 10 and id 2 and id 3 have one record each with value_two = 10
One way of doing this uses a correlated subquery:
select a.id,
(select count(*) from table_b b where b.id = a.id and b.value_two = 10) as cnt_10
from table_a a;
Another method uses a left join:
select a.id, count(b.id)
from table_a a left join
table_b b
on b.id = a.id and b.value_two = 10
group by a.id;
In your example data, this works:
select b.id, count(*)
from table_b b
where b.value_two = 10
group by b.id;
This is equivalent under the following circumstances:
All ids in a are in b.
All ids have at least one value of 10.
If these two conditions are true, then use this simpler query.
You can do conditional aggregation :
select id, sum(value_two = 10) as count
from table_b tb
group by id;
If you want matching ids then add INNER JOIN. This will show 0 count whereas value_two = 10 not found. You can add where clause to find only value_two = 10 count.

Combine queries in MySQL

I have two table in MySQL that looks as follows:
ID Name Information
1 A fsdf
2 B ada
3 A dsafd
4 A retret
5 C asdfsa
6 B xzc
and,
P_ID Name Loc_X Loc_Y
1 A 2 3
2 B 3 4
3 C 4 5
I would like to run a query in MySQL that return the result as follows:
NAME COUNT Loc_X Loc_Y
A 3 2 3
B 2 3 4
C 1 4 5
Currently, I am able to execute the following query:
SELECT Name,COUNT(*) as count FROM Table_A GROUP BY Name ORDER BY count DESC;
to get the following result:
NAME COUNT
A 3
B 2
C 1
I know that probably I can use this result to extract only the "Name" and fire another query to get the Loc_X and Loc_Y using PHP, but I was wondering whether there is a moe efficient way of doing it using DML. Is there a way to nest the queries?
Try something like this :
SELECT Table_A.Name,COUNT(*) as count, Table_B.Loc_X, Table_B.Loc_Y
FROM Table_A
INNER JOIN Table_B ON Table_A.name = Table_B.name
GROUP BY Table_A.Name, Table_B.Loc_X, Table_B.Loc_Y
ORDER BY count DESC;
I think you just need to join the tables on the common field here.
Try:
SELECT a.Name, count(a.id) AS Count b.Loc_X, b.Loc_Y
FROM Table_A a
INNER JOIN Table_B b ON a.Name = b.Name
GROUP BY a.Name

first item used by a user

I am writing a query to grab the items that a specific user_id was the first to use. Here is some sample data -
item_id used_user_id date_used
1 1 2012-08-25
1 2 2012-08-26
1 3 2012-08-27
2 2 2012-08-27
3 1 2012-08-27
4 1 2012-08-21
4 3 2012-08-24
5 3 2012-08-23
query
select item_id as inner_item_id, ( select used_user_id
from test
where test.item_id = inner_item_id
order by date_used asc
limit 1 ) as first_to_use_it
from test
where used_user_id = 1
group by item_id
It returns the correct values
inner_item_id first_to_use_it
1 1
3 1
4 1
but the query is VERY slow on a giant table. Is there a certain index that I can use or a better query that I can write?
i can't get exactly what you mean because in your inner query you have sorted it by their used_user_id and and on your outer query you have filtered it also by their userid. Why not do this directly?
SELECT DISTINCT item_id AS inner_item_id,
used_user_id AS first_to_use_it
FROM test
WHERE used_user_id = 1
UPDATE 1
SELECT b.item_id,
b.used_user_id AS first_to_use_it
FROM
(
SELECT item_ID, MIN(date_used) minDate
FROM tableName
GROUP BY item_ID
) a
INNER JOIN tableName b
ON a.item_ID = b.item_ID AND
a.minDate = b.date_used
WHERE b.used_user_id = 1