2012-02-29 98 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 
相關問題