英文:
Select 75% of records to rename, based on column sum
问题
我需要重命名一个列中的值,基于另一个列的总数。以下是一个示例表格,用基本数学来表示这个概念。我想将“Condition”列中的值更改为“Used”,对应于占“Revenue”列总数的70%的行(在这个示例中将是7行)。其余30%将被重命名为“New”(剩下的3行)。不需要其他特定的逻辑。
我发现这里提到的方法适用于选择所需百分比的行:
https://stackoverflow.com/questions/45153631/select-rows-whos-sum-value-80-of-the-total
我想我可以创建两个临时表,分别重命名各自的列字段,然后将它们连接在一起。不知道是否有更简单的方法?
现有表格:
Source | Condition | Revenue |
---|---|---|
A | Old | 1 |
B | New | 1 |
C | Old | 1 |
D | New | 1 |
E | Old | 1 |
F | New | 1 |
G | Old | 1 |
H | New | 1 |
I | Old | 1 |
J | New | 1 |
新表格:
Source | Condition | Revenue |
---|---|---|
A | Used | 1 |
B | Used | 1 |
C | Used | 1 |
D | Used | 1 |
E | Used | 1 |
F | Used | 1 |
G | Used | 1 |
H | New | 1 |
I | New | 1 |
J | New | 1 |
英文:
I have a scenario where I need to rename a value in one column, based on another column's total. Example table below with basic math, to express concept. I'd like to change the value in 'Condition' column to "Used" for the rows that make up 70% of the 'Revenue' column (which in this example would be 7 rows). The other 30% would be renamed to "New" (the remaining 3 rows). No other specific logic required.
I found that the approach mentioned here works for selecting the percentage of rows required
https://stackoverflow.com/questions/45153631/select-rows-whos-sum-value-80-of-the-total
I suppose I could create two temporary tables, rename the column fields in each respective table, and then join together. Curious if there is an easier way?
Current Table:
Source | Condition | Revenue |
---|---|---|
A | Old | 1 |
B | New | 1 |
C | Old | 1 |
D | New | 1 |
E | Old | 1 |
F | New | 1 |
G | Old | 1 |
H | New | 1 |
I | Old | 1 |
J | New | 1 |
New Table:
Source | Condition | Revenue |
---|---|---|
A | Used | 1 |
B | Used | 1 |
C | Used | 1 |
D | Used | 1 |
E | Used | 1 |
F | Used | 1 |
G | Used | 1 |
H | New | 1 |
I | New | 1 |
J | New | 1 |
答案1
得分: 2
以下是翻译好的内容:
You could do this with two updates. The first would update the entire table. The second would update the first 70%.
首先,您可以使用两个更新操作来完成。第一个更新将更新整个表,第二个更新将更新前70%的数据。
First we need sample data in a table. I used a table variable here but you would use your actual table.
首先,我们需要在表中准备示例数据。我在这里使用了一个表变量,但您应该使用实际的表。
declare @Something table
(
Source char(1)
, Condition varchar(10)
, Revenue int
)
insert @Something values
('A', 'Old', 1)
, ('B', 'New', 1)
, ('C', 'Old', 1)
, ('D', 'New', 1)
, ('E', 'Old', 1)
, ('F', 'New', 1)
, ('G', 'Old', 1)
, ('H', 'New', 1)
, ('I', 'Old', 1)
, ('J', 'New', 1)
首先,我们需要在表中创建一个包含示例数据的表。在这里,我使用了一个表变量,但您应该使用实际的表。
select *
from @Something;
接下来,只需更新整个表。
update @Something
set Condition = 'New';
然后,只需更新前70%的数据。一个简单的方法是使用一个通用表表达式 (cte) 来选择前70%,然后更新通用表表达式。
with Top70 as
(
select top 70 percent *
from @Something
order by Source
)
update Top70
set Condition = 'Used';
最后,这是最终的输出。
select *
from @Something;
最后,这是最终的输出。
--EDIT--
Now understanding we need a running total you could do something like this.
现在,如果我们需要一个累积总和,您可以尝试像这样的方法。
select *
, case when sum(Revenue) over(order by Source) > (sum(Revenue) over() * .7) then 'New' else 'Old' end
from @Something
英文:
You could do this with two updates. The first would update the entire table. The second would update the first 70%.
First we need sample data in a table. I used a table variable here but you would use your actual table.
declare @Something table
(
Source char(1)
, Condition varchar(10)
, Revenue int
)
insert @Something values
('A', 'Old', 1)
, ('B', 'New', 1)
, ('C', 'Old', 1)
, ('D', 'New', 1)
, ('E', 'Old', 1)
, ('F', 'New', 1)
, ('G', 'Old', 1)
, ('H', 'New', 1)
, ('I', 'Old', 1)
, ('J', 'New', 1)
select *
from @Something;
Next simply update the entire table.
update @Something
set Condition = 'New';
Last step is to update the first 70%. An easy to do this is to use a cte to select the first 70% and then update the cte.
with Top70 as
(
select top 70 percent *
from @Something
order by Source
)
update Top70
set Condition = 'Used';
Here is the final output.
select *
from @Something;
--EDIT--
Now understanding we need a running total you could do something like this.
select *
, case when sum(Revenue) over(order by Source) > (sum(Revenue) over() * .7) then 'New' else 'Old' end
from @Something
答案2
得分: 2
你可以使用以下查询选择/标记70%和30%的记录:
with cte as (
SELECT *, SUM(revenue) OVER(ORDER BY source) AS cumulative_revenue, SUM(revenue) OVER() as total
FROM mytable t
)
select Source, iif((cumulative_revenue + 0.0) /total <= 0.7, 'Used', 'New') as Condition, revenue, cumulative_revenue, (cumulative_revenue + 0.0) /total as perc
from cte
英文:
You can select/mark the 70% and 30% records using this query :
with cte as (
SELECT *, SUM(revenue) OVER(ORDER BY source) AS cumulative_revenue, SUM(revenue) OVER() as total
FROM mytable t
)
select Source, iif((cumulative_revenue + 0.0) /total <= 0.7, 'Used', 'New') as Condition, revenue, cumulative_revenue, (cumulative_revenue + 0.0) /total as perc
from cte
答案3
得分: 1
你可以链式使用几个公共表达式(CTE)来运行UPDATE语句。
-- 删除表如果存在
DROP TABLE IF EXISTS #t
-- 创建临时表
CREATE TABLE #t([Source] VARCHAR(10), [Condition] VARCHAR(10), Revenue INT)
-- 向临时表插入数据
INSERT INTO #t([Source], [Condition], [Revenue])
VALUES
('A', 'Old', 1),
('B', 'New', 1),
('C', 'Old', 1),
('D', 'New', 1),
('E', 'Old', 1),
('F', 'New', 1),
('G', 'Old', 1),
('H', 'New', 1),
('I', 'Old', 1),
('J', 'New', 1);
-- 使用两个CTE
WITH cte AS (
SELECT *, SUM(Revenue) OVER (ORDER BY Source) ACC
FROM #t
), cte2 AS (
SELECT MAX(ACC) * 1. AS TotalRevenue FROM cte
)
-- 更新cte中的数据
UPDATE cte
SET [Condition] = CASE WHEN ACC / TotalRevenue <= 0.7 THEN 'Used' ELSE 'New' END
FROM cte
CROSS APPLY (SELECT TotalRevenue FROM cte2) ca;
-- 查询临时表的内容
SELECT * FROM #t
这段代码使用公共表达式(CTE)来计算ACC
(累积收入),然后更新#t
表中的Condition
列,根据条件判断是否将其设置为'Used'或'New'。最后,它查询#t
表的内容。
英文:
You could chain a couple of CTEs to run the UPDATE
DROP TABLE IF EXISTS #t
CREATE TABLE #t([Source] VARCHAR(10), [Condition] VARCHAR(10), Revenue INT)
INSERT INTO #t([Source], [Condition], [Revenue])
values
('A', 'Old', 1)
,('B', 'New', 1)
,('C', 'Old', 1)
,('D', 'New', 1)
,('E', 'Old', 1)
,('F', 'New', 1)
,('G', 'Old', 1)
,('H', 'New', 1)
,('I', 'Old', 1)
,('J', 'New', 1)
;WITH cte AS (
SELECT *, SUM( Revenue) OVER (ORDER BY Source) ACC
FROM #t
), cte2 as(
SELECT MAX(acc)*1. TotalRevenue FROM cte
)
UPDATE cte
SET Condition = CASE WHEN Acc / TotalRevenue <= .7 THEN 'Used' ELSE 'New' END
FROM cte
CROSS APPLY (SELECT TotalRevenue FROM cte2) ca
SELECT * FROM #t
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论