Suppose I have a table like this:
+------------+-----------+--+--+--+
| First name | Last name | | | |
+------------+-----------+--+--+--+
| First 1 | Last 1 | | | |
+------------+-----------+--+--+--+
| First 2 | Last 2 | | | |
+------------+-----------+--+--+--+
| First 3 | Last 3 | | | |
+------------+-----------+--+--+--+
How would I create a query that displays the data like this
+---------+--+--+--+--+
| Name | | | | |
+---------+--+--+--+--+
| First 1 | | | | |
+---------+--+--+--+--+
| Last 1 | | | | |
+---------+--+--+--+--+
| First 2 | | | | |
+---------+--+--+--+--+
| Last 2 | | | | |
+---------+--+--+--+--+
| First 3 | | | | |
+---------+--+--+--+--+
| Last 3 | | | | |
+---------+--+--+--+--+
with fnames as
(
select fname Name, ROW_NUMBER() over (order by fname,lname) rank from myTable
), lnames as
(
select lname Name, 0.5 + ROW_NUMBER() over (order by fname,lname) rank from myTable
),
merged as
(
(select * from fnames) union (select * from lnames)
)
select Name from merged order by rank
Assuming every other column is repeated, and there is no ID column initially
WITH T (FirstName, LastName,Ranking)
AS
(
SELECT
FirstName,
LastName,
2* ROW_NUMBER() OVER(ORDER First Name, Last Name) AS Ranking --, other columns
FROM TBL
)
SELECT Name --, other columns
FROM
(
SELECT FirstName AS Name,
Ranking-1 as r--, other columns
FROM T
UNION
SELECT LastName AS Name,
Ranking as r--, other columns
FROM T
) Tbl ORDER BY r ASC
Related
I have a dataset looks like this
| Country | id |
-------------------
| a | 5 |
| a | 1 |
| a | 2 |
| b | 1 |
| b | 5 |
| b | 4 |
| b | 7 |
| c | 5 |
| c | 1 |
| c | 2 |
and i need a query which returns 2 random values from where country in ('a', 'c'):
| Country | id |
------------------
| a | 2 | -- Two random rows from Country = 'a'
| a | 1 |
| c | 1 |
| c | 5 | --Two random rows from Country = 'c'
This should work:
select Country, id from
(select Country,
id,
row_number() over(partition by Country order by rand()) as rn
from table_name
) t
where Country in ('a', 'c') and rn <= 2
Replace rand() with random() if you're using Postgres or newid() in SQL Server.
Let's say I have the following table:
| sku | id | value | count |
|-----|----|-------|-------|
| A | 1 | 1 | 2 |
| A | 1 | 2 | 2 |
| A | 3 | 3 | 3 |
I want to select rows that don't have the same count for the same id. So my desired outcome is:
| sku | id | value | count |
|-----|----|-------|-------|
| A | 3 | 3 | 3 |
I need something that works with Postgres 10
A simple method is window functions:
select t.*
from (select t.*, count(*) over (partition by sku, id) as cnt
from t
) t
where cnt = 1;
This assumes you really mean the sku/id combination.
I'd like to sort column A based on a column B which contains previous values from column A.
This is what I have:
+----+----------+----------+
| ID | A | B |
+----+----------+----------+
| 1 | 17209061 | |
| 2 | 53199491 | 51249612 |
| 3 | 61249612 | 17209061 |
| 4 | 51249612 | 61249612 |
+----+----------+----------+
And this is what I'd like to have:
+----+----------+----------+----------+
| ID | A | B | Sort_seq |
+----+----------+----------+----------+
| 1 | 17209061 | | 1 |
| 3 | 61249612 | 17209061 | 2 |
| 4 | 51249612 | 61249612 | 3 |
| 2 | 53199491 | 51249612 | 4 |
+----+----------+----------+----------+
I'm sure there's an easy way to do this. Do you have any ideas?
Thank you!
Just use lag() in order by:
order by lag(a) over (order by id) nulls first
If you want a column, then:
select t.id, t.a, t.prev_a,
row_number() over (order by prev_a nulls first)
from (select t.*, lag(a) over (order by id) as prev_a
from t
) t;
I need to add an order column to following table:
| Id | DepId | Name |
|----|-------|-------|
| 1 | 1 | Bill |
| 2 | 1 | Joe |
| 3 | 2 | Jack |
| 4 | 1 | Jill |
It should become:
| Id | DepId | Name | Order |
|----| ------|-------|-------|
| 1 | 1 | Bill | 1 |
| 2 | 1 | Joe | 2 |
| 3 | 2 | Jack | 1 |
| 4 | 1 | Jill | 3 |
I know let's use order by id, and don't worry about such order column, but in this case the difficulty increases when entries are shifted.
You're looking for the ROW_NUMBER() OLAP function...
Instead of actually adding the column to the physical table, you could (should) create a view:
create view myview as
(select Id, DepId, Name
, ROW_NUMBER() OVER(PARTITION BY DepId ORDER BY DepId, ID) as OrderNbr
from mytable
)
I have been trying to get this to work with some row_number, group by, top, sort of things, but I am missing some fundamental concept. I have a table like so:
+-------+-------+-------+
| name | ord | f_id |
+-------+-------+-------+
| a | 1 | 2 |
| b | 5 | 2 |
| c | 6 | 2 |
| d | 2 | 1 |
| e | 4 | 1 |
| a | 2 | 3 |
| c | 50 | 4 |
+-------+-------+-------+
And my desired output would be:
+-------+---------+--------+-------+
| f_id | ord_n | ord | name |
+-------+---------+--------+-------+
| 2 | 1 | 1 | a |
| 2 | 2 | 5 | b |
| 1 | 1 | 2 | d |
| 1 | 2 | 4 | e |
| 3 | 1 | 2 | a |
| 4 | 1 | 50 | c |
+-------+---------+--------+-------+
Where data is ordered by the ord value, and only up to two results per f_id. Should I be working on a Stored Procedure for this or can I just do it with SQL? I have experimented with some select TOP subqueries, but nothing has even come close..
Here are some statements to create the test table:
create table help(name varchar(255),ord tinyint,f_id tinyint);
insert into help values
('a',1,2),
('b',5,2),
('c',6,2),
('d',2,1),
('e',4,1),
('a',2,3),
('c',50,4);
You may use Rank or DENSE_RANK functions.
select A.name, A.ord_n, A.ord , A.f_id from
(
select
RANK() OVER (partition by f_id ORDER BY ord asc) AS "Rank",
ROW_NUMBER() OVER (partition by f_id ORDER BY ord asc) AS "ord_n",
help.*
from help
) A where A.rank <= 2
Sqlfiddle demo