加入两个表,合并并转置结果
Join two tables, merge and transpose the result
好吧,假设我有两个 tables products
和 product_options
.
结构tableproducts
如:
+--------------------------------------+
| p_id | product_name | product_status |
+--------------------------------------+
| 1 | Keyboard ABC | PENDING |
| 2 | Mouse ABC | ORDERED |
| 3 | Monitor ABC | ORDERED |
+--------------------------------------+
和table product_options
就像:
+--------------------------------------+
| po_id | p_id | opt_name | opt_value +
+--------------------------------------+
| 1 | 1 | part_no | KB-ABC-001 |
| 2 | 1 | stock | 0 |
| 3 | 2 | part_no | MS-ABC-001 |
| 4 | 2 | stock | 14 |
| 5 | 3 | part_no | MO-ABC-001 |
| 6 | 3 | stock | 10 |
+--------------------------------------+
问题是,我想同时显示 table 的查询,并且只显示我订购的产品的特定标准。结果如下:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | 14 | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | 10 | ORDERED |
+------------------------------------------------------------+
我的SQL查询是:
SELECT
t.p_id,
t.product_name,
(CASE WHEN t.key_name = 'part_no' THEN t.key_value ELSE NULL END) AS part_no,
(CASE WHEN t.key_name = 'stock' THEN t.key_value ELSE NULL END) AS stock,
t.product_status
FROM
(
SELECT
products.p_id as p_id,
products.product_name as product_name,
products.product_status as product_status,
product_options.opt_name as key_name,
product_options.opt_value as key_value
FROM
product_options Inner Join
products On product_options.p_id = products.p_id
WHERE
(products.product_status = 'ORDERED') AND
(product_options.opt_name = 'part_no' OR product_options.opt_name = 'stock')
) as t
GROUP BY t.p_id
我得到的是:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | NULL | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | NULL | ORDERED |
+------------------------------------------------------------+
但是,我想要的是在 stock
字段显示 NULL,因为 product_options
上的数据有:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | 14 | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | 10 | ORDERED |
+------------------------------------------------------------+
问题是,如何显示/合并两个 table 这样的大小写?
我尝试使用 GROUP_CONCAT
,但这不是我要搜索的内容。
请帮忙。
试试这个查询:
select p.p_id p_id , p.product_name product_name ,
(select i.opt_value from product_options i where i.p_id=p.p_id and i.opt_name='part_no') part_no,
(select i.opt_value from product_options i where i.p_id=p.p_id and i.opt_name='stock') stock,
p.product_status product_status
from products p
where p.product_status='ORDERED';
你可以试试这个:
SELECT
p.p_id p_id ,
p.product_name product_name ,
po.opt_value_1 AS part_no,
po.opt_value_2 AS stock,
p.product_status product_status
FROM
products p LEFT JOIN (SELECT po1.p_id,
po1.opt_name AS opt_name_1,
po1.opt_value AS opt_value_1,
po2.opt_name AS opt_name_2,
po2.opt_value AS opt_value_2
FROM product_options po1
LEFT JOIN product_options po2
ON po1.p_id = po2.p_id
AND po1.opt_name != po2.opt_name
GROUP BY po1.p_id) AS po
ON p.p_id = po.p_id
WHERE p.product_status='ORDERED';
这里是 sqlfiddle.
SELECT p.p_id
, p.product_name
, MAX(CASE WHEN o.opt_name = 'part_no' THEN o.opt_value END) part_no
, MAX(CASE WHEN o.opt_name = 'stock' THEN o.opt_value END) stock
, p.product_status
FROM products p
JOIN product_options o
ON o.p_id = p.p_id
WHERE p.product_status = 'ordered'
GROUP
BY p.p_id;
或者,更快,但打字更多...
SELECT p.p_id
, p.product_name
, o1.opt_value part_no
, o2.opt_value stock
, p.product_status
FROM products p
LEFT
JOIN product_options o1
ON o1.p_id = p.p_id
AND o1.opt_name = 'part_no'
LEFT
JOIN product_options o2
ON o2.p_id = p.p_id
AND o2.opt_name = 'stock'
WHERE product_status = 'ordered'
您可以 JOIN
将以下两个查询组合在一起以获得结果 table:
SELECT t1.p_id, t1.product_name, t1.part_no, t2.stock, t1.product_status
FROM
(
SELECT products.p_id, products.product_name, products.product_status, po1.opt_value AS 'part_no'
FROM products INNER JOIN product_options AS po1
ON products.p_id = po1.p_id
WHERE po1.opt_name = 'part_no'
) AS t1
INNER JOIN
(
SELECT products.p_id, po2.opt_value AS 'stock'
FROM products INNER JOIN product_options AS po2
ON products.p_id = po2.p_id
WHERE po2.opt_name = 'stock'
) AS t2
ON t1.p_id = t2.p_id;
第一个 SELECT
(t1
) 通过将 product_options
中的产品限制为 opt_name
为 [=16= 的产品来获取每个产品的部件号].第二个SELECT
(t2
)使用类似的策略获得股票。
好吧,假设我有两个 tables products
和 product_options
.
结构tableproducts
如:
+--------------------------------------+
| p_id | product_name | product_status |
+--------------------------------------+
| 1 | Keyboard ABC | PENDING |
| 2 | Mouse ABC | ORDERED |
| 3 | Monitor ABC | ORDERED |
+--------------------------------------+
和table product_options
就像:
+--------------------------------------+
| po_id | p_id | opt_name | opt_value +
+--------------------------------------+
| 1 | 1 | part_no | KB-ABC-001 |
| 2 | 1 | stock | 0 |
| 3 | 2 | part_no | MS-ABC-001 |
| 4 | 2 | stock | 14 |
| 5 | 3 | part_no | MO-ABC-001 |
| 6 | 3 | stock | 10 |
+--------------------------------------+
问题是,我想同时显示 table 的查询,并且只显示我订购的产品的特定标准。结果如下:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | 14 | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | 10 | ORDERED |
+------------------------------------------------------------+
我的SQL查询是:
SELECT
t.p_id,
t.product_name,
(CASE WHEN t.key_name = 'part_no' THEN t.key_value ELSE NULL END) AS part_no,
(CASE WHEN t.key_name = 'stock' THEN t.key_value ELSE NULL END) AS stock,
t.product_status
FROM
(
SELECT
products.p_id as p_id,
products.product_name as product_name,
products.product_status as product_status,
product_options.opt_name as key_name,
product_options.opt_value as key_value
FROM
product_options Inner Join
products On product_options.p_id = products.p_id
WHERE
(products.product_status = 'ORDERED') AND
(product_options.opt_name = 'part_no' OR product_options.opt_name = 'stock')
) as t
GROUP BY t.p_id
我得到的是:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | NULL | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | NULL | ORDERED |
+------------------------------------------------------------+
但是,我想要的是在 stock
字段显示 NULL,因为 product_options
上的数据有:
+------------------------------------------------------------+
| p_id | product_name | part_no | stock | product_status |
+------------------------------------------------------------+
| 2 | Mouse ABC | MS-ABC-001 | 14 | ORDERED |
| 3 | Monitor ABC | MO-ABC-001 | 10 | ORDERED |
+------------------------------------------------------------+
问题是,如何显示/合并两个 table 这样的大小写?
我尝试使用 GROUP_CONCAT
,但这不是我要搜索的内容。
请帮忙。
试试这个查询:
select p.p_id p_id , p.product_name product_name ,
(select i.opt_value from product_options i where i.p_id=p.p_id and i.opt_name='part_no') part_no,
(select i.opt_value from product_options i where i.p_id=p.p_id and i.opt_name='stock') stock,
p.product_status product_status
from products p
where p.product_status='ORDERED';
你可以试试这个:
SELECT
p.p_id p_id ,
p.product_name product_name ,
po.opt_value_1 AS part_no,
po.opt_value_2 AS stock,
p.product_status product_status
FROM
products p LEFT JOIN (SELECT po1.p_id,
po1.opt_name AS opt_name_1,
po1.opt_value AS opt_value_1,
po2.opt_name AS opt_name_2,
po2.opt_value AS opt_value_2
FROM product_options po1
LEFT JOIN product_options po2
ON po1.p_id = po2.p_id
AND po1.opt_name != po2.opt_name
GROUP BY po1.p_id) AS po
ON p.p_id = po.p_id
WHERE p.product_status='ORDERED';
这里是 sqlfiddle.
SELECT p.p_id
, p.product_name
, MAX(CASE WHEN o.opt_name = 'part_no' THEN o.opt_value END) part_no
, MAX(CASE WHEN o.opt_name = 'stock' THEN o.opt_value END) stock
, p.product_status
FROM products p
JOIN product_options o
ON o.p_id = p.p_id
WHERE p.product_status = 'ordered'
GROUP
BY p.p_id;
或者,更快,但打字更多...
SELECT p.p_id
, p.product_name
, o1.opt_value part_no
, o2.opt_value stock
, p.product_status
FROM products p
LEFT
JOIN product_options o1
ON o1.p_id = p.p_id
AND o1.opt_name = 'part_no'
LEFT
JOIN product_options o2
ON o2.p_id = p.p_id
AND o2.opt_name = 'stock'
WHERE product_status = 'ordered'
您可以 JOIN
将以下两个查询组合在一起以获得结果 table:
SELECT t1.p_id, t1.product_name, t1.part_no, t2.stock, t1.product_status
FROM
(
SELECT products.p_id, products.product_name, products.product_status, po1.opt_value AS 'part_no'
FROM products INNER JOIN product_options AS po1
ON products.p_id = po1.p_id
WHERE po1.opt_name = 'part_no'
) AS t1
INNER JOIN
(
SELECT products.p_id, po2.opt_value AS 'stock'
FROM products INNER JOIN product_options AS po2
ON products.p_id = po2.p_id
WHERE po2.opt_name = 'stock'
) AS t2
ON t1.p_id = t2.p_id;
第一个 SELECT
(t1
) 通过将 product_options
中的产品限制为 opt_name
为 [=16= 的产品来获取每个产品的部件号].第二个SELECT
(t2
)使用类似的策略获得股票。