如何将第三列包含在 SELECT 中 MIN
How can I include third column in a SELECT with MIN
在此查询中,我还想在同一个查询中 SELECT 第三列 wp_postmeta.post_id
。如果不通过涉及子查询的 JOIN 附加它,我无法弄清楚如何执行此操作。有没有不使用子查询的更简单的方法? (如果解决方案高效且不太占用资源,愿意在子查询上让步。)
MariaDB 10.1
create table wp_posts (
ID integer primary key auto_increment,
post_title varchar(30),
post_type varchar(30)
);
✓
create table wp_postmeta (
ID integer primary key auto_increment,
post_id integer,
meta_key varchar(30) not null default '_regular_price',
meta_value integer not null
);
✓
insert into wp_posts (post_title, post_type) values
('Apple Pie','Product'),
('French Toast','Product'),
('Shepards Pie','Product'),
('Jam Pie','Product'),
('Jam Pie','Product'),
('Plate','Not a Product'),
('Bucket','Not a Product'),
('Chequebook','Not a Product'),
('French Toast','Product'),
('French Toast','Product'),
('Banana','Product'),
('Banana','Product'),
('Banana','Product');
✓
insert into wp_postmeta (post_id, meta_value) values
(1,10),
(2,5),
(3,9),
(4,8),
(5,11),
(6,12),
(7,10),
(8,6),
(9,1),
(10,1),
(11,7),
(12,2),
(13,2);
✓
SELECT wp_posts.post_title, MIN(wp_postmeta.meta_value) FROM wp_postmeta JOIN wp_posts
ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product' AND wp_postmeta.meta_key = '_regular_price'
GROUP BY wp_posts.post_title
ORDER BY wp_posts.post_title
post_title | MIN(wp_postmeta.meta_value)
:----------- | --------------------------:
Apple Pie | 10
Banana | 2
French Toast | 1
Jam Pie | 8
Shepards Pie | 9
db<>fiddle here
编辑:我在最初的问题中不够清楚和明确 - 我想折叠重复的 post_titles
并使用对应于 MIN(pm.meta_value)
[=26 的 wp_postmeta.post_id
=]
你不能把它包含在 GROUP BY
中吗?
SELECT p.post_title, p.id, MIN(pm.meta_value)
FROM wp_postmeta pm JOIN
wp_posts p
ON pm.post_id = p.id
WHERE p.post_type = 'Product' AND pm.meta_key = '_regular_price'
GROUP BY p.post_title, p.id
ORDER BY p.post_title;
post_id
与p.id
相同,所以你不妨使用它。
编辑:
如果标题可以重复,那么简单地使用相关子查询:
SELECT p.post_title, p.id, pm.meta_value
FROM wp_postmeta pm JOIN
wp_posts p
ON pm.post_id = p.id
WHERE p.post_type = 'Product' AND
pm.meta_key = '_regular_price' AND
pm.meta_value = (SELECT MIN(pm2.meta_value)
FROM wp_postmeta pm2 JOIN
wp_posts p2
ON pm2.post_id = p2.id
WHERE p2.post_title = p.post_title
)
ORDER BY p.post_title;
如果我没听错,你的问题可以使用 window 函数解决 :
SELECT x.post_title, x.id
FROM (
SELECT wp_posts.post_title, wp_postmeta.id, ROW_NUMBER() OVER (PARTITION BY wp_posts.post_title ORDER BY wp_postmeta.meta_value) rn
FROM wp_postmeta
INNER JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product' AND wp_postmeta.meta_key = '_regular_price'
) x WHERE x.rn = 1;
Window 函数是处理此类用例的方法(如果我理解正确的话)。他们通常在效率和可读性方面击败其他解决方案。
如果您的 RDBMS 不支持 window 函数,一种解决方案是使用具有 NOT EXISTS 条件的相关子查询,以确保没有记录具有给定 [=33= 的更小元值] 标题.
SELECT p.post_title, MIN(m.id)
FROM
wp_postmeta m
INNER JOIN wp_posts p
ON p.id = m.post_id
AND p.post_type = 'Product'
WHERE
m.meta_key = '_regular_price'
AND NOT EXISTS (
SELECT 1
FROM
wp_postmeta m1
INNER JOIN wp_posts p1
ON p1.id = m1.post_id
AND p1.post_type = 'Product'
WHERE
m1.meta_key = '_regular_price'
AND p1.post_title = p.post_title
AND m1.meta_value < m.meta_value
)
GROUP BY p.post_title
注意:我在你的 SQL 中做了一些清理(添加了 table 别名并将一些条件移动到相关连接的 then ON 子句中)。
您可以使用 CTE 托盘:
WITH T1
AS ( SELECT post_title, MIN(id) AS ID
FROM wp_posts
GROUP BY post_title )
SELECT T1.ID, wp_posts.post_title, MIN(wp_postmeta.meta_value)
FROM wp_postmeta
JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
JOIN T1 ON T1.post_title = wp_posts.post_title
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
GROUP BY T1.ID, wp_posts.post_title
ORDER BY wp_posts.post_title;
编辑:
你的 table wp_posts 应该是这样的
Id, post_title, post_type
1, 'Apple Pie','Product'
2, 'French Toast','Product'
3, 'Shepards Pie','Product'
4, 'Jam Pie','Product'
5, 'Plate','Not a Product'
6, 'Bucket','Not a Product'
7, 'Chequebook','Not a Product'
8, 'Banana','Product'
比你在 wp_postmeta table 这样的数据
post_id, meta_value
1, 10
2, 5
3, 9
4, 8
4, 11
5, 12
6, 10
7, 6
2, 1
2, 1
8, 7
8, 2
8, 2
查询看起来像这样
SELECT wp_postmeta.post_id, wp_posts.post_title, MIN(wp_postmeta.meta_value)
FROM wp_postmeta
JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = 'REG PRICE'
GROUP BY wp_postmeta.post_id, wp_posts.post_title
ORDER BY wp_posts.post_title;
在此查询中,我还想在同一个查询中 SELECT 第三列 wp_postmeta.post_id
。如果不通过涉及子查询的 JOIN 附加它,我无法弄清楚如何执行此操作。有没有不使用子查询的更简单的方法? (如果解决方案高效且不太占用资源,愿意在子查询上让步。)
MariaDB 10.1
create table wp_posts ( ID integer primary key auto_increment, post_title varchar(30), post_type varchar(30) );
✓
create table wp_postmeta ( ID integer primary key auto_increment, post_id integer, meta_key varchar(30) not null default '_regular_price', meta_value integer not null );
✓
insert into wp_posts (post_title, post_type) values ('Apple Pie','Product'), ('French Toast','Product'), ('Shepards Pie','Product'), ('Jam Pie','Product'), ('Jam Pie','Product'), ('Plate','Not a Product'), ('Bucket','Not a Product'), ('Chequebook','Not a Product'), ('French Toast','Product'), ('French Toast','Product'), ('Banana','Product'), ('Banana','Product'), ('Banana','Product');
✓
insert into wp_postmeta (post_id, meta_value) values (1,10), (2,5), (3,9), (4,8), (5,11), (6,12), (7,10), (8,6), (9,1), (10,1), (11,7), (12,2), (13,2);
✓
SELECT wp_posts.post_title, MIN(wp_postmeta.meta_value) FROM wp_postmeta JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id WHERE wp_posts.post_type = 'Product' AND wp_postmeta.meta_key = '_regular_price' GROUP BY wp_posts.post_title ORDER BY wp_posts.post_title
post_title | MIN(wp_postmeta.meta_value) :----------- | --------------------------: Apple Pie | 10 Banana | 2 French Toast | 1 Jam Pie | 8 Shepards Pie | 9
db<>fiddle here
编辑:我在最初的问题中不够清楚和明确 - 我想折叠重复的 post_titles
并使用对应于 MIN(pm.meta_value)
[=26 的 wp_postmeta.post_id
=]
你不能把它包含在 GROUP BY
中吗?
SELECT p.post_title, p.id, MIN(pm.meta_value)
FROM wp_postmeta pm JOIN
wp_posts p
ON pm.post_id = p.id
WHERE p.post_type = 'Product' AND pm.meta_key = '_regular_price'
GROUP BY p.post_title, p.id
ORDER BY p.post_title;
post_id
与p.id
相同,所以你不妨使用它。
编辑:
如果标题可以重复,那么简单地使用相关子查询:
SELECT p.post_title, p.id, pm.meta_value
FROM wp_postmeta pm JOIN
wp_posts p
ON pm.post_id = p.id
WHERE p.post_type = 'Product' AND
pm.meta_key = '_regular_price' AND
pm.meta_value = (SELECT MIN(pm2.meta_value)
FROM wp_postmeta pm2 JOIN
wp_posts p2
ON pm2.post_id = p2.id
WHERE p2.post_title = p.post_title
)
ORDER BY p.post_title;
如果我没听错,你的问题可以使用 window 函数解决 :
SELECT x.post_title, x.id
FROM (
SELECT wp_posts.post_title, wp_postmeta.id, ROW_NUMBER() OVER (PARTITION BY wp_posts.post_title ORDER BY wp_postmeta.meta_value) rn
FROM wp_postmeta
INNER JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product' AND wp_postmeta.meta_key = '_regular_price'
) x WHERE x.rn = 1;
Window 函数是处理此类用例的方法(如果我理解正确的话)。他们通常在效率和可读性方面击败其他解决方案。
如果您的 RDBMS 不支持 window 函数,一种解决方案是使用具有 NOT EXISTS 条件的相关子查询,以确保没有记录具有给定 [=33= 的更小元值] 标题.
SELECT p.post_title, MIN(m.id)
FROM
wp_postmeta m
INNER JOIN wp_posts p
ON p.id = m.post_id
AND p.post_type = 'Product'
WHERE
m.meta_key = '_regular_price'
AND NOT EXISTS (
SELECT 1
FROM
wp_postmeta m1
INNER JOIN wp_posts p1
ON p1.id = m1.post_id
AND p1.post_type = 'Product'
WHERE
m1.meta_key = '_regular_price'
AND p1.post_title = p.post_title
AND m1.meta_value < m.meta_value
)
GROUP BY p.post_title
注意:我在你的 SQL 中做了一些清理(添加了 table 别名并将一些条件移动到相关连接的 then ON 子句中)。
您可以使用 CTE 托盘:
WITH T1
AS ( SELECT post_title, MIN(id) AS ID
FROM wp_posts
GROUP BY post_title )
SELECT T1.ID, wp_posts.post_title, MIN(wp_postmeta.meta_value)
FROM wp_postmeta
JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
JOIN T1 ON T1.post_title = wp_posts.post_title
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = '_regular_price'
GROUP BY T1.ID, wp_posts.post_title
ORDER BY wp_posts.post_title;
编辑:
你的 table wp_posts 应该是这样的
Id, post_title, post_type
1, 'Apple Pie','Product'
2, 'French Toast','Product'
3, 'Shepards Pie','Product'
4, 'Jam Pie','Product'
5, 'Plate','Not a Product'
6, 'Bucket','Not a Product'
7, 'Chequebook','Not a Product'
8, 'Banana','Product'
比你在 wp_postmeta table 这样的数据
post_id, meta_value
1, 10
2, 5
3, 9
4, 8
4, 11
5, 12
6, 10
7, 6
2, 1
2, 1
8, 7
8, 2
8, 2
查询看起来像这样
SELECT wp_postmeta.post_id, wp_posts.post_title, MIN(wp_postmeta.meta_value)
FROM wp_postmeta
JOIN wp_posts ON wp_postmeta.post_id = wp_posts.id
WHERE wp_posts.post_type = 'Product'
AND wp_postmeta.meta_key = 'REG PRICE'
GROUP BY wp_postmeta.post_id, wp_posts.post_title
ORDER BY wp_posts.post_title;