Sql 合并和组?
好的。我有一个如下的查询:Sql 合并和组?,sql,mysql,Sql,Mysql,好的。我有一个如下的查询: SELECT SUM(`order_items`.`quantity`) as `count`, `menu_items`.`name` FROM `orders`, `menu_items`, `order_items` WHERE `orders`.`id` = `order_items`.`order_id` AND `menu_items`.`id` = `order_items`.`menu_i
SELECT
SUM(`order_items`.`quantity`) as `count`,
`menu_items`.`name`
FROM
`orders`,
`menu_items`,
`order_items`
WHERE
`orders`.`id` = `order_items`.`order_id` AND
`menu_items`.`id` = `order_items`.`menu_item_id` AND
`orders`.`date` >= '2008-11-01' AND
`orders`.`date` <= '2008-11-30'
GROUP BY
`menu_items`.`id`
选择
总和(`order\u items`.`quantity`)为`count`,
`菜单项`.`名称`
从…起
`订单`,
`菜单项`,
`订购商品`
哪里
`订单`.`id`=`order\u items`.`order\u id`和
`菜单项`.`id`=`订单项`.`菜单项`.`id`和
`订单`.`日期`>='2008-11-01'和
`orders`.`date`Randy的答案很接近,但是where语句删除了对那些不属于该日期范围内任何订单的项目的任何提及
请注意,“左连接”与where子句中链接表的方式不同(即内部连接)。我建议您仔细阅读不同类型的SQL联接(内部联接、外部联接、交叉联接)
在essense中,您需要将从Randy的查询中获得的数据与您的源项列表相关联。使用子选择将执行以下操作:
SELECT
name
, nvl(count, 0) as count
FROM
menu_items items
LEFT JOIN (
SELECT
menu_items.id
, SUM(order_items.quantity) as count
FROM
menu_items
LEFT JOIN order_items ON menu_items.id = order_items.menu_item_id
LEFT JOIN orders ON orders.id = order_items.order_id
WHERE
"date" between to_date('2008-11-01','YYYY-MM-DD') and to_date('2008-11-30','YYYY-MM-DD')
GROUP BY
menu_items.id
) counts on items.id = counts.id;
这是在Oracle 10g BTW中。我怀疑您正在使用Oracle,所以您需要转换到您自己的数据库
运行测试将显示以下内容:
SQL> create table menu_items ( id number, name varchar2(10));
create table order_items (order_id number, menu_item_id number, quantity number);
create table orders (id number, "date" date);
Table created.
SQL>
Table created.
SQL>
Table created.
SQL>
insert into menu_items values (1, 'bread');
insert into menu_items values (2, 'milk');
insert into menu_items values (3, 'honey');
insert into menu_items values (4, 'cheese');
SQL>
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
insert into orders values (1, to_date('2008-11-02', 'YYYY-MM-DD'));
insert into orders values (2, to_date('2008-11-03', 'YYYY-MM-DD'));
insert into orders values (3, to_date('2008-10-29', 'YYYY-MM-DD'));SQL>
1 row created.
SQL>
1 row created.
SQL>
insert into order_items values (1, 1, 1);
insert into order_items values (1, 3, 1);
1 row created.
SQL>
1 row created.
SQL>
insert into order_items values (2, 1, 1);
insert into order_items values (2, 2, 1);
insert into order_items values (2, 3, 1);
insert into order_items values (3, 4, 10);
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL>
1 row created.
SQL> SQL>
1 row created.
SQL>
SELECT
name
, nvl(count, 0) as count
FROM
menu_items items
LEFT JOIN (
SELECT
menu_items.id
, SUM(order_items.quantity) as count
FROM
menu_items
LEFT JOIN order_items ON menu_items.id = order_items.menu_item_id
LEFT JOIN orders ON orders.id = order_items.order_id
WHERE
"date" between to_date('2008-11-01','YYYY-MM-DD') and to_date('2008-11-30','YYYY-MM-DD')
GROUP BY
menu_iteSQL> 2 3 4 5 6 7 ms.id
) counts on items.id = counts.id; 8 9 10 11 12 13 14 15 16 17 18
NAME COUNT
---------- ----------
bread 2
milk 1
honey 2
cheese 0
SQL>
drop table menu_items;
drop table order_items;
drop table orders;SQL>
Table dropped.
SQL>
Table dropped.
SQL>
Table dropped.
SQL>
PS:使用“date”作为列名是一种不好的做法,因为它(在大多数情况下)是一种类型名,并且可能会导致查询和解析问题。如果将日期条件放在JOIN
子句中,这可以在没有任何子查询的情况下完成
下面是我在MySQL 5.0上测试的代码
SELECT m.name, COALESCE(SUM(oi.quantity), 0) AS count
FROM menu_items AS m
LEFT OUTER JOIN (
order_items AS oi JOIN orders AS o
ON (o.id = oi.order_id)
) ON (m.id = oi.menu_item_id
AND o.`date` BETWEEN '2008-11-01' AND '2008-11-30')
GROUP BY m.id;
输出:
+--------+-------+
| name | count |
+--------+-------+
| bread | 2 |
| milk | 1 |
| honey | 2 |
| cheese | 0 |
+--------+-------+
以下是MySQL风格的DDL和设置代码:
DROP TABLE IF EXISTS menu_items;
CREATE TABLE menu_items (
id INT PRIMARY KEY,
name VARCHAR(10)
) TYPE=InnoDB;
DROP TABLE IF EXISTS orders;
CREATE TABLE orders (
id INT PRIMARY KEY,
`date` DATE
) TYPE=InnoDB;
DROP TABLE IF EXISTS order_items;
CREATE TABLE order_items (
order_id INT,
menu_item_id INT,
quantity INT,
PRIMARY KEY (order_id, menu_item_id),
FOREIGN KEY (order_id) REFERENCES orders(id),
FOREIGN KEY (menu_item_id) REFERENCES menu_items(id)
) TYPE=InnoDB;
INSERT INTO menu_items VALUES
(1, 'bread'),
(2, 'milk'),
(3, 'honey'),
(4, 'cheese');
INSERT INTO orders VALUES
(1, '2008-11-02'),
(2, '2008-11-03'),
(3, '2008-10-29');
INSERT INTO order_items VALUES
(1, 1, 1),
(1, 3, 1),
(2, 1, 1),
(2, 2, 1),
(2, 3, 1),
(3, 4, 10);
做得好,杰米。1子查询比我的少,而且更合理。MySQL唯一需要改变的是去掉Oracle的日期函数+1我的需求显然比我发布的查询复杂一点,但我用它来构建,现在它运行得很好。谢谢。