表格布局:
CREATE TABLE t_order (id INT, custId INT, order DATE)
我正在寻找一个SQL命令来为每个订单选择最多一行(拥有该订单的客户由名为custId的字段标识)。
如果没有为任何行指定订单日期,我想选择客户订单的 ONE (无论哪一个,按ID排序)。
如果已存在具有给定订单日期的记录,我想检索customerId的空Resultset。
这是一个例子。每个客户最多应该有一个订单(一个没有给出日期)。已经存在日期值的订单根本不应出现。
+---------------------------------------------------------+ |id | custId | date | +---------------------------------------------------------+ | 1 10 NULL | | 2 11 2008-11-11 | | 3 12 2008-10-23 | | 4 11 NULL | | 5 13 NULL | | 6 13 NULL | +---------------------------------------------------------+ | | | Result \ | / \ / +---------------------------------------------------------+ |id | custId | date | +---------------------------------------------------------+ | 1 10 NULL | | | | | | | | 5 13 NULL | | | +---------------------------------------------------------+ powered be JavE
编辑: 我选择格拉维奇的答案是正确的,因为它提供了 稍微修改数据的正确结果:
+---------------------------------------------------------+ |id | custId | date | +---------------------------------------------------------+ | 1 10 NULL | | 2 11 2008-11-11 | | 3 12 2008-10-23 | | 4 11 NULL | | 5 13 NULL | | 6 13 NULL | | 7 11 NULL | +---------------------------------------------------------+
当客户出现两次以上因为其where子句约束a.id!= b.id时,Sfossen的答案将不起作用。
Quassnoi的答案对我不起作用,因为我运行服务器版本4.0.24,产生以下错误: alt text http://img25.imageshack.us/img25/8186/picture1vyj.png
答案 0 :(得分:2)
对于特定客户,它是:
SELECT *
FROM t_order
WHERE date IS NULL AND custId=? LIMIT 1
对于所有客户:
SELECT a.*
FROM t_order a
LEFT JOIN t_order b ON a.custId=b.custID and a.id != b.id
WHERE a.date IS NULL AND b.date IS NULL
GROUP BY custId;
答案 1 :(得分:1)
试试这个:
SELECT to1.*
FROM t_order AS to1
WHERE
to1.date IS NULL AND
to1.custId NOT IN (
SELECT to2.custId
FROM t_order AS to2
WHERE to2.date IS NOT NULL
GROUP BY to2.custId
)
GROUP BY to1.custId
对于MySQL 4:
SELECT to1.*
FROM t_order AS to1
LEFT JOIN t_order AS to2 ON
to2.custId = to1.custId AND
to2.date IS NOT NULL
WHERE
to1.date IS NULL AND
to2.id IS NULL
GROUP BY to1.custId
答案 2 :(得分:1)
此查询将在custId
上使用一次传递索引。
对于每个不同的custId
,它将在相同的索引上使用一个子查询。
没有GROUP BY
,没有TEMPORARY
和没有FILESORT
- 效率很高。
SELECT VERSION()
--------
'4.1.22-standard'
CREATE INDEX ix_order_cust_id ON t_order(custId)
SELECT id, custId, order_date
FROM (
SELECT o.*,
CASE
WHEN custId <> @c THEN
(
SELECT 1
FROM t_order oi
WHERE oi.custId = o.custId
AND order_date IS NOT NULL
LIMIT 1
)
END AS n,
@c <> custId AS f,
@c := custId
FROM
(
SELECT @c := -1
) r,
t_order o
ORDER BY custId
) oo
WHERE n IS NULL AND f
---------
1, 10, ''
5, 13, ''
答案 3 :(得分:0)
首先过滤掉带有日期的行,然后过滤掉具有较低ID的类似行的任何行。这应该有效,因为如果id是唯一的,具有最小id的匹配记录是唯一的。
select * from t_order o1
where date is null
and not exists (select * from t_order o2
where o2.date is null
and o1.custId = o2.custId
and o1.id > o2.id)