SQL sub query return value subtractions - php

I am doing a sort based on names, for that, I am using rownum, since the sorting is according to names I am trying to fetch next and prev id according to rownum column.
I am trying to subtract subquery result near WHERE clause but its not showing any result. If I place a numeric value directly i.e 3 it will subtract properly.
I have tried typecasting the return value but it still gives me empty result set.
SELECT inner_id, first_name, rank as sort_id
FROM
(
SELECT id as inner_id, first_name, (#rownum:=#rownum+1) rank
FROM ympa_applications, (SELECT #rownum:=0) t
ORDER BY first_name ASC
) t WHERE rank = ( (SELECT DISTINCT CAST(rank AS UNSIGNED) FROM ympa_applications WHERE inner_id=132) - 1 )

Related

How to get the largest number for each item in the table MySql

How to get the largest number for each item in the table MySql
I want to have the most chosen name "name_p" everywhere "num_place"
SELECT name_p,num_place,COUNT(`id`) as couny_pla FROM selec_user GROUP BY name_p,num_place ORDER BY selec_user.num_place ASC
this result:-
But this is the result I needed
This can produce your desired result but may arbitrarily either 'e' or 'h' for num_place 3, since they are tied:
select name_p, num_place, couny_pla
from (
select name_p, num_place, row_number() over (partition by num_place order by couny_pla desc) n, count(*) couny_pla
from selec_user
group by name_p, num_place
) ranked_groups
where n=1
order by num_place;
Replace row_number() with rank() if you want all tied values returned.
fiddle

Sort table id's cut by a hyphen (PHP/MySQL)

I have a MySQL table that I would like to display in a decreasing way. The problem is that the ID is broken by a dash ... So MySQL does not understand my request.
SELECT * FROM table WHERE id ORDER BY id DESC
results
20633-18489
184945-190028
183661-188782
1575-1610
but I want this order
184945-190028
183661-188782
20633-18489
1575-1610
What is the solution in php?
What you are looking for is the REPLACE() FUNCTION
so your query would look like:
SELECT *, REPLACE(id, '-' , '') AS sortable_id WHERE id ORDER BY sortable_id DESC
In the SQL statement, we could do this:
ORDER BY id + 0 DESC
or this:
ORDER BY SUBSTRING_INDEX(id,'-',1) + 0 DESC
The "+ 0" is going to cause the string before it to be evaluated in a numeric context. That will return a number. And then the ordering will be by the numeric value.
As a demonstration
SELECT t.id
, t.id + 0 AS id0
, SUBSTRING_INDEX(t.id,'-',1)+0 AS id1
FROM ( SELECT '184945-190028' AS id
UNION ALL SELECT '183661-188782'
UNION ALL SELECT '20633-18489'
UNION ALL SELECT '1575-1610'
) t
ORDER BY t.id + 0 DESC
returns
id id0 id1
------------- ------ ------
184945-190028 184945 184945
183661-188782 183661 183661
20633-18489 20633 20633
1575-1610 1575 1575
Note: this is ordering only on the part of the id before the dash. This doesn't specify what order id values that "match" on the leading portion will be returned in. MySQL would be free to return these two in any order.
456-42
456-321
We can add more expressions to the ORDER BY clause to make the order of these deterministic.

Select most common value? [duplicate]

How can I find the most frequent value in a given column in an SQL table?
For example, for this table it should return two since it is the most frequent value:
one
two
two
three
SELECT
<column_name>,
COUNT(<column_name>) AS `value_occurrence`
FROM
<my_table>
GROUP BY
<column_name>
ORDER BY
`value_occurrence` DESC
LIMIT 1;
Replace <column_name> and <my_table>. Increase 1 if you want to see the N most common values of the column.
Try something like:
SELECT `column`
FROM `your_table`
GROUP BY `column`
ORDER BY COUNT(*) DESC
LIMIT 1;
Let us consider table name as tblperson and column name as city. I want to retrieve the most repeated city from the city column:
select city,count(*) as nor from tblperson
group by city
having count(*) =(select max(nor) from
(select city,count(*) as nor from tblperson group by city) tblperson)
Here nor is an alias name.
Below query seems to work good for me in SQL Server database:
select column, COUNT(column) AS MOST_FREQUENT
from TABLE_NAME
GROUP BY column
ORDER BY COUNT(column) DESC
Result:
column MOST_FREQUENT
item1 highest count
item2 second highest
item3 third higest
..
..
For use with SQL Server.
As there is no limit command support in that.
Yo can use the top 1 command to find the maximum occurring value in the particular column in this case (value)
SELECT top1
`value`,
COUNT(`value`) AS `value_occurrence`
FROM
`my_table`
GROUP BY
`value`
ORDER BY
`value_occurrence` DESC;
Assuming Table is 'SalesLT.Customer' and the Column you are trying to figure out is 'CompanyName' and AggCompanyName is an Alias.
Select CompanyName, Count(CompanyName) as AggCompanyName from SalesLT.Customer
group by CompanyName
Order By Count(CompanyName) Desc;
If you can't use LIMIT or LIMIT is not an option for your query tool. You can use "ROWNUM" instead, but you will need a sub query:
SELECT FIELD_1, ALIAS1
FROM(SELECT FIELD_1, COUNT(FIELD_1) ALIAS1
FROM TABLENAME
GROUP BY FIELD_1
ORDER BY COUNT(FIELD_1) DESC)
WHERE ROWNUM = 1
If you have an ID column and you want to find most repetitive category from another column for each ID then you can use below query,
Table:
Query:
SELECT ID, CATEGORY, COUNT(*) AS FREQ
FROM TABLE
GROUP BY 1,2
QUALIFY ROW_NUMBER() OVER(PARTITION BY ID ORDER BY FREQ DESC) = 1;
Result:
Return all most frequent rows in case of tie
Find the most frequent value in mysql,display all in case of a tie gives two possible approaches:
Scalar subquery:
SELECT
"country",
COUNT(country) AS "cnt"
FROM "Sales"
GROUP BY "country"
HAVING
COUNT("country") = (
SELECT COUNT("country") AS "cnt"
FROM "Sales"
GROUP BY "country"
ORDER BY "cnt" DESC,
LIMIT 1
)
ORDER BY "country" ASC
With the RANK window function, available since MySQL 8+:
SELECT "country", "cnt"
FROM (
SELECT
"country",
COUNT("country") AS "cnt",
RANK() OVER (ORDER BY COUNT(*) DESC) "rnk"
FROM "Sales"
GROUP BY "country"
) AS "sub"
WHERE "rnk" = 1
ORDER BY "country" ASC
This method might save a second recount compared to the first one.
RANK works by ranking all rows, such that if two rows are at the top, both get rank 1. So it basically directly solves this type of use case.
RANK is also available on SQLite and PostgreSQL, I think it might be SQL standard, not sure.
In the above queries I also sorted by country to have more deterministic results.
Tested on SQLite 3.34.0, PostgreSQL 14.3, GitHub upstream.
Most frequent for each GROUP BY group
MySQL: MySQL SELECT most frequent by group
PostgreSQL:
Get most common value for each value of another column in SQL
https://dba.stackexchange.com/questions/193307/find-most-frequent-values-for-a-given-column
SQLite: SQL query for finding the most frequent value of a grouped by value
SELECT TOP 20 WITH TIES COUNT(Counted_Column) AS Count, OtherColumn1,
OtherColumn2, OtherColumn3, OtherColumn4
FROM Table_or_View_Name
WHERE
(Date_Column >= '01/01/2023') AND
(Date_Column <= '03/01/2023') AND
(Counted_Column = 'Desired_Text')
GROUP BY OtherColumn1, OtherColumn2, OtherColumn3, OtherColumn4
ORDER BY COUNT(Counted_Column) DESC
20 can be changed to any desired number
WITH TIES allows all ties in the count to be displayed
Date range used if date/time column exists and can be modified to search a date range as desired
Counted_Column 'Desired_Text' can be modified to only count certain entries in that column
Works in INSQL for my instance
One way I like to use is:
select *<given_column>*,COUNT(*<given_column>*)as VAR1 from Table_Name
group by *<given_column>*
order by VAR1 desc
limit 1

select the 3 highest values using php mysql query

I have a table like this:
`id|value
1|2
2|8
3|5
4|6
5|10
6|7`
I need a query to pull AND sum the 3 highest values. So the correct query would pull the following:
3 highest:
5|10
2|8
6|7
Sum of 3 highest values = 25
I feel like this should be pretty simple but i'm having a tough time! Thanks for your help
SELECT SUM(Value) AS SumOfTop3Values
FROM (
SELECT Value
FROM Table
ORDER BY Value DESC
LIMIT 3
) AS sub
I think you need to wrap this in a subquery:
SELECT SUM(value) AS total FROM (
SELECT value FROM table
ORDER BY value DESC
LIMIT 3
);
To have MySQL return highest 3 values and their Sum in a 4th row, you can use (aasuming that id is the Primary Key of the table):
SELECT id, SUM(value)
FROM
( SELECT id, value
FROM TableX
ORDER BY value DESC
LIMIT 3
) AS tmp
GROUP BY id
WITH ROLLUP ;

Forward Back Records in MySQL with the same DATA in the primary

I have a table that is is sorted 1st by Reminder Date then ID
Table Looks like:
ID | remind_date
1 2011-01-23
2 2010-02-21
4 2011-04-04
5 2011-04-04
6 2009-05-04
I am using a PHP front end to move forward and back thur the records. I want to have forward and back buttons but i am running into a problem with the 2 reminder dates that are the same.
Just to note the ID's are NOT in order, they are here but in the actual database they are mixed up when sorting by reminder_date
The select statement i am using is: ($iid is the current record i am on)
SELECT id FROM myDB.reminders where remind_date > (SELECT remind_date FROM myDB.reminders where id=$iid) order by remind_date ASC LIMIT 1
So what happens when i get to the dates that are the same its skips over one because its asking for remind_date >.
If i use remind_date >= it returns the current record. My solution was then to use limit 2 and check via PHP to if the 1st record = my current ID, if it did use the next one. but what it there are 3 dates the same or 4 etc..
I also thought about using the ID field but since they are out of order i can't add in a ID > $iid.
Any ideas? it works great except for 2 dates that are the same.
You might be able to use this:
SELECT ID, remind_date
FROM
(
SELECT #prev_id := -1
) AS vars
STRAIGHT_JOIN
(
SELECT
ID,
remind_date,
#prev_id AS prev_id,
#prev_id := id
FROM myDB.reminders
ORDER BY remind_date, ID
) T1
WHERE prev_id = $iid
Here is a test of the above with your test data from your comment:
CREATE TABLE Table1 (ID INT NOT NULL, remind_date DATE NOT NULL);
INSERT INTO Table1 (ID, remind_date) VALUES
(45, '2011-01-14'),
(23, '2011-01-22'),
(48, '2011-01-23'),
(25, '2011-01-23'),
(63, '2011-02-19');
SELECT ID, remind_date
FROM
(
SELECT #prev_id := -1
) AS vars
STRAIGHT_JOIN
(
SELECT
ID,
remind_date,
#prev_id AS prev_id,
#prev_id := id
FROM table1
ORDER BY remind_date, ID
) T1
WHERE prev_id = 25
Result:
ID remind_date
48 2011-01-23
add a condition WHERE ID<>MY_LAST_ID. This can not work with triple and more same dates, so you can collect already taken ID's to array like (4,5,6) - see array_push(), implode it with "," to convert to a string (let's call it YOUR_IDS_STRING) and add to your query:
WHERE id NOT IN( YOUR_IDS_STRING )
And after each query make check, does date has changed and if it does - you can unset your array and start from begining (this is not neccesary, but gives you more performance, because YOUR_ID_STRING will be only that long as is need).
If your page is refreshing between queries, maybe try to push YOUR_ID_STRING in session variable, _GET or cookies, and simply concat next id's by operator .=
I used the code provided by Mark Byers and with small changes I adapted it to navigate in opposite directions (and to pass other columns too, not only the date and ID):
$results = $mysqli->query("SELECT * FROM (SELECT #prev_id := -1) AS vars STRAIGHT_JOIN (SELECT *, #prev_id AS prev_id, #prev_id := ID FROM my_table ORDER BY data, ID) T1 WHERE prev_id = ".$ID);
$results = $mysqli->query("SELECT * FROM (SELECT #next_id := 1) AS vars STRAIGHT_JOIN (SELECT *, #next_id AS next_id, #next_id := ID FROM my_table ORDER BY data DESC, ID DESC) T1 WHERE next_id = ".$ID);
I tested it on duplicate dates and it navigates well trough a list of records displayed with:
$results = $mysqli->query("SELECT * FROM my_table ORDER BY data DESC, ID DESC");

Categories