Rank order grouped data in MySQL without session variables?
My data looks like this:
Table Name = sales_orders
Customer_id| Order_id| Item_Id
-------------------------------
1 | 1 | 10
1 | 1 | 24
1 | 1 | 37
1 | 2 | 11
1 | 2 | 15
1 | 3 | 28
2 | 4 | 37
4 | 6 | 10
2 | 7 | 10
However, I need it to look like this:
Customer_id| Order_id| Item_Id |Order_rank
------------------------------------------
1 | 1 | 10 | 1
1 | 1 | 24 | 1
1 | 1 | 37 | 1
1 | 2 | 11 | 2
1 | 2 | 15 | 2
1 | 3 | 28 | 3
2 | 4 | 37 | 1
4 | 6 | 10 | 1
2 | 7 | 10 | 2
Customer_Id is a unique person
Order_id is a unique order
item_id is the product code
To further explain, the first three lines are from Customer #1's first order (order_id = 1) where this person ordered 3 different items (10,24, and 37). They then purchased another order (order_id =2) with two other products. Person with customer_id =2 has 2 unique orders (4 and 6), while customer with ID '4' has one unique order (order_id =6)
Essentially, what I need to do is rank these orders by customer_id and order Id, so that I can say "Order_id = 7 is the second order for customer_id = 2, because Order_rank = 2"
The challenge here is that I can't use session variables (e.g. @grp := customer_id ) in the MySQL query
For example, a query such as this is NOT allowed:
SELECT
customer_id,
order_id,
@ss := CASE WHEN @grp = customer_id THEN @ss + 1 ELSE 1 END AS
order_rank,
@grp := customer_id
FROM
(
SELECT
customer_id,
order_id
FROM sales_orders
GROUP BY customer_id, order_id
ORDER BY customer_id, order_id ASC
) AS t_1
CROSS JOIN (SELECT @ss := 0, @grp = NULL)ss
ORDER BY customer_id asc
Thanks for the help!
mysql sql session-variables ranking rank
add a comment |
My data looks like this:
Table Name = sales_orders
Customer_id| Order_id| Item_Id
-------------------------------
1 | 1 | 10
1 | 1 | 24
1 | 1 | 37
1 | 2 | 11
1 | 2 | 15
1 | 3 | 28
2 | 4 | 37
4 | 6 | 10
2 | 7 | 10
However, I need it to look like this:
Customer_id| Order_id| Item_Id |Order_rank
------------------------------------------
1 | 1 | 10 | 1
1 | 1 | 24 | 1
1 | 1 | 37 | 1
1 | 2 | 11 | 2
1 | 2 | 15 | 2
1 | 3 | 28 | 3
2 | 4 | 37 | 1
4 | 6 | 10 | 1
2 | 7 | 10 | 2
Customer_Id is a unique person
Order_id is a unique order
item_id is the product code
To further explain, the first three lines are from Customer #1's first order (order_id = 1) where this person ordered 3 different items (10,24, and 37). They then purchased another order (order_id =2) with two other products. Person with customer_id =2 has 2 unique orders (4 and 6), while customer with ID '4' has one unique order (order_id =6)
Essentially, what I need to do is rank these orders by customer_id and order Id, so that I can say "Order_id = 7 is the second order for customer_id = 2, because Order_rank = 2"
The challenge here is that I can't use session variables (e.g. @grp := customer_id ) in the MySQL query
For example, a query such as this is NOT allowed:
SELECT
customer_id,
order_id,
@ss := CASE WHEN @grp = customer_id THEN @ss + 1 ELSE 1 END AS
order_rank,
@grp := customer_id
FROM
(
SELECT
customer_id,
order_id
FROM sales_orders
GROUP BY customer_id, order_id
ORDER BY customer_id, order_id ASC
) AS t_1
CROSS JOIN (SELECT @ss := 0, @grp = NULL)ss
ORDER BY customer_id asc
Thanks for the help!
mysql sql session-variables ranking rank
add a comment |
My data looks like this:
Table Name = sales_orders
Customer_id| Order_id| Item_Id
-------------------------------
1 | 1 | 10
1 | 1 | 24
1 | 1 | 37
1 | 2 | 11
1 | 2 | 15
1 | 3 | 28
2 | 4 | 37
4 | 6 | 10
2 | 7 | 10
However, I need it to look like this:
Customer_id| Order_id| Item_Id |Order_rank
------------------------------------------
1 | 1 | 10 | 1
1 | 1 | 24 | 1
1 | 1 | 37 | 1
1 | 2 | 11 | 2
1 | 2 | 15 | 2
1 | 3 | 28 | 3
2 | 4 | 37 | 1
4 | 6 | 10 | 1
2 | 7 | 10 | 2
Customer_Id is a unique person
Order_id is a unique order
item_id is the product code
To further explain, the first three lines are from Customer #1's first order (order_id = 1) where this person ordered 3 different items (10,24, and 37). They then purchased another order (order_id =2) with two other products. Person with customer_id =2 has 2 unique orders (4 and 6), while customer with ID '4' has one unique order (order_id =6)
Essentially, what I need to do is rank these orders by customer_id and order Id, so that I can say "Order_id = 7 is the second order for customer_id = 2, because Order_rank = 2"
The challenge here is that I can't use session variables (e.g. @grp := customer_id ) in the MySQL query
For example, a query such as this is NOT allowed:
SELECT
customer_id,
order_id,
@ss := CASE WHEN @grp = customer_id THEN @ss + 1 ELSE 1 END AS
order_rank,
@grp := customer_id
FROM
(
SELECT
customer_id,
order_id
FROM sales_orders
GROUP BY customer_id, order_id
ORDER BY customer_id, order_id ASC
) AS t_1
CROSS JOIN (SELECT @ss := 0, @grp = NULL)ss
ORDER BY customer_id asc
Thanks for the help!
mysql sql session-variables ranking rank
My data looks like this:
Table Name = sales_orders
Customer_id| Order_id| Item_Id
-------------------------------
1 | 1 | 10
1 | 1 | 24
1 | 1 | 37
1 | 2 | 11
1 | 2 | 15
1 | 3 | 28
2 | 4 | 37
4 | 6 | 10
2 | 7 | 10
However, I need it to look like this:
Customer_id| Order_id| Item_Id |Order_rank
------------------------------------------
1 | 1 | 10 | 1
1 | 1 | 24 | 1
1 | 1 | 37 | 1
1 | 2 | 11 | 2
1 | 2 | 15 | 2
1 | 3 | 28 | 3
2 | 4 | 37 | 1
4 | 6 | 10 | 1
2 | 7 | 10 | 2
Customer_Id is a unique person
Order_id is a unique order
item_id is the product code
To further explain, the first three lines are from Customer #1's first order (order_id = 1) where this person ordered 3 different items (10,24, and 37). They then purchased another order (order_id =2) with two other products. Person with customer_id =2 has 2 unique orders (4 and 6), while customer with ID '4' has one unique order (order_id =6)
Essentially, what I need to do is rank these orders by customer_id and order Id, so that I can say "Order_id = 7 is the second order for customer_id = 2, because Order_rank = 2"
The challenge here is that I can't use session variables (e.g. @grp := customer_id ) in the MySQL query
For example, a query such as this is NOT allowed:
SELECT
customer_id,
order_id,
@ss := CASE WHEN @grp = customer_id THEN @ss + 1 ELSE 1 END AS
order_rank,
@grp := customer_id
FROM
(
SELECT
customer_id,
order_id
FROM sales_orders
GROUP BY customer_id, order_id
ORDER BY customer_id, order_id ASC
) AS t_1
CROSS JOIN (SELECT @ss := 0, @grp = NULL)ss
ORDER BY customer_id asc
Thanks for the help!
mysql sql session-variables ranking rank
mysql sql session-variables ranking rank
asked Nov 21 '18 at 1:38
Negative CorrelationNegative Correlation
588
588
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
In a Correlated Subquery, we can Count(..)
the unique and previous order_id
values for a specific row's customer_id
and order_id
to determine the rank.
We need to count unique values because you have multiple rows per order (due to multiple items).
Query
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
Result
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
View on DB Fiddle
add a comment |
You can use a correlated subquery:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
Or in MySQL 8+:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404131%2frank-order-grouped-data-in-mysql-without-session-variables%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
In a Correlated Subquery, we can Count(..)
the unique and previous order_id
values for a specific row's customer_id
and order_id
to determine the rank.
We need to count unique values because you have multiple rows per order (due to multiple items).
Query
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
Result
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
View on DB Fiddle
add a comment |
In a Correlated Subquery, we can Count(..)
the unique and previous order_id
values for a specific row's customer_id
and order_id
to determine the rank.
We need to count unique values because you have multiple rows per order (due to multiple items).
Query
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
Result
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
View on DB Fiddle
add a comment |
In a Correlated Subquery, we can Count(..)
the unique and previous order_id
values for a specific row's customer_id
and order_id
to determine the rank.
We need to count unique values because you have multiple rows per order (due to multiple items).
Query
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
Result
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
View on DB Fiddle
In a Correlated Subquery, we can Count(..)
the unique and previous order_id
values for a specific row's customer_id
and order_id
to determine the rank.
We need to count unique values because you have multiple rows per order (due to multiple items).
Query
SELECT
t1.Customer_id,
t1.Order_id,
t1.Item_Id,
(SELECT COUNT(DISTINCT t2.Order_id)
FROM sales_orders t2
WHERE t2.Customer_id = t1.Customer_id AND
t2.Order_id <= t1.Order_id
) AS Order_rank
FROM sales_orders AS t1;
Result
| Customer_id | Order_id | Item_Id | Order_rank |
| ----------- | -------- | ------- | ---------- |
| 1 | 1 | 10 | 1 |
| 1 | 1 | 24 | 1 |
| 1 | 1 | 37 | 1 |
| 1 | 2 | 11 | 2 |
| 1 | 2 | 15 | 2 |
| 1 | 3 | 28 | 3 |
| 2 | 4 | 37 | 1 |
| 4 | 6 | 10 | 1 |
| 2 | 7 | 10 | 2 |
View on DB Fiddle
edited Nov 21 '18 at 5:58
answered Nov 21 '18 at 5:33
Madhur BhaiyaMadhur Bhaiya
19.6k62236
19.6k62236
add a comment |
add a comment |
You can use a correlated subquery:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
Or in MySQL 8+:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;
add a comment |
You can use a correlated subquery:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
Or in MySQL 8+:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;
add a comment |
You can use a correlated subquery:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
Or in MySQL 8+:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;
You can use a correlated subquery:
select so.*,
(select count(*)
from sales_orders so2
where so2.Customer_id = so.Customer_id and
so2.order_id <= so.order_id
) as rank_order
from sales_orders so;
Or in MySQL 8+:
select so.*,
dense_rank() over (partition by Customer_Id order by Order_Id) as rank_order
from sales_orders so;
answered Nov 21 '18 at 1:49
Gordon LinoffGordon Linoff
783k35310414
783k35310414
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53404131%2frank-order-grouped-data-in-mysql-without-session-variables%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown