我想知道我在给定日期和特定商店(我们有)给定范围尺寸(比如3:X,Y,Z)的模型(比如说T恤)有多少说3:A,B,C)库存。
其中:
X = between 40 and 50
Y = between 30 and 60
Z = between 20 and 70
最终输出看起来像这样(但有很多结果):
Date | Store | Model | Availability X | Availability Y | Availability Z
02/26 | A | shirt | Yes | Yes | No
02/26 | B | shirt | Yes | No | No
02/26 | C | shirt | Yes | Yes | Yes
可用性意味着我必须拥有给定尺寸范围之间的所有尺寸。
我仍然想找到一种方法来做到这一点。我现在的表格就是这样设计的(一些说明性信息):
表“设置”
id | name | initial_value | final_value
1 | X | 40 | 50
2 | Y | 30 | 60
3 | Z | 20 | 70
表“项目”
id | date | store | model | size | in_stock
1 | 02/26 | A | shirt | 40 | 1
2 | 02/26 | A | shirt | 50 | 2
3 | 02/26 | A | shirt | 30 | 0
4 | 02/26 | B | shirt | 30 | 1
我感谢任何帮助!感谢。
答案 0 :(得分:1)
这是SQL Server的输出,我不知道postgresql。
- 创建SETS
create table dbo.test_sets
(
id int not null,
name varchar(255),
initial_value int not null default (0),
final_value int not null default(0)
)
go
insert into dbo.test_sets( id, name, initial_value, final_value)
values (1, 'X', 40, 50)
insert into dbo.test_sets( id, name, initial_value, final_value)
values (2, 'Y', 30, 60)
insert into dbo.test_sets( id, name, initial_value, final_value)
values (3, 'Z', 20, 70)
go
- 创建ITEMS
create table dbo.test_items
(
id int not null,
[date] date,
store varchar(255) not null,
model varchar(255) not null,
size int not null default (0),
in_stock int not null default(0)
)
go
insert into dbo.test_items( id, [date], store, model, size, in_stock)
values (1, '02/26/2016', 'A', 'shirt', 40, 1)
insert into dbo.test_items( id, [date], store, model, size, in_stock)
values (2, '02/26/2016', 'A', 'shirt', 50, 2)
insert into dbo.test_items( id, [date], store, model, size, in_stock)
values (3, '02/26/2016', 'A', 'shirt', 30, 0)
insert into dbo.test_items( id, [date], store, model, size, in_stock)
values (4, '02/26/2016', 'B', 'shirt', 30, 1)
insert into dbo.test_items( id, [date], store, model, size, in_stock)
values (5, '02/26/2016', 'C', 'shirt', 80, 1)
go
- 创建NUMBERS LOOKUP
create table dbo.test_numbers
(
id int not null
)
go
declare @first as int
declare @step as int
declare @last as int
select @first = 1, @step = 1, @last = 100
BEGIN TRANSACTION
WHILE(@first <= @last)
BEGIN
INSERT INTO dbo.test_numbers VALUES(@first) SET @first += @step
END
COMMIT TRANSACTION
go
- 查询以提供所需的输出
;with unique_store_models as
(
select distinct store, model from dbo.test_items
),
set_sizes as
(
select ts.id, ts.name as size_group, tn.id as size
from
dbo.test_sets ts
inner join dbo.test_numbers tn on
tn.id between ts.initial_Value and ts.final_value
),
items_by_sizes_flat as
(
select
ti.[date],
usm.store,
usm.model,
ss.size_group,
ss.size,
ti.in_stock
from
unique_store_models usm
left outer join dbo.test_items ti on
ti.store = usm.store
and ti.model = usm.model
left outer join set_sizes ss on
ss.size = ti.size
),
items_by_sizes_pivoted as
(
select
*
from
(
select
[date],
store,
model,
size_group,
--size,
in_stock
from
items_by_sizes_flat
) as p
PIVOT
(
count(in_stock) for size_group in ([X], [Y], [Z])
) as pv
)
select
[date],
store,
model,
case
when [X] > 0 then 'Yes' else 'No'
end as [Availability X],
case
when [Y] > 0 then 'Yes' else 'No'
end as [Availability Y],
case
when [Z] > 0 then 'Yes' else 'No'
end as [Availability Z]
from
items_by_sizes_pivoted
以下是上述输入的输出:
答案 1 :(得分:0)
也许你可以尝试这样的事情:
SELECT date,
store,
model,
SUM(
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 1) AND (SELECT final_value FROM Table "sets" WHERE id = 1)
THEN in_stock
ELSE 0
END
) as "Availability X",
SUM(
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 2) AND (SELECT final_value FROM Table "sets" WHERE id = 2)
THEN in_stock
ELSE 0
END
) as "Availability Y",
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 3) AND (SELECT final_value FROM Table "sets" WHERE id = 3)
THEN in_stock
ELSE 0
END
) as "Availability Z"
FROM Table "items"
WHERE date > '02/26/2016'
AND
date < '02/26/2016'
AND
Model = 'shirt'
GROUP BY date, store, model
我认为这会为您提供您之后的信息,但如果您想要完全按照您的要求输出,那么您可以围绕每个可用性案例声明包装另一个案例陈述,或使用如下的CTE: / p>
WITH
data AS
(
SELECT date,
store,
model,
SUM(
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 1) AND (SELECT final_value FROM Table "sets" WHERE id = 1)
THEN in_stock
ELSE 0
END
) as availability_x,
SUM(
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 2) AND (SELECT final_value FROM Table "sets" WHERE id = 2)
THEN in_stock
ELSE 0
END
) as availability_y,
SUM(
CASE
WHEN size BETWEEN (SELECT initial_value FROM Table "sets" WHERE id = 3) AND (SELECT final_value FROM Table "sets" WHERE id = 3)
THEN in_stock
ELSE 0
END
) as availability_z
FROM Table "items"
WHERE date > '02/26/2016'
AND
date < '02/26/2016'
AND
Model = 'shirt'
GROUP BY date, store, model
)
SELECT date, store, model,
CASE
WHEN availability_x > 0 THEN "Yes"
ELSE "No"
END as "Availability X",
CASE
WHEN availability_y > 0 THEN "Yes"
ELSE "No"
END as "Availability Y",
CASE
WHEN availability_z > 0 THEN "Yes"
ELSE "No"
END as "Availability Z"
FROM data
答案 2 :(得分:0)
crosstab()
用例的典型示例。
示例数据:
-- DDL and data
CREATE TABLE items(
id SERIAL PRIMARY KEY,
"Date" DATE,
store TEXT,
model TEXT,
size INTEGER,
in_stock INTEGER
);
INSERT INTO items VALUES
(1, '02/26/2016':: DATE, 'A', 'shirt', 40, 1),
(2, '02/26/2016':: DATE, 'A', 'shirt', 50, 2),
(3, '02/26/2016':: DATE, 'A', 'shirt', 30, 0),
(4, '02/26/2016':: DATE, 'B', 'shirt', 30, 1);
CREATE TABLE sets(
id SERIAL PRIMARY KEY,
name TEXT,
initial_value INTEGER,
final_value INTEGER
);
INSERT INTO sets VALUES
(1, 'X', 40, 50),
(2, 'Y', 30, 60),
(3, 'Z', 20, 70);
为了选择我使用int4range(start,end,inclusion)
函数来配置大小范围include.Query本身:
SELECT * FROM crosstab(
'SELECT i.store,i."Date",i.model,s.name,
bool_or(CASE WHEN size_range @> i.size
THEN TRUE
ELSE FALSE
END)
FROM items i,sets s,int4range(s.initial_value, s.final_value, ''[)'') AS size_range
WHERE i.in_stock > 0
GROUP BY 1,2,3,4
ORDER BY 1,2',
'SELECT DISTINCT(name) FROM sets ORDER BY 1')
AS output(store TEXT,"Date" DATE,model TEXT,"Availability X" BOOLEAN,"Availability Y" BOOLEAN,"Availability Z" BOOLEAN);
结果:
store | Date | model | Availability X | Availability Y | Availability Z
-------+------------+-------+----------------+----------------+----------------
A | 2016-02-26 | shirt | t | t | t
B | 2016-02-26 | shirt | f | t | t
(2 rows)