How can i group_concat the selected max id in the query.
example:
select group_concat(max(id) SEPARATOR ',') from attempts group by user, attempt having count(*) > 1;
im having an error code
1111: invalid use of group function
One option is to use a subquery:
SELECT GROUP_CONCAT(id)
FROM
(
SELECT MAX(id) AS id
FROM attempts
GROUP BY user
) t;
The subquery finds all max id values for users in your table. Then, we roll them up into a CSV string. Note that if you wanted only distinct id values then you could have done:
SELECT GROUP_CONCAT(DISTINCT id)
Related
Yesterday I tried to retrieve data from my db table using 'user_id' as a criterion to limit the amount of data per user.
I tried to get data from table https://prnt.sc/p53zhp in format like this https://prnt.sc/p541wk and limit the number of output records for user_id where limit will be 2 (count(user_id) <= 2), but i don't understand how to do that. What kind of sql request can i use to get this data?
Assuming that your RDBMS, here is a solution yo select only the top 2 records per user. You can use ROW_NUMBER() in a subquery to rank records by id within groups of records having the same user_id, and the filter out unerelevant records in the outer query, like:
SELECT *
FROM (
SELECT
t.*,
ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY id)
FROM mytable
) x WHERE rn <= 2
On earlier versions of MySQL, you could use self-LEFT JOIN the table and use GROUP BY and HAVING COUNT(...) < 2 to limit the results to first two records per group:
SELECT
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
FROM mytable t
LEFT JOIN mytable t1 ON t1.user_id = t.user_id AND t1.id > t.id
GROUP BY
t.id,
t.user_id,
t.vip,
t.title,
t.description,
t.data
HAVING COUNT(t1.id) < 2
I don't understand if your problem is a Transact-SQL or your code.
In SQL you can limit record with "LIMIT": https://www.w3schools.com/sql/sql_top.asp
In code, you can use a condition IF.
values = 2,3,4
When doing a JOIN (SELECT *, SUM(values) AS MaxValues FROM table GROUP BY id), $a = $data['MaxValues'] will equal 9 as it should. However, how can I still pull the individual values(2,3,4)? trying a foreach on $b = $data['values'] only gives me one of the values. I'm assuming because of the required GROUP BY. I'm still new to all of this. Thank you
You are looking for group_concat(), I think:
JOIN (SELECT id, SUM(values) AS MaxValues, group_concat(values) as values
FROM table
GROUP BY id)
Note: You should not be using SELECT * with GROUP BY. Only include the columns in the GROUP BY clause.
You can select both values and SUM with JOIN. Also, you don't need GROUP BY if you want to get all the values, e.g.:
SELECT value, a.sum
FROM table, (SELECT SUM(value) AS `sum` FROM table ) a;
I have a table which has the id column and score column, I want to sort the table based on score column and then find the specific user who is loading the page and show him his/her position. for example, tell him "your position is 40th".
Well I know how to sort a query:
SELECT id,score FROM `table` ORDER BY `score` DESC
But after the sort how can I find an specific id's position?
You don't need an order by for this. Instead:
select 1 + count(*)
from table t
where t.score > (select t2.score from table t2 where id = $id);
Try it:
SELECT #rownum:=#rownum+1 ‘rank’, id, score FROM table t, (SELECT #rownum:=0) r ORDER BY score DESC;
This will create a column and increase 1 in each record.
If I have a mysql query like
(SELECT COUNT(*) FROM data AS amount)
UNION
(SELECT COUNT(*) FROM data WHERE some < 50 AS something)
and then create an array with php like this $row = mysqli_fetch_array($sql, MYSQLI_ASSOC);.
How can I now address each of the AS names. This does not work: echo $row["amount"];. The second question I have is why can't I use AS something when having a WHERE clause?
Try this:
(
SELECT
'amount1' as za_name,
COUNT(*) as za_count
FROM
data
)
UNION
(
SELECT
'amount2' as za_name,
COUNT(*) as za_count
FROM
data
WHERE some < 50
)
Then you can differentiate by $row[za_name] and get the amount $row[za_count]
For the second question : you can use it if you make a temp table :
SELECT
tmp.za_name,
tmp.za_count
FROM (
SELECT
'amount2' as za_name,
COUNT(*) as za_count
FROM
data
WHERE some < 50
) as tmp
In a UNION the row names/aliases for the entire query are whatever they are in the first query.
So if you have
SELECT field1 AS A
UNION
SELECT field2 AS B
Your final result will only have an A field, which will have both field1 and field2.
In your query, you want to alias the COUNT(*), not the table.
(SELECT COUNT(*) AS amount FROM data)
UNION
(SELECT COUNT(*) FROM data WHERE some < 50)
Nor $row['amount'] will be all of the COUNT(*) rows from the entire query.
in your query
(SELECT COUNT(*) FROM data AS amount) UNION (SELECT COUNT(*) FROM data WHERE some < 50 AS something)
You are aliasing the table data to the name amount rather than the sub-query
You have to edit the query this way (aliases on the columns, too)
(SELECT COUNT(*) as amount FROM data)
UNION
(SELECT COUNT(*) as amount FROM data WHERE some < 50 AS something)
This way You are able to address $result['amount'] as a result from the fetch assoc method.
If I have a list of ID's that I have selected from a statement
SELECT id FROM myTable WHERE name = 'TEST'
This would return just the ids (1001, 1002, 1003, etc...) Then I want to perform another SELECT statement to retrieve all the titles for all those ids.
SELECT title FROM myTable2 WHERE id = XXXX
the id in table2 is the foreign key of table2. id in myTable is the Primary Key. How can I go about retrieving all the titles from those ids. I was thinking about storing all the results of the first select statement in an array, and then using a while loop to iterate through the list and return each result into another array, but my fear is that when the database gets big if it has to return 1000 rows that could be some bad overhead. So in PHP or SQL what is the best way to perform this?
You can use a subquery:
SELECT title
FROM myTable2
WHERE id IN (
SELECT id
FROM myTable
WHERE name = 'TEST'
)
Another way to do it would to be use a JOIN, to avoid the sub-query:
SELECT title
FROM myTable2
LEFT JOIN myTable
ON myTable.id = myTable2.id
WHERE myTable.name = 'TEST'
You should just be able to select them at the same time.
SELECT a.id, b.title
FROM myTable a, myTable2 b
WHERE a.name = 'TEST' AND b.id = a.id;
to select both:
SELECT id, title FROM mytable WHERE name="TEST"
or to select the whole row
SELECT * FROM mytable WHERE name="TEST"
if its two tables you are selecting from:
SELECT id, title FROM mytable A JOIN mytable2 B USING (id)