sql 'select max' query - sql

I have a table with name "table_name" approximately like this
+----+-----------+
| ID | title |
| 1 | title 1 |
| 2 | title 2 |
| ...| ......... |
| ...| ......... |
| n | title n |
+----+-----------+.
And I need a query that returns this result
+------+-----------+
| n+1 | title 1 |
| n+1 | title 2 |
| ... | ......... |
| ... | ......... |
| n+1 | title n |
+------+-----------+
(n+1 is select max(ID) from table_name)
how can I do that?

Simply add a sub-query to the select list:
select (select max(ID) + 1 from tablename), title
from tablename

Window function
SELECT MAX(ID) OVER() + 1, title
FROM table_name

You can select this max ID to a variable, and then simply use it in your select:
DECLARE #maxId INT = (SELECT MAX(ID) FROM [dbo].[table1]);
SELECT #maxId, t.title, t.column2, t.column3 ... from [dbo].[table2] t

For Mysql
select (1+max(ID)) as ID ,title
from table_name;

Related

How do I select rows with maximum value?

Given this table I want to retrieve for each different url the row with the maximum count. For this table the output should be: 'dell.html' 3, 'lenovo.html' 4, 'toshiba.html' 5
+----------------+-------+
| url | count |
+----------------+-------+
| 'dell.html' | 1 |
| 'dell.html' | 2 |
| 'dell.html' | 3 |
| 'lenovo.html' | 1 |
| 'lenovo.html' | 2 |
| 'lenovo.html' | 3 |
| 'lenovo.html' | 4 |
| 'toshiba.html' | 1 |
| 'toshiba.html' | 2 |
| 'toshiba.html' | 3 |
| 'toshiba.html' | 4 |
| 'toshiba.html' | 5 |
+----------------+-------+
What SQL query do I need to write to do this?
Try to use this query:
select url, max(count) as count
from table_name
group by url;
use aggregate function
select max(count) ,url from table_name group by url
From your comments it seems you need corelated subquery
select t1.* from table_name t1
where t1.count = (select max(count) from table_name t2 where t2.url=t1.url
)
If row_number support on yours sqllite version
then you can write query like below
select * from
(
select *,row_number() over(partition by url order by count desc) rn
from table_name
) a where a.rn=1

Getting the last updated name

I am having a table having records like this:
+------+------+
| ID | name |
+------+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | A |
| 5 | B |
| 6 | A |
| 7 | A |
| 8 | A |
+------+------+
I need to get value of A after it was last updated from a different value, for example here it would be the row at ID 6.
Try this query (MySQL syntax):
select min(ID)
from records
where name = 'A'
and ID >=
(
select max(ID)
from records
where name <> 'A'
);
Illustration:
select * from records;
+------+------+
| ID | name |
+------+------+
| 1 | A |
| 2 | B |
| 3 | C |
| 4 | A |
| 5 | B |
| 6 | A |
| 7 | A |
| 8 | A |
+------+------+
-- run query:
+---------+
| min(ID) |
+---------+
| 6 |
+---------+
Using the Lag function...
SELECT Max([ID])
FROM (SELECT [name], [ID],
Lag([name]) OVER (ORDER BY [ID]) AS PrvVal
FROM tablename) tbl
WHERE [name] = 'A'
AND prvval <> 'A'
Online Demo: http://www.sqlfiddle.com/#!18/a55eb/2/0
If you want to get the whole row, you can do this...
SELECT Top 1 *
FROM (SELECT [name], [ID],
Lag([name]) OVER (ORDER BY [ID]) AS PrvVal
FROM tablename) tbl
WHERE [name] = 'A' AND prvval <> 'A'
ORDER BY [ID] DESC
Online Demo: http://www.sqlfiddle.com/#!18/a55eb/22/0
The ANSI SQL below uses a self-join on the previous id.
And the where-clause gets those with a name that's different from the previous.
select max(t1.ID) as ID
from YourTable as t1
left join YourTable as t2 on t1.ID = t2.ID+1
where (t1.name <> t2.name or t2.name is null)
and t1.name = 'A';
It should work on most RDBMS, including MS Sql Server.
Note that with the ID+1 that there's an assumption that are no gaps between the ID's.

Creating New Table by select query with sequental column names

I have a table that contains column names like this;
+--------------------------------------------------------------------+-----------+
| BankTable | |
+--------------------------------------------------------------------+-----------+
| Id | BANK1 | BANK2 | BRANCH1 | BRANCH2 | IBAN1 | IBAN2 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
| 1 | BANK1_ID1 | BANK2_ID1 | BRANCH1_ID1 | BRANCH2_ID1 | IBAN1_ID1 | IBAN2_ID1 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
| 2 | BANK1_ID2 | BANK2_ID2 | BRANCH1_ID2 | BRANCH1_ID2 | IBAN1_ID2 | IBAN2_ID2 |
+----+-----------+-----------+-------------+-------------+-----------+-----------+
How can i write a query that returns the result like this;
+------------------------------------------+
| BANK |
+------------------------------------------+
| ID | BANK | BRANCH | IBAN |
+----+-----------+-------------+-----------+
| 1 | BANK1_ID1 | BRANCH1_ID1 | IBAN1_ID1 |
+----+-----------+-------------+-----------+
| 2 | BANK2_ID2 | BRANCH1_ID2 | IBAN2_ID2 |
+----+-----------+-------------+-----------+
P.s: I am writing select query by Id column. BTW query result contains one row every time.
Any help appreciated.
SOLUTION
I don't know if it's good approach but i solved this by based on #Giorgos Betsos answer. Here is how i fixed this problem.
SELECT BANK, BRANCH, IBAN
FROM (
SELECT BANK1, BANK2, BRANCH1, BRANCH2, IBAN1, IBAN2
FROM BankTable
WHERE ID = your_id_here
) AS src
UNPIVOT (
BANK FOR Col IN(BANK1, BANK2)
) AS unpvt1
UNPIVOT (
BRANCH FOR Col1 IN(BRANCH1, BRANCH2)
) AS unpvt2
UNPIVOT (
IBAN FOR Col2 IN(IBAN1, IBAN2)
) AS unpvt3
WHERE RIGHT(Col, 1) = RIGHT(Col1, 1)
AND RIGHT(Col, 1) = RIGHT(Col2, 1)
You can use UNPIVOT for this:
SELECT Bank
FROM (
SELECT Id, BANK1, BANK2, BANK3, BANK4, BANK5
FROM BankTable
WHERE id = 1) AS src
UNPIVOT (
Bank FOR Col IN([BANK1], [BANK2], [BANK3], [BANK4], [BANK5])) AS unpvt
Demo here
If number of column is more, then you can use a dynamic sql query as below:
Query
declare #sql as varchar(max);
select #sql =stuff(
(select 'union all select [' + column_name + '] as Bank
from BankTable where Id = 1 '
from information_schema.columns
where table_name = 'BankTable'
and column_name like 'BANK[0-9]%'
for xml path('')), 1, 9, '');
execute(#sql);
Result
+-----------+
| Bank |
+-----------+
| BANK1_ID1 |
| BANK2_ID1 |
| BANK3_ID1 |
| BANK4_ID1 |
| BANK5_ID1 |
+-----------+

Count rows grouped by condition in SQL

We have a table like this:
+----+--------+
| Id | ItemId |
+----+--------+
| 1 | 1100 |
| 1 | 1101 |
| 1 | 1102 |
| 2 | 2001 |
| 2 | 2002 |
| 3 | 1101 |
+----+--------+
We want to count how many items each guy has, and show the guys with 2 items or more. Like this:
+----+-----------+
| Id | ItemCount |
+----+-----------+
| 1 | 3 |
| 2 | 2 |
+----+-----------+
We didn't count the guy with Id = 3 because he's got only 1 item.
How can we do this in SQL?
SELECT id, COUNT(itemId) AS ItemCount
FROM YourTable
GROUP BY id
HAVING COUNT(itemId) > 1
Use this query
SELECT *
FROM (
SELECT COUNT(ItemId ) AS COUNT, Id FROM ITEM
GROUP BY Id
)
my_select
WHERE COUNT>1
SELECT id,
count(1)
FROM YOUR_TABLE
GROUP BY id
HAVING count(1) > 1;
select Id, count(ItemId) as ItemCount
from table_name
group by Id
having ItemCount > 1

... where count(col) > 1

I have a table like this:
+-----+-----+-------+
| id | fk | value |
+-----+-----+-------+
| 0 | 1 | peter |
| 1 | 1 | josh |
| 3 | 2 | marc |
| ... | ... | ... |
I'd like now to get all entries which have more than one value.
The expected result would be:
+-----+-------+
| fk | count |
+-----+-------+
| 1 | 2 |
| ... | ... |
I tried to achieve that like this:
select fk, count(value) from table where count(value) > 1;
But Oracle didn't like it.
So I tried this...
select * from (
select fk, count(value) as cnt from table
) where cnt > 1;
...with no success.
Any ideas?
Use the having clause for comparing aggregates.
Also, you need to group by what you're aggregating against for the query to work correctly. The following is a start, but since you're missing a group by clause still it won't quite work. What exactly are you trying to count?
select fk, count(value)
from table
group by fk
having count(value) > 1;