I have table like this
id buildingId order title
--------------------------
1 2 null test1
2 2 null test2
3 2 null test3
4 3 null test4
5 3 null test5
6 5 null test6
I need calculate order value for every row. I need after execute sql query get this table
id buildingId order title
1 2 0 test1
2 2 1 test2
3 2 2 test3
4 3 0 test4
5 3 1 test5
6 5 0 test6
How can I do that?
WITH recordList
AS
(
SELECT ID, buildingID, [order], title,
ROW_NUMBER() OVER (PARTITION BY buildingID
ORDER BY ID) rn
FROM tableName
)
UPDATE recordList
SET [order] = rn - 1
SQLFiddle Demo
Related
I have a table that I need to assign a number sequence to, then have the number sequence restarts to 1 again based on a value in another column.
Here is my table:
Date
Name
Indicator
01/12/2022
Test1
1
02/12/2022
Test2
NULL
03/12/2022
Test3
NULL
04/12/2022
Test4
NULL
05/12/2022
Test5
1
06/12/2022
Test6
NULL
07/12/2022
Test7
1
08/12/2022
Test8
NULL
What I need is to add an "Instance" column to the end, this column simply continues the number sequence until it hits a row with a 1 in the "Indicator" column again then it resets.
So my desired outcome would be:
Date
Name
Indicator
Instance
01/12/2022
Test1
1
1
02/12/2022
Test2
NULL
2
03/12/2022
Test3
NULL
3
04/12/2022
Test4
NULL
4
05/12/2022
Test5
1
1
06/12/2022
Test6
NULL
2
07/12/2022
Test7
1
1
08/12/2022
Test8
NULL
2
I've tried playing aound with DENSE_RANK() over (Order by Date)
But I understandly end up with this:
Date
Name
Indicator
Instance
01/12/2022
Test1
1
1
02/12/2022
Test2
NULL
2
03/12/2022
Test3
NULL
3
04/12/2022
Test4
NULL
4
05/12/2022
Test5
1
1
06/12/2022
Test6
NULL
6
07/12/2022
Test7
1
1
08/12/2022
Test8
NULL
8
The sequence carries on, it does not reset at the 1 (in the indicator column).
You can do:
select x.*, row_number() over(partition by g order by date) as instance
from (select t.*, sum(indicator) over(order by date) as g from t) x
Result:
Date Name Indicator g instance
----------- ------ ---------- -- --------
2022-01-12 Test1 1 1 1
2022-02-12 Test2 null 1 2
2022-03-12 Test3 null 1 3
2022-04-12 Test4 null 1 4
2022-05-12 Test5 1 2 1
2022-06-12 Test6 null 2 2
2022-07-12 Test7 1 3 1
2022-08-12 Test8 null 3 2
See running example at db<>fiddle.
I have this table with the following records:
table1
id ele_id_1 ele_val ele_id_2
1 2 123 1
1 1 abc 1
1 4 xyz 2
1 4 456 1
2 5 22 1
2 4 344 1
2 3 6 1
2 2 Test Name 1
2 1 Hello 1
I am trying to add position for each id when ele_id_1 and ele_id_2 is order by ASC.
Here is the output:
id ele_id_1 ele_val ele_id_2 position
1 2 123 1 2
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 3
2 5 22 1 5
2 4 344 1 4
2 3 6 1 3
2 2 Test Name 1 2
2 1 Hello 1 1
I have 34 million rows in table1, so would like to use an efficient way of doing this.
Any idea on how I can add position with values?
I think you want row_number() used like this:
select row_number() over (partition by id
order by ele_id_1, ele_id_2
) as position
Oracle can use an index for this, on (id, ele_id_1, ele_id_2).
I should note that for your example data order by ele_id_1, ele_id_2 and order by ele_id_2, ele_id_1 produce the same result. Your question suggests that you want the first.
So, you would get
id ele_id_1 ele_val ele_id_2 position
1 1 123 2 2
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 3
Rather than:
id ele_id_1 ele_val ele_id_2 position
1 1 123 2 3
1 1 abc 1 1
1 4 xyz 2 4
1 4 456 1 2
EDIT:
If you want to update the data, then merge is probably the best approach.
MERGE INTO <yourtable> dest
USING (select t.*,
row_number() over (partition by id
order by ele_id_1, ele_id_2
) as new_position
from <yourtable> t
) src
ON dest.id = src.id AND
dest.ele_id_1 = src.ele_id_1 AND
dest.ele_id_2 = src.ele_id_2
WHEN MATCHED THEN UPDATE
SET desc.postition = src.new_position;
Note that updating all the rows in a table is an expensive operation. Truncating the table and recreating it might be easier:
create table temp_t as
select t.*,
row_number() over (partition by id
order by ele_id_1, ele_id_2
) as new_position
from t;
truncate table t;
insert into t ( . . . )
select . . . -- all columns but position
from temp_t;
However, be very careful if you truncate the table. Be sure to back it up first!
i have 3 tables
Posts_comments
comment_id, comment_post_id, comment_value, comment_time comment_user_id
1 1 test DATETIME 1
2 1 test2 DATETIME 2
3 2 test3 DATETIME 2
4 1 test4 DATETIME 2
5 1 test5 DATETIME 1
6 1 test6 DATETIME 2
Members
member_id member_fistname member_lastname member_slug
1 John Doe john-doe
2 Test User test-user
Members_photos
member_user_id member_photo_type member_photo_name
1 2 test.jpg
2 2 test2.jpg
And i have sql
SELECT
posts_comments.comment_id,
posts_comments.comment_post_id,
posts_comments.comment_value,
posts_comments.comment_time,
members.member_id,
members.member_lastname,
members.member_fistname,
members_photos.member_photo_name
FROM
posts_comments
LEFT JOIN
members ON posts_comments.comment_user_id = members.member_id
LEFT JOIN
members_photos ON members.member_id = members_photos.member_user_id
AND
members_photos.member_photo_type = 2
ORDER BY
posts_comments.comment_time DESC
LIMIT 4
But this query show only last 4 comments independently from the comment_post_id.
In this case i want to show last 4 comments for every comment_post_id (in this example: 4 comments where comment_post_id = 1 and 1 comment where comment_post_id = 2).
I hope I wrote it clearly enough.
Thx 4 help :)
use row_number() window function if it mariadb version MariaDB 10.2.0 or greatere
select a.* from ( SELECT
posts_comments.comment_id,
posts_comments.comment_post_id,
posts_comments.comment_value,
posts_comments.comment_time,
members.member_id,
members.member_lastname,
members.member_fistname,
members_photos.member_photo_name,
row_number()over(partition by posts_comments.comment_post_id order by posts_comments.comment_time desc) rn
FROM
posts_comments
LEFT JOIN
members ON posts_comments.comment_user_id = members.member_id
LEFT JOIN
members_photos ON members.member_id = members_photos.member_user_id
AND
members_photos.member_photo_type = 2
) a where a.rn<=4
Looking for a SQL solution to the following problem
Return USER and NUMBER combination WHERE PRIORITY = MIN(PRIORITY) [NULL is equivalent to MAX(PRIORITY + 1)] ... in the case of ties in PRIORITY, break using lowest LINEITEM
FIELDS:
USER,
LINEITEM,
NUMBER,
PRIORITY
VALUES: ('X' signifies desired combination)
USER LINEITEM NUMBER PRIORITY
-------------------------------------
1 1 12345 NULL
1 2 23456 2
1 3 34567 1 X
2 1 9876 3
2 2 98765 1 X
2 3 12345 2
2 4 23456 1
3 1 23456 NULL X
3 2 12345 NULL
4 1 34567 NULL
4 2 45678 NULL
4 3 12345 1 X
4 4 12345 2
4 5 23456 1
Thanks in advance.
In response to PM 77-1,
My current method:
SELECT table1.user,table1.number
FROM table1
JOIN (
SELECT user,
CAST(MIN((COALESCE(priority,999) *
(10 ^ (5 - LEN(COALESCE(CAST(priority AS VARCHAR),'999'))))) +
lineitem) AS VARCHAR) AS selector
FROM table1 GROUP BY user
) AS table2
ON table1.user = table2.user
AND table1.lineitem = CAST(RIGHT(table2.selector, 1) AS int)
ORDER BY table1.user;
Use ROW_NUMBER:
SQL Fiddle
;WITH Cte AS(
SELECT *,
ROW_NUMBER() OVER(
PARTITION BY [User]
ORDER BY
CASE WHEN Priority IS NULL THEN 1 ELSE 0 END,
Priority,
LineItem
) AS rn
FROM tbl
)
SELECT
[User], LineItem, Number, Priority
FROM Cte
WHERE rn = 1
here is the table
and data like:
id name
1 test1
2 test2
3 test3
4 test4
5 test5
6 test6
From above data i want the data like
if i pass the id as parameter and return the data from from up and gown by order
Example if i pass the id as parameter = 4 then it should be return
upline 2 row and downline 2 row for particular id, and it should be like this
id name
2 test2
3 test3
4 test4
5 test5
6 test6
and same for the id = 3
id name
1 test1
2 test2
3 test3
4 test4
5 test5
SELECT TOP 3 id, name
FROM table
WHERE id =< #id
ORDER BY id DESC
UNION
SELECT TOP 2 id, name
FROM table
WHERE id > #id
ORDER BY id ACS