选择第一个匹配的行

时间:2012-02-29 18:47:46

标签: sql ms-access

我有一个表“tbl”,看起来像这样:

prod | cust | qty
p1   | c1   | 5
p1   | c2   | 10
p2   | c1   | 2
p3   | c2   | 8

我需要的是产品和客户对的清单,但如果产品销售给多个客户,则只有第一个客户。换句话说,结果需要如下所示:

prod | cust
p1   | c1   
p2   | c1   
p3   | c2   

我已经尝试过每一种我能想到的方式,但是我无法得到正确的结果。很明显,既不是不同的也不是group by(因为它们都将返回p1,c2行)。

我发现这个question是一个非常接近的匹配,但我无法弄清楚如何重新编写它以使其完成我需要的工作。

最重要的是,目前所有这些都需要在Access 2007或更高版本中运行,但在将来某些时候它也需要在MySQL中运行。

对于也将结果加入到客户表中的任何人的额外信用,以便我可以从客户代码中查找人类可读的名称,例如c1 => Fred Bloggs扳手

4 个答案:

答案 0 :(得分:16)

核心问题:

SELECT prod, MIN(cust)
FROM yourTable
GROUP BY prod

对于“奖金”:

SELECT T.prod,
       T.cust,
       YC.SomeCustomerAttribute1,
       YC.SomeCustomerAttribute2
FROM (
      SELECT prod, MIN(cust) AS first_cust
      FROM yourProducts
      GROUP BY prod
) AS T
JOIN yourCustomers AS YC ON YC.cust = T.first_cust

答案 1 :(得分:2)

我将不得不假设您有某种标识符,表明谁是“第一”。日期列或标识列等。

在我的示例中,我使用order_id标识列完成了它。

CREATE TABLE products (
    order_id MEDIUMINT NOT NULL AUTO_INCREMENT,
    prod char(2), 
    cust char(2),
    qty int,
    PRIMARY KEY (order_id)
);

INSERT INTO products (prod, cust, qty) VALUES
   ('p1', 'c1', 5),
   ('p1', 'c2', 10),
   ('p2', 'c1', 2),
   ('p3', 'c2', 8);

然后运行您的值:

select p1.prod, p1.cust, p1.qty
from products p1
where not exists (select * from products p2
              where p1.prod = p2.prod
              and p2.order_id < p1.order_id)

在每一行上,您检查是否有任何其他客户比您更早订购它。如果有先前的订单,则不要列出此行。 (因此not exists

这是mysql语法,顺便说一句,你说你正在迁移到它。 (访问专家必须适当地编辑它。)

现在,如果您没有列标识用于指定订单输入顺序的列,则需要一个列。任何依赖于基于插入顺序的隐式row_numbering的方案最终都会崩溃,因为“第一行”不能保证保持不变。

答案 2 :(得分:1)

如果您只希望第一个结果为查询添加LIMIT 1,或使用SELECT DISTINCT获得唯一结果。

关于你的加入请查看:

SELECT * FROM TableA
INNER JOIN TableB
ON TableA.name = TableB.name

这将从tableA和tableB获得匹配name的所有行。

修改 J Cooper是对的,ms-access没有等同于LIMIT。最接近的是TOP,但我认为这不会有所帮助。抱歉,自大学以来没有使用访问权限。

答案 3 :(得分:0)

“First”和min()不一样。如果你真的想要第一个,试试这个:

declare @source table
(
    prod varchar(10),
    cust varchar(10),
    qty int
)

insert into @source (prod, cust, qty) values ('p1', 'c1', 5)
insert into @source (prod, cust, qty) values ('p1', 'c2', 10)
insert into @source (prod, cust, qty) values ('p2', 'c1', 2)
insert into @source (prod, cust, qty) values ('p3', 'c2', 8)

select * from @source

declare @target table
(
    prod varchar(10),
    cust varchar(10),
    qty int
)

insert into @target (prod)
select distinct prod from @source

update @target
set
    cust = s.cust,
    qty = s.qty
from @source s
join @target t on t.prod = s.prod

select * from @target