2009-03-03 64 views
0

我有一個名爲name_email的名稱和電子郵件的簡單表。不同的sql查詢

我想取出來的數據,以便: 如果兩行具有相同的名稱的,但是這與「@ yahoo.com」,而另一個具有不同的電子郵件結尾的電子郵件,那麼應該放棄使用「@​​ yahoo.com」電子郵件的人。

什麼是最好的方式來獲取這些數據?

回答

3

好的,我不打算介入另一場與那些說我不應該主張數據庫模式更改(是的,你知道你是誰:-)的鬥爭,但這是我該怎麼做。如果你絕對不能改變模式,我會用代碼解決它(無論是在數據庫之外的真正誠實的程序代碼,或是你DBMS允許的任何語言的存儲過程)。

這將檢查數據庫中的非雅虎名稱並返回它,如果有的話。如果不存在,它會嘗試返回雅虎名稱。如果兩者都不存在,它將返回一個空數據集。

2 /如果您可以更改模式,並且您希望使用SQL查詢來完成這項工作,那麼我將如何執行此操作。在表格中創建一個名爲CLASS的獨立列,對於非雅虎地址,預計將設置爲0,對於雅虎地址,則爲1。

創建插入/更新觸發器來檢查每行添加或更改,根據電子郵件地址(結尾)設置CLASS。這保證CLASS將始終正確設置。

當您查詢您的表時,按名稱和類對其排序,並且只選擇第一行。這將爲您提供以下首選項的電子郵件地址:非雅虎,雅虎,空數據集。

喜歡的東西:

select name, email 
from tbl 
where name = '[name]' 
order by name, class 
fetch first row only; 

如果你的DBMS不具有等同於DB2「取第一行只有」條款,你可能仍然需要編寫代碼來只處理一個記錄。

如果你要處理該名稱的所有名稱,但只有特定所需的電子郵件,一個程序,這樣就足夠了(在試圖以程序的方式來使用關係代數如SQL我的看法是相當殘酷的,所以我也不會造成他們對你在這裏):

# Get entire table contents sorted in name/class order. 
resultSet = execQuery "select name, email from tbl order by name, class" 

# Ensure different on first row 
lastName = resultSet.value["name"] + "X" 

# Process every single row returned. 
while not resultSet.endOfFile: 
    # Only process the first in each name group (lower classes are ignored). 
    if resultSet.value["name"] != lastName: 
     processRow resultSet.value["name"] resultSet.value["email"] 
    # Store the last name so we can detect next name group. 
    lastName = resultSet.value["name"] 
0

您可以使用類似下面以排除無效的電子郵件地址:

SELECT name, email 
FROM name_email 
WHERE email NOT LIKE '%@yahoo.com' // % symbol is a wildcard so [email protected] and [email protected] both match this query. 
AND name = 'Joe Guy'; 

還是不喜歡這樣,以只包括有效的電子郵件地址或域名:

SELECT name, email 
FROM name_email 
WHERE email LIKE '%@gmail.com' 
AND name = 'Joe Guy'; 

這種運作良好,如果您事先知道要查詢的具體名稱以及要排除或包含的電子郵件地址或域名。

或者,如果你不關心你返回的電子郵件地址,但只想要回一個,你可以使用這樣的事情:

SELECT DISTINCT (name, email) 
FROM name_email; 
+0

多數民衆贊成在事。我不知道名稱提前:)我正在尋找重複的名字。 – Omnipresent 2009-03-03 05:28:27

+0

第二個使用DISTINCT運算符會更好嗎? – 2009-03-03 05:33:19

+0

如果您有其他條件,例如每個有兩個電子郵件地址的名稱都應該總是返回x電子郵件地址,那麼請編輯您的問題以反映該問題。 – 2009-03-03 05:34:47

0

你可以做

SELECT TOP 1 email 
FROM name_email 
WHERE name = 'Joe Guy' 
ORDER BY case when email like '%yahoo.com' then 1 else 0 end 

所以對它們進行排序通過*@yahoo.com最後和其他任何第一,並採取第一個。

編輯:對不起,錯誤的問題 - 你想每個名稱的列表,只有一個電子郵件,和非雅虎電子郵件的首選項。大概可以和上面一起使用,我不得不重新考慮它。

+0

這將工作,但我不是選擇方每行處理的忠實粉絲。這是應該使用單獨的列和觸發器來完成的事情。根據我的經驗,大多數表格的閱讀次數遠多於書面形式。設置排序順序的插入/更新端過程更好IMNSHO :-)。 – paxdiablo 2009-03-03 05:47:18

0

抓住所有行從數據庫中,知道名字都沒有什麼(不需要關心真的),但只是希望他們展示,如果匹配,則跳過匹配,如果電子郵件中包含,在這種情況下,@ yahoo.com

SELECT DISTINCT name, email FROM name_email 
    WHERE email NOT LIKE '%@yahoo.com' 
    GROUP BY name; 

這樣做會抓取所有行,但只有其中一個記錄如果名稱與另一行匹配。但是,如果有兩行名稱匹配的垃圾郵件,則在電子郵件中使用@ yahoo.com垃圾郵件。

1
select ne.* 
from name_email ne 
where ne.email not like '%@yahoo.com' escape '\' or 
    not exists(
       select 1 from name_email 
       where name = ne.name and 
       email not like '%@yahoo.com' escape '\' 
      ) 
0

不是很漂亮,但我相信它應該工作

select 
    ne.name 
    ,ne.email 
from 
    name_email ne 
    inner join (
     select 
      name 
      ,count(*) as emails_per_name 
     from 
      name_email 
     group by name 
    ) nec 
     on ne.name = nec.name 
where 
    nec.emails_per_name = 1 
    or (nec.emails_per_name > 1 and ne.email not like ('%@yahoo.com')) 

即假定重複的電子郵件將是yahoo.com域名 - 在你的問題中指定,而這些將被排除如果每個名稱有多個電子郵件

0

如果您正在使用SQL Server 2005或Oracle,則可以使用排名(分析)功能輕鬆解決您的問題。

select a.name, a.name_email 
from (select name, name_email, 
      row_number() over (partition by name 
           order by case 
              when name_email like '%@yahoo.com' then 1 
              when name_email like '%@gmail.com' then 1 
              when ... (other 'generic' email) then 1 
              else 0 
             end) as rn) as a 
where a.rn = 1 

通過爲各種通用電子郵件名稱分配不同的值,您甚至可以選擇'首選項'。正如它在這裏寫的,如果你有一個雅虎和Gmail的地址,你不能預測哪一個會被挑選出來。

0

你可以爲此使用一個UNION。選擇沒有yahoo.com的所有內容,然後選擇具有yahoo.com並且不在第一個列表中的記錄。

SELECT DISTINCT(姓名,name_email)FROM TABLE WHERE name_email NOT '%yahoo.com' UNION SELECT DISTINCT(姓名,name_email)FROM TABLE WHERE名稱NOT IN(SELECT DISTINCT(姓名,name_email)FROM TABLE WHERE name_email NOT'%yahoo.com')