how to number the datas from mysql - mysql

This is a doubt on mysql select query
let me axplain my doubt with a simple example
consider this is my query
SELECT dbCountry from tableCountry
tableCountry has fields dbCuntryId, dbCountry and dbState
I have the result as
dbCountry
india
america
england
kenya
pakisthan
I need the result as
1 india
2 america
3 england
4 kenya
5 pakisthan
the numbers 12345 must be generated with the increase in data and it is not an autoincrement id.
How can i get it
is it something like loop

You can try this:
SELECT dbCountry,
(SELECT COUNT(*) FROM tableCountry t2 WHERE t2.dbCountry <= t1.dbCountry)
AS RowNum
FROM tableCountry t1
ORDER BY dbCountry

The following should do what you need. It uses a variable that is incremented and returned for each row:
SELECT
#rownum:=#rownum+1 number,
c.dbCountry
FROM
tableCountry c,
(SELECT #rownum:=0) r
If you want the result to always be in the same order you'll need to add an order by constraint to the query, for example, ORDER BY c.dbCountry to order by the country name.

Related

Distinct based on one row with multiple non-aggregate columns selected

I'm trying to run a query that returns distinct AddressIDs.
The row to be retuned for each AddressID should be the one with the latest ReadDate.
I also want to return the value from (non-aggregate) columns PhoneNumber, SomeCode, and Country for the given records.
There are similar questions on here to mine, but nothing seems to suit my exact situation. I've tried different subqueries and making the other columns aggregates, but I can't seem to get the results I desire.
Say the base of the query like:
select cr.AddressID, cr.ReadDate, in.PhoneNumber, in.SomeCode, in.Country
from CustomerReadings cr, in.CustomerInfo
where cr.AddressID = in.AddressID
For example, if I have a table that looks like:
AddressID ReadDate PhoneNumber SomeCode Country
1005 01/01/1997 5556565 GHS Canada
1005 05/06/2006 5556753 ROT USA
1005 08/12/2018 5552345 JKR USA
2007 02/05/2012 5558746 MSC Canada
2007 12/07/2018 5552345 RRE France
4000 03/01/1999 5552345 RRE France
4000 09/05/2007 5551243 MSR USA
I want the query results to look like:
AddressID ReadDate PhoneNumber SomeCode Country
1005 08/12/2018 5552345 JKR USA
2007 12/07/2018 5552345 RRE France
4000 09/05/2007 5551243 MSR USA
If anything is unclear please let me know and I'll update my question accordingly.
In the case of 1 table as you used in your answer example, the code works.
But when I bring in another table, I no longer get just one distinct AddressID back, eg:
select (or select distinct)
cr.AddressID, cr.ReadDate, in.PhoneNumber, in.SomeCode, in.Country
from
CustomerReadings cr,
CustomerInfo in
where
cr.AddressID = in.AddressID
and cr.ReadDate =
(select max(cr2.ReadDate)
from CustomerReadings cr2
where cr2.AddressID = cr.AddressID)
order by
2 desc,
1;
There should be questions that are very similar. I use a correlated subquery:
select t.*
from t
where t.readdate = (select max(t2.readdate) from t t2 where t2.addressid = t.addressid);
You need correlated subquery :
select t.*
from table t
where readdate = (select max(t1.readdate) from table t1 where t1.addressid = t.addressid);
If you are working with latest version of MySQL, then row_number() would helpful :
select t.*
from (select t.*,
row_number() over (partition by addressid order by readdate desc) as seq
from table t
) t
where seq = 1;
However, if the readdate has ties, then row_number() would no longer help use dense_rank() instead.

How do I get the top 4 results of a column in mysql query?

I'm not very experienced in mySQL, but
I have a SQL query table where I need to return:
Salary_amount_1
Salary_amount_2
Salary_amount_3
Salary_amount_4
(not relevant below)
Salary_Date_1
Salary_Date_2
Salary_Date_3
Salary_Date_4
I've got 4 seperate columns for each salary amount to select into in the destination table we're inserting into, and a column called Salary with 15+ different amounts in the source table we're selecting from, but how do I specifically select the first salary for column 1, second for column two, third for three and fourth salary for column four?
Thanks in advance
What I have tried:
This is what I have (and isn't working for me yet)
Select
ID,
Bank Name,
UserName,
min(details_Credit) as Salary_Amount_1,
max(details_Credit) as Salary_Amount_2,
Case
when details_Credit = min(details_Credit)
and details_Credit > min(details_Credit)
end Salary_Amount_3,
????? as Salary_Amount_4,
any help would be appreciated. thank you
Sample Data:
Salary| SalaryDate| UserName| BankName
=====================================
1000 |2013-05-23 |MikeRoss |NetBank
1500 |2013-06-23 |MikeRoss |NetBank
2000 |2013-07-22 |MikeRoss |NetBank
1000 |2013-08-15 |MikeRoss |NetBank
Desired Results:
Username|Bank|Salary1|Salary2|Salary3|Salary4|Date1|Date2|Date3|Date4
MikeRoss|Netbank|1000|1500|2000|1000|2013-05-23| 2013-06-23| 2013-06-22| 2013-08-15
I think what you need is something like this:
Select ID, Bank Name, UserName, Salary_amount_1 from yourTable
order by Salary_amount_1 limit 1
Union
Select ID, Bank Name, UserName, Salary_amount_2 from yourTable
order by Salary_amount_2 limit 1,1
Union
Select ID, Bank Name, UserName, Salary_amount_3 from yourTable
order by Salary_amount_3 limit 2,1
Union
Select ID, Bank Name, UserName, Salary_amount_4 from yourTable
order by Salary_amount_4 limit 3,1
This will perform 4 queries, each returning one of your desired results.
limit offset, rowcount will take the first rowcount rows after skipping offset rows.
That said, I strongly advice you to check the structure of your table.
I used Left Join instead to resolve this incase anyone is wondering. i.e
left join DB.Table_Name as a1 on a1.ID=a.ID and a1.TransactionDate=a0.maxDate
left join DB.Table_Name as a2 on a2.ID=a1.ID and a2.TransactionDate<a1.TransactionDate
left join DB.Table_Name as a3 on a3.ID=a2.ID and a3.TransactionDate<a2.TransactionDate
etc

SQL select attribute tupel in reversed order (not order by)

I have a mysql table with entries of my driver's logbook. In the table there are two columns: start_place and end_place. Sometimes it's possible, that end_place is equal to start_place (i think that sounds logical).
Now I wan't to select the entries of the table which occour as tupel (x,y), but not as (y,x).
Example:
id | start_place | end_place
-----------------------------------
0 | New York | San Francisco
-----------------------------------
1 | San Francisco | New York
The row with the id 1 is a duplicate of id 0 in reversed order and should not be part of the result.
Does someone has an idea? Several times I tried with subselects or where conditions like (x,y) != (y,x) but that doesn't work.
This can be done with least and greatest functions with a group by.
select least(start_place,end_place), greatest(start_place,end_place)
from tbl
group by least(start_place,end_place), greatest(start_place,end_place)
having count(*) = 1
To retrieve such rows with other columns, use
select *
from tbl
where (least(start_place,end_place), greatest(start_place,end_place))
in (select least(start_place,end_place), greatest(start_place,end_place)
from tbl
group by least(start_place,end_place), greatest(start_place,end_place)
having count(*) = 1
)
Use LEAST, GREATEST and DISTINCT to get distinct pairs:
select distinct
least(start_place, end_place) as place1,
greatest(start_place, end_place) as place2
from mytable;

Select distinct column along with some other columns in MySQL

I can't seem to find a suitable solution for the following (probably an age old) problem so hoping someone can shed some light. I need to return 1 distinct column along with other non distinct columns in mySQL.
I have the following table in mySQL:
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
3 James Barbados 3 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
6 Declan Trinidad 3 WI
I would like SQL statement to return the DISTINCT name along with the destination, rating based on country.
id name destination rating country
----------------------------------------------------
1 James Barbados 5 WI
2 Andrew Antigua 6 WI
4 Declan Trinidad 2 WI
5 Steve Barbados 4 WI
As you can see, James and Declan have different ratings, but the same name, so they are returned only once.
The following query returns all rows because the ratings are different. Is there anyway I can return the above result set?
SELECT (distinct name), destination, rating
FROM table
WHERE country = 'WI'
ORDER BY id
Using a subquery, you can get the highest id for each name, then select the rest of the rows based on that:
SELECT * FROM table
WHERE id IN (
SELECT MAX(id) FROM table GROUP BY name
)
If you'd prefer, use MIN(id) to get the first record for each name instead of the last.
It can also be done with an INNER JOIN against the subquery. For this purpose the performance should be similar, and sometimes you need to join on two columns from the subquery.
SELECT
table.*
FROM
table
INNER JOIN (
SELECT MAX(id) AS id FROM table GROUP BY name
) maxid ON table.id = maxid.id
The problem is that distinct works across the entire return set and not just the first field. Otherwise MySQL wouldn't know what record to return. So, you want to have some sort of group function on rating, whether MAX, MIN, GROUP_CONCAT, AVG, or several other functions.
Michael has already posted a good answer, so I'm not going to re-write the query.
I agree with #rcdmk . Using a DEPENDENT subquery can kill performance, GROUP BY seems more suitable provided that you have already INDEXed the country field and only a few rows will reach the server. Rewriting the query giben by #rcdmk , I added the ORDER BY NULL clause to suppress the implicit ordering by GROUP BY, to make it a little faster:
SELECT MIN(id) as id, name, destination as rating, country
FROM table WHERE country = 'WI'
GROUP BY name, destination ORDER BY NULL
You can do a GROUP BY clause:
SELECT MIN(id) AS id, name, destination, AVG(rating) AS rating, country
FROM TABLE_NAME
GROUP BY name, destination, country
This query would perform better in large datasets than the subquery alternatives and it can be easier to read as well.

SQL Selecting multiple columns based on max value in one column

OK so I have looked theough the other solutions an no help. So here is what I am trying to do.
I need to select the row with multiple columns where the value in one column is the max value.
here is sample data
orderfileid item number item cost warehouse
1 1234 3.45 ATL
1 2345 1.67 DFW
3 2345 2.45 NYY
3 678 2.4 ORD
2 1234 1.67 DFW
I need to select the entire row where the orderfileid is the max for each unique item number
the returned dataset should look like
orderfileid item number item cost warehouse
2 1234 1.67 DFW
3 2345 2.45 NYY
3 6789 2.4 ORD
I think i tried every combination of select max(orderfileid) i can think of
Any help would be appriciated.
thanks
You need to find your MAX values in a subquery, then use those results to join to your main table to retrieve the columns.
SELECT t.OrderFileId, t.ItemNumber, t.ItemCost, t.Warehouse
FROM YourTable t
INNER JOIN (SELECT ItemNumber, MAX(OrderFileId) AS MaxOrderId
FROM YourTable
GROUP BY ItemNumber) q
ON t.ItemNumber = q.ItemNumber
AND t.OrderFileId = q.MaxOrderId
select
t.*
from
table t
inner join (
select itemnumber, max(orderfileid) maxof
from table
group by itemnumber
) m on t.itemnumber = m.itemnumber
and t.orderfileid = m.maxof
I wouldn't even use Max. Just combine GROUP BY and ORDER BY
SELECT * FROM orders GROUP BY item_number ORDER BY orderfileid DESC
then for minimum just change to ASC
Try
SELECT * FROM `TABLE` WHERE orderfileid=(select max(orderfileid) from TABLE)
you can refer to a similar problem on how to group things using partitioning and picking one per partition in mysql
Deleting Rows: No Single Member Has More Than x Records
this is something similar to doing rank over in Oracle. my previous post was for oracle. my bad..
I think what you are looking for is the "Having" clause. Take a look at this.
select orderfileid, max(itemnumber), itemcost, warehouse from MyTable group by orderfileid having max(itemnumber) ;