我有一个包含产品订单表的数据库,如下所示:
order_id | prod_code | prod_color | size | quantity |
-----------------------------------------------------
1 SHIRT 001 S 10
1 SHIRT 001 M 7
1 SHIRT 001 L 8
1 SHIRT 001 XL 1
1 SHIRT 995 S 2
1 SHIRT 995 M 1
1 SHIRT 995 L 0
1 SHIRT 995 XL 1
2 PANTS ....
和这样的产品价格表:
prod_code | prod_color | price | currency
-----------------------------------------
SHIRT 001 10 EUR
SHIRT 001 9 USD
SHIRT 001 50 YEN
SHIRT 001 15 RUB
SHIRT 995 20 EUR
SHIRT 995 29 USD
SHIRT 995 100 YEN
SHIRT 995 45 RUB
PANTS ....
我想得到的是这样一个视图(为了简单过滤order_id):
order_id | prod_code | prod_color | size | quantity | EUR | USD | YEN | RUB
---------------------------------------------------------------------------
1 SHIRT 001 S 10 10 9 50 15
1 SHIRT 001 M 7 10 9 50 15
1 SHIRT 001 L 8 10 9 50 15
1 SHIRT 001 XL 1 10 9 50 15
1 SHIRT 995 S 2 20 29 100 45
1 SHIRT 995 M 1 20 29 100 45
1 SHIRT 995 L 0 20 29 100 45
1 SHIRT 995 XL 1 20 29 100 45
我已经浏览了网页并通过SO,我发现THIS QUESTION向我展示了我需要做的事情,但我认为我做了一些修改......
我尝试在数据库上运行此查询:
SELECT o.order_id, o.prod_code, o.prod_color, o.size, o.quantity,
MAX(CASE WHEN p.currency = 'EUR' THEN p.price END) AS 'EUR',
MAX(CASE WHEN p.currency = 'USD' THEN p.price END) AS 'USD',
MAX(CASE WHEN p.currency = 'YEN' THEN p.price END) AS 'YEN',
MAX(CASE WHEN p.currency = 'RUB' THEN p.price END) AS 'RUB'
FROM products_order o JOIN products_prices p ON o.prod_code = p.prod_code
WHERE o.order_id = 1
GROUP BY o.order_id, o.prod_code, o.prod_color, o.size, o.quantity
将在价格列中返回,对于每一行,在整个列中找到MAX值:因此,对于[product_color = 001]和[product_color = 995],我的价格等于20欧元(对于001而言,它是更便宜,只有10欧元!)
我也试过没有MAX,但它给了我一行每个价格,让很多单元格为空(然后我明白了MAX用于:D)。
你知道如何做我想做的事吗?如何通过每个prod_color在单个prod_color中使用MAX?
我希望你能理解我写的内容,提前谢谢,感谢任何帮助。
(如果您需要更清楚地解释一些问题,请尽快回答。
再次感谢,最好的问候
答案 0 :(得分:7)
我添加了额外的JOIN
条件:AND o.prod_color = p.prod_color
http://sqlfiddle.com/#!5/fadad/5
SELECT
o.order_id, o.prod_code, o.prod_color, o.size, o.quantity,
MAX(CASE WHEN p.currency = 'EUR' THEN p.price END) AS 'EUR',
MAX(CASE WHEN p.currency = 'USD' THEN p.price END) AS 'USD',
MAX(CASE WHEN p.currency = 'YEN' THEN p.price END) AS 'YEN',
MAX(CASE WHEN p.currency = 'RUB' THEN p.price END) AS 'RUB'
FROM products_order o
JOIN products_prices p
ON o.prod_code = p.prod_code
AND o.prod_color = p.prod_color /* this line is added */
WHERE o.order_id = '1'
GROUP BY
o.order_id,
o.prod_code,
o.prod_color,
o.size,
o.quantity
没有GROUP BY
的简化示例查询显示了差异:
答案 1 :(得分:0)
动态查询方法(每个数据透视列使用 CASE
表达式)应该是首选方法,但是当您事先不知道数据透视列或者由于某种原因很难在应用程序端生成查询时,有 pivot_vtab SQLite 虚拟表扩展形式的替代方案。在撰写本文时,它不太实用,因为它似乎是一个概念验证工作,但这并不意味着它可以/不会改进。
我不会详细介绍构建扩展程序——您可以在此 related answer 中看到它们。 我正在使用这样的问题中的数据。
CREATE TABLE products_order(
order_id INTEGER,
prod_code TEXT,
prod_color INTEGER,
size TEXT,
quantity INTEGER
);
INSERT INTO products_order(order_id, prod_code, prod_color, size, quantity)
VALUES
(1, 'SHIRT', 001, 'S', 10), (1, 'SHIRT', 001, 'M', 7),
(1, 'SHIRT', 001, 'L', 8), (1, 'SHIRT', 001, 'XL', 1),
(1, 'SHIRT', 995, 'S', 2), (1, 'SHIRT', 995, 'M', 1),
(1, 'SHIRT', 995, 'L', 0), (1, 'SHIRT', 995, 'XL', 1);
CREATE TABLE products_prices(
prod_code TEXT,
prod_color INTEGER,
price INTEGER,
currency TEXT
);
INSERT INTO products_prices(prod_code, prod_color, price, currency)
VALUES
('SHIRT', 001, 10, 'EUR'), ('SHIRT', 001, 9, 'USD'),
('SHIRT', 001, 50, 'YEN'), ('SHIRT', 001, 15, 'RUB'),
('SHIRT', 995, 20, 'EUR'), ('SHIRT', 995, 29, 'USD'),
('SHIRT', 995, 100, 'YEN'), ('SHIRT', 995, 45, 'RUB');
枢轴是这样构建的(我假设扩展已加载,.load ./pivot_vtab
)。
因为扩展仅限于一个“行”列(您可以根据该列进行分组),
创建临时映射。我假设订单键是 (order_id, prod_code, prod_color, size)
并且 quantity
在功能上取决于 order_id
,所以没有
需要对其进行分组,但它将在第 3 步中使用。
CREATE TABLE rowmap AS
SELECT
ROW_NUMBER() OVER(ORDER BY 1) row_id,
order_id,
prod_code,
prod_color,
size,
quantity
FROM products_order
GROUP BY 2, 3, 4, 5;
使用 pivot
表创建 rowmap
表。请注意,第三个枢轴“矩阵填充”
查询也只需要单列。
CREATE VIRTUAL TABLE pivot USING pivot_vtab(
(SELECT row_id FROM rowmap),
(SELECT currency, currency FROM products_prices GROUP BY currency),
(
SELECT price
FROM products_order o
JOIN products_prices p USING(prod_code, prod_color)
JOIN rowmap m USING(order_id, prod_code, prod_color, size)
WHERE o.order_id = 1 AND m.row_id = ?1 AND p.currency = ?2
GROUP BY o.order_id, o.prod_code, o.prod_color, o.size, p.currency
)
);
重新组合 rowmap
列。
SELECT order_id, prod_code, prod_color, size, quantity, p.*
FROM pivot p
JOIN rowmap r ON p.row_id = r.row_id;
结果集应如下所示(我有 .headers on
和 .mode column
)。
order_id prod_code prod_color size quantity row_id EUR RUB USD YEN
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
1 SHIRT 1 L 8 1 10 15 9 50
1 SHIRT 1 M 7 2 10 15 9 50
1 SHIRT 1 S 10 3 10 15 9 50
1 SHIRT 1 XL 1 4 10 15 9 50
1 SHIRT 995 L 0 5 20 45 29 100
1 SHIRT 995 M 1 6 20 45 29 100
1 SHIRT 995 S 2 7 20 45 29 100
1 SHIRT 995 XL 1 8 20 45 29 100
或者,如果你想去掉 row_id
列,你可以使用另一个临时删除它
表(从 SQLite 3.35 开始支持 ALTER TABLE ... DROP COLUMN
)。
CREATE TABLE result_pivot AS
SELECT order_id, prod_code, prod_color, size, quantity, p.*
FROM pivot p
JOIN rowmap r ON p.row_id = r.row_id;
ALTER TABLE result_pivot DROP COLUMN row_id;
SELECT * FROM temp.result_pivot;