2012-02-29 94 views
10

我有一个表“TBL”它看起来像这样:选择第一个匹配行

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

我需要的是产品和客户对独特的列表,但只有第一个客户,如果产品销售到不止一个客户。为了词的结果需要是这样的:

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

我已经试过这其中每一个我能想到的办法,但我不能完全得到正确的结果。很明显,既不区分也不分群,因为它们都会返回p1,c2行。

我发现这个question这是一个非常接近的比赛,但我无法弄清楚如何重新写来得到它做什么,我需要。

最糟糕的是这一切的当前需要在Access 2007或更高版本的工作,但在未来的某个时刻,它会需要在MySQL中正常工作。

额外信用的人谁也加入结果给客户表,这样我可以从客户代码查找人类可读的名字,例如: c1 => Fred Bloggs扳手

+1

你如何定义“第一个客户”?是否有一个日期字段明确表明你没有显示? – 2012-02-29 18:53:21

+0

我定义“第一个”是查询返回的任何一个 - 我会很高兴与p1,c1或p1,c2被返回我无法应付两个被返回(因为产品代码正在使用另一个连接,我不想重复)。表tbl中没有其他有用的字段。 – wobblycogs 2012-02-29 19:01:12

+1

好的,我在发布答案后阅读此评论 - 这没有意义 - 您希望“第一”客户,但实际上并不关心“第一”客户是谁或他们如何确定?我没有写出你的要求,但是你真的很想随机抽取结果吗?!? – 2012-02-29 19:25:45

回答

13

核心问题:

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

+1虽然我开始怀疑OP只是想'SELECT DISTINCT prod FROM table' – Fionnuala 2012-02-29 19:19:17

+0

非常感谢您的答案,发现我想要的东西。我从来没有想过使用min。 – wobblycogs 2012-02-29 19:21:13

1

如果您只想要第一个结果,请将LIMIT 1添加到您的查询中,或使用SELECT DISTINCT获取唯一结果。

为您的加盟检查了这一点:

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

这将让来自表A和tableB的一个匹配name所有行。

编辑 J库珀是正确的,MS访问没有相当于LIMIT。最接近的是TOP,但我认为这不会有帮助。对不起,大学以后没有使用过。

+0

我不想要_just_第一行。我也想要p2,c1和p3,c2行。限制会导致只有p1,c1被返回。 – wobblycogs 2012-02-29 19:04:49

+2

我很确定ms-access不支持'LIMIT'。 – 2012-02-29 19:04:59

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的方案最终都会分崩离析,因为“第一行”不保证保持不变。

+0

据我所知MS Access不支持'存在' – 2012-02-29 19:25:34

+0

MS Access支持'存在'。 – HansUp 2012-02-29 19:30:00

+0

你可能对访问是正确的 - 我使用了很多数据库,但没有访问,我认为这是ANSI,但显然不是。应该把关于mysql的限定词放在更高的位置(他说他最终需要)。我仍然会强调我的讨论,即做任何事情都需要某种序列/日期时间标识符。但是因为他只是想要一个随机的结果,那么无论如何。 。 。 – 2012-02-29 19:33:39

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 
相关问题