Lets say I have a table A ,
A
user count
a 4
b 1
c 3
d 2
I want to write a query which returns each value of A along with max value of count,something like
user maxCount
a 4
b 4
c 4
d 4
The way I am trying to achieve this is,
select user,max(count) as maxCount from A
The result which I get is :
user maxCount
a 4
Which is clearly not what I want.
I understand I could write multiple queries(i.e. 'select user from A' /'select max(count) from A') as this may seem redundant ,
but I think having it this way would be best for me as I don't want to call mysql multiple times and also I push the returned data as a single jsonObj to the front end , so it is easier to have a single table then combing two returned-tables into one and than converting into json
This query will give you the max value on all rows:
SELECT user,
(SELECT MAX(count) FROM yourTable) AS maxCount
FROM yourTable;
Try this:
select user,max(count) as maxCount from yourTable group by user
That will get your your max counts, and group them by whatever unique values are in the user column.
Related
in my local website, people can pass a test, and administrator can see the result.
before, all the result were display but it was ugly, so I decided to show only the last test people pass. but I'm stuck because I can show only one result per person, but I can't sort him by date :(
SELECT * FROM resultateval join personne using (id) group by id
this is the query who show one result per people and here is the table.
it's supposed to show
654321 / 08-06-2018 / 12 : 02 / 5 / 8 / 1
A256589 / 05-06-2018 /13 : 05 / 7 / 10 / 2
Thank you!
Because you stored time and date separately, the query you'll need to do this is relatively ugly. We can form an effective timestamp by using ADDTIME to add the heuereeval time to the dateeval date. Then, this is just a basic aggregation join query:
SELECT t1.*
FROM resultateval t1
INNER JOIN
(
SELECT id, MAX(ADDTIME(dateeval, heureeval)) AS max_date
FROM resultateval
GROUP BY id
) t2
ON t1.id = t2.id AND
ADDTIME(t1.dateeval, t1.heureeval) = t2.max_date;
Demo
For future reference, avoid storing the date and time separately, unless there is a very good reason for doing so (and I don't see one here).
Edit: As a I feared, based on comments it appears that you have stored your dates as text. You can use the following function call to generate a date based on the date's text:
STR_TO_DATE(dateeval, '%d-%m-%Y')
Just replace in my original query dateeval with the above call to STR_TO_DATE and it should still work.
What you are doing is very wrong. You group by id, but you select all columns. As id is not unique in your joined data, this makes no sense and is invalid SQL. You cannot say: "Give me the dateeval (etc.) for the id". You must say something like: " "Give me the minimum / maximum / average dateeval for the id".
This query should result in an error, but MySQL outside ONLY_FULL_GROUP_BY mode let's this slip and silently converts select * to select id, any_value(dateeval), any_value(heureeval) .... So you get arbitrarily picked values that can even stem from different records.
What you want is something like this:
select *
from resultateval
join personne using (id)
where (id, timestamp(dateeval,heureeval)) in
(
select id, max(timestamp(dateeval,heureeval))
from resultateval
join personne using (id)
group by id
);
For example, lets say in column source I have the following entries
SourceFileEmbed122
SourceFile1333
SourceItem13366
PreLoadSource7755
And I do a query of SourceFile it should match row 1 and 2 and show me all the column data for that row, but if I search for example: PreLoadSource or SourceItem it shouldnt show anything, as there is only 1 row that has a similar entry.
Kinda like an if contains sort of thing.
Basically, I want to do something like:
SELECT source, COUNT(*) TotalCount FROM sources GROUP BY source HAVING COUNT(*) > 1 ORDER BY COUNT(*) DESC
But the query does LIKE instead of LIKE%...% (Like in PHPMyAdmin) which results in it only matching EXACT matches of each other, so stuff like:
row123/
row123
Wont match each other and will be ignored. But I want this to MATCH basically if row123's full text is ALSO all in another row's value, then match.
Lets say I have:
http://link.ext/dir123/file.mp3
http://link.ext/dir123
http://link.ext/dir123/file2.mp3
http://link.ext/dir123
The query should match .../file.mp3, .../file2.mp3 and ../dir123 because row 2 http://link.ext/dir123 is also in row 1, 3 and 4.
One way is doing a inner join with the same table,
if you need a simple count you can do something like that:
SELECT s1.source, COUNT(*)
FROM sources s1
INNER JOIN sources s2
ON s1.id <> s2.id AND s1.source LIKE CONCAT('%', s2.source, '%')
GROUP BY s1.source
One way to test for at least two matches is:
select s.*
from sources s
where s.source like '%<whatever>%' and
exists (select 1
from source s2
where s2.source like '%<whatever>%' and
s2.source <> s.source
);
I have a complicated select like:
select id from table
left join...
left join... (a lot of joins)
where ... (a lot of ANDs and ORs)
order by... (a lot of orders)
and I'm getting a result like:
1234
5565
7212
2212
etc.
I have an id which belongs to the result-set, like 7212, and want to know which row in the result-set matches the id (starting with row 0 this would be row 2 in my example).
Right now I'm reading all data and compare it in php, but I was wondering if there is a SQL-statement which does that for me and results 2 when entering 7212.
In fact I want to get the previous and next ids (row 1 and row 3 = 5565 and 2212), if thats somehow possible in 1 query that would be even better.
You can select the number row:
select #rownum:=#rownum+1 No, foo, bar from table, (SELECT #rownum:=0) r;
It's a possible duplicate of the question asked here: How to show sequential number in MySQL query result
Add an auto_increment index for each selected rows:
SELECT
#i:=#i+1 as index,
id
FROM table, (SELECT #i:= 0) AS i
LEFT JOIN...
LEFT JOIN...(a lot of joins)
WHERE ... (a lot of ANDs and ORs)
ORDER BY... (a lot of orders)
Give you this:
index id
1 1234
2 5565
3 7212
4 2212
So I am having a hard time trying to write a single query for this. I have a table we will call table_a. I need to pull a single record that matches certain criteria. If the first one produces nothing then fall back to another one. I have been at this awhile and it very well could be something simple I am just missing.
SELECT COALESCE(ta.id,tb.id,0) AS theid,
FROM table_a
RIGHT JOIN (
SELECT table_a.id
FROM table_a
WHERE table_a.field_3='1' AND table_a.field_4='100' AND table_a.user_id='someidhere'
) AS ta
ON table_a.id = ta.id
RIGHT JOIN (
SELECT table_a.id
FROM table_a
WHERE table_a.field_5='2' AND table_a.field_4='100' AND table_a.user_id='someidhere'
) AS tb
ON table_a.id = tb.id
The problem with RIGHT JOIN is if the first one does not produce a record it will not go on to the next one, if I do LEFT JOIN it will pull all the records from table_a, if I specify WHERE table_a.user_id='someidhere' it will obviously pull all the records for that user. I am only looking for one. Essentially only field_3 and field_5 will be the ones that change. If I can not find something for field_3 it moves onto field_5. This will run on a table with 80k records. Thoughts?
Although a newbie, starting out with a cryptic example is not the greatest, but I'm trying here. Your query in itself is rather pointless on what it is doing. Its joining to itself to ultimately grab the ID of a thing that is for a certain user ID and field 4 value, but the field 3 or 5 should be a 1 or 2 respectively.
So, I've written the query directly to the "a" table for the user ID and field 4 which were common regardless of your right-join... THEN added an ( OR ) for your field 3 and 5 columns. This way, I only care about those of the 3 OR 5 value with same user/field 4 area. The ORDER BY clause will force that any record with the field 3 value of 1 is sorted first, then any that are field 5 = 2 will be secondary... So the final first record would be the '1' entry if one existed.
SELECT
table_a.id
FROM
table_a
where
table_a.user_id = 'someidhere'
AND table_a.field_4 = '100'
AND ( table_a.field_3 = '1'
OR table_a.field_5 = '2' )
order by
case when table_a.field_3 = '1'
then 1 else 2 end
So, if there are multiple records returned, you only need to care about the first one returned (in case there are two that qualify).
I am fetching records from one table with count of one field with other field as name. I want only 10 records. out of which 9 records give me field and its count. but i want to show 10 record as "Others" with all remaining fields with count. This is something like wrapping records.
Something like below will be table contents.
emp_id | designation
1 | software Engg.
2 | software Engg.
3 | Project Manager
not less than 10 designation.
And I want to show first 10 records as
Software Engineers 20
Project Manager 5
....
....
....
Others 50
Is there any way to make SQL Query for mysql db. So that it will be fast and save time in application level where I am adding up record counts for "Others". Or Suggest me how I can make it possible in effective way.
Try this:
SELECT IF(rowNum <= 9, designation, 'Other') designation, SUM(cnt)
FROM (SELECT designation, COUNT(*) cnt, (#row := #row + 1) rowNum
FROM contents, (SELECT #row := 0) dm
GROUP BY designation
ORDER BY designation
) d
GROUP BY IF(rowNum <= 9, designation, 'Other')
Change the GROUP BY and ORDER BY however you decide what 9 to show.
you can use SQL_CALC_FOUND_ROWS option in your query which will tell MySQL to count total number of rows disregarding LIMIT clause. You still need to execute a second query in order to retrieve row count, but it’s a simple query and not as complex as your query which retrieved the data.
Usage is pretty simple. In you main query you need to add SQL_CALC_FOUND_ROWS option just after SELECT and in second query you need to use FOUND_ROWS() function to get total number of rows. Queries would look like this:
SELECT SQL_CALC_FOUND_ROWS name, email FROM users WHERE name LIKE 'a%' LIMIT 10;
SELECT FOUND_ROWS();