MySQL:枚举计数
MySQL: Enumerate and count
我有两个 table,table1
和 table2
。
table1
table.
示例
^ invoice ^ valid ^
| 10 | yes |
| 11 | yes |
| 12 | no |
示例 table2
table
^ invoice ^ detail ^
| 10 | A |
| 10 | C |
| 10 | F |
| 11 | A |
| 11 | F |
| 10 | E |
| 12 | A |
想要 select 来自 table 2 的所有行:
- 在 table 1
中有有效发票
并枚举:
- 每张发票的详细信息
- 发票
这里是想要的结果
^ invoice ^ detail ^ ordination ^ ordinationb ^
| 10 | A | 1 | 1 |
| 10 | C | 2 | 1 |
| 10 | F | 3 | 1 |
| 11 | A | 1 | 2 |
| 11 | F | 2 | 2 |
| 10 | E | 4 | 1 |
这句话应该适用于 phpMyAdmin 4.8.4
这是 MySQL 8+ 的实现方式:
SELECT
t2.Invoice,
t2.`lines`,
ROW_NUMBER() OVER (PARTITION BY t2.Invoice ORDER BY t2.`lines`) line_order,
DENSE_RANK() OVER (ORDER BY t2.Invoice) ordination
FROM table2 t2
WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.Invoice = t2.Invoice AND t1.valid = 'yes');
如果您使用的 MySQL 版本早于 8,那么您可能不得不求助于使用会话变量。这可能会导致难看的查询。如果您长期需要这样的查询,那么我建议升级到 MySQL 8+。
编辑:
我突然意识到我们可以使用相关子查询来模拟您的 ROW_NUMBER
和 DENSE_RANK
需求。这是在 MySQL 5.7 或更早版本中执行此查询的一种方法:
SELECT
t2.Invoice,
t2.detail,
(SELECT COUNT(*) FROM table2 t
WHERE t.Invoice = t2.Invoice AND t.detail <= t2.detail) ordination,
t.dr AS ordinationb
FROM table2 t2
INNER JOIN
(
SELECT DISTINCT
t2.Invoice,
(SELECT COUNT(*)
FROM (SELECT DISTINCT Invoice FROM table2) t
WHERE t.Invoice <= t2.Invoice) dr
FROM table2 t2
) t
ON t.Invoice = t2.Invoice
WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.Invoice = t2.Invoice AND t1.valid = 'yes')
ORDER BY
t2.Invoice,
t2.detail;
我有两个 table,table1
和 table2
。
table1
table.
^ invoice ^ valid ^
| 10 | yes |
| 11 | yes |
| 12 | no |
示例 table2
table
^ invoice ^ detail ^
| 10 | A |
| 10 | C |
| 10 | F |
| 11 | A |
| 11 | F |
| 10 | E |
| 12 | A |
想要 select 来自 table 2 的所有行:
- 在 table 1 中有有效发票
并枚举:
- 每张发票的详细信息
- 发票
这里是想要的结果
^ invoice ^ detail ^ ordination ^ ordinationb ^
| 10 | A | 1 | 1 |
| 10 | C | 2 | 1 |
| 10 | F | 3 | 1 |
| 11 | A | 1 | 2 |
| 11 | F | 2 | 2 |
| 10 | E | 4 | 1 |
这句话应该适用于 phpMyAdmin 4.8.4
这是 MySQL 8+ 的实现方式:
SELECT
t2.Invoice,
t2.`lines`,
ROW_NUMBER() OVER (PARTITION BY t2.Invoice ORDER BY t2.`lines`) line_order,
DENSE_RANK() OVER (ORDER BY t2.Invoice) ordination
FROM table2 t2
WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.Invoice = t2.Invoice AND t1.valid = 'yes');
如果您使用的 MySQL 版本早于 8,那么您可能不得不求助于使用会话变量。这可能会导致难看的查询。如果您长期需要这样的查询,那么我建议升级到 MySQL 8+。
编辑:
我突然意识到我们可以使用相关子查询来模拟您的 ROW_NUMBER
和 DENSE_RANK
需求。这是在 MySQL 5.7 或更早版本中执行此查询的一种方法:
SELECT
t2.Invoice,
t2.detail,
(SELECT COUNT(*) FROM table2 t
WHERE t.Invoice = t2.Invoice AND t.detail <= t2.detail) ordination,
t.dr AS ordinationb
FROM table2 t2
INNER JOIN
(
SELECT DISTINCT
t2.Invoice,
(SELECT COUNT(*)
FROM (SELECT DISTINCT Invoice FROM table2) t
WHERE t.Invoice <= t2.Invoice) dr
FROM table2 t2
) t
ON t.Invoice = t2.Invoice
WHERE EXISTS (SELECT 1 FROM table1 t1 WHERE t1.Invoice = t2.Invoice AND t1.valid = 'yes')
ORDER BY
t2.Invoice,
t2.detail;