在HAVING中使用通配符

时间:2017-07-05 18:35:24

标签: sql

我试图获取所有至少有2位客户使用雅虎电子邮件的国家/地区的列表。

到目前为止,我提出了这个问题:

SELECT Country 
FROM Customer
GROUP BY Country
HAVING COUNT(Email LIKE '%yahoo%')>= 2

但这不起作用。可能是因为我不能在HAVING子句中使用LIKE。我试图在where子句中使用它,但我不能在那里使用聚合函数。你知道怎么做这个吗?假设标准sql。 THX

2 个答案:

答案 0 :(得分:5)

使用条件聚合

Sub GetData()
Dim DataSheet As Worksheet
Dim EndDate As Date
Dim StartDate As Date
Dim Symbol As String
Dim qurl As String
Dim nQuery As Name
Dim LastRow As Integer

Application.ScreenUpdating = False
Application.DisplayAlerts = False
Application.Calculation = xlCalculationManual

Sheets("Data").Cells.Clear


Set DataSheet = ActiveSheet

StartDate = DataSheet.Range("startDate").Value
EndDate = DataSheet.Range("endDate").Value
Sheets("Data").Range("a1").CurrentRegion.ClearContents

'my ops here'
Sheets("Spread").Cells.Clear

Dim Last As Integer
Last = DataSheet.Range("K6000").End(xlUp).Row
Dim j As Integer
For j = 2 To Last
        If j < Last Then
        Symbol = DataSheet.Range("K" & j).Value
'On my Sheet, I have a list of symbols down Column K'
'********'


qurl = "http://finance.google.com/finance/historical?q=" & Symbol
qurl = qurl & "&startdate=" & MonthName(Month(StartDate), True) & _
       "+" & Day(StartDate) & "+" & Year(StartDate) & _
       "&enddate=" & MonthName(Month(EndDate), True) & _
       "+" & Day(EndDate) & "+" & Year(EndDate) & "&output=csv"

QueryQuote:
With Sheets("Data").QueryTables.Add(Connection:="URL;" & qurl, Destination:=Sheets("Data").Range("a1"))
    .BackgroundQuery = True
    .TablesOnlyFromHTML = False
    .Refresh BackgroundQuery:=False
    .SaveData = True
End With


'Below is where I think the error start. I'm not sure if the loop get iterated here before my nested loop is done..'
Sheets("Data").Range("a1").CurrentRegion.TextToColumns Destination:=Sheets("Data").Range("a1"), DataType:=xlDelimited, _
                                                       TextQualifier:=xlDoubleQuote, ConsecutiveDelimiter:=False, Tab:=True, _
                                                       Semicolon:=False, Comma:=True, Space:=False, other:=False

Sheets("Data").Columns("A:H").ColumnWidth = 15

LastRow = Sheets("Data").UsedRange.Row - 2 + Sheets("Data").UsedRange.Rows.Count




Sheets("Data").Sort.SortFields.Add Key:=Range("A2:A" & LastRow), _
                                   SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal

With Sheets("Data").Sort
    .SetRange Range("A1:G" & LastRow)
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
    .SortFields.Clear
End With

'My ops here'
Sheets("Spread").Cells(1, j) = Symbol
Dim k As Integer
k = Sheets("Data").Range("A1", Sheets("Data").Range("A1").End(xlDown)).Rows.Count


Dim i As Integer
For i = 2 To k - 1
If i < k - 1 Then
Sheets("Spread").Cells(i, j) = Sheets("Data").Cells(i, 2) & "~" & Sheets("Data").Cells(i, 5)
End If
Next i


End If
Next j
'Here is where I have a nested loop'

End Sub

或者只是将限制放在where子句中......这样就可以在计数可能提升之前施加限制;因为它只需要评估类似'%yahoo%'的电子邮件或者计算时的所有电子邮件;但是因为where子句无论如何都必须进行评估。我不确定哪种更快,无需测试。

SELECT Country 
FROM Customer 
GROUP BY Country 
HAVING SUM(case when Email like '%yahoo%' then 1 else 0 end )>= 2

虽然像%val%无法使用任何索引所以;也许不吧。但如果它像%yahoo.com'你会看到一个。 (如果索引在电子邮件中)

答案 1 :(得分:1)

使用CTE构建已过滤国家/地区的汇总列表。

设置测试数据

IF OBJECT_ID('tempdb.dbo.#td', 'U') IS NOT NULL
  DROP TABLE #td; 

CREATE TABLE #td ( country varchar(10), email varchar(20) ) ;

INSERT INTO #td ( country, email )
VALUES 
       ('US','bob@builder.com')
     , ('GB','bob@yahoo.com')
     , ('US','bill@yahoo.com')
     , ('US','ted@yahoo.com')
     , ('FR','joe@friday.com')
     , ('GR','jim@gmail.com')
     , ('NZ','mrmaori@yahoo.com')
     , ('NZ','kiwi@yahoo.com')    
     , ('US','rufus@yahoo.com')
;

QUERY

WITH CTE AS(
   SELECT country, count(*) AS countryCount
   FROM #td
   WHERE email LIKE '%yahoo%'
   GROUP BY country
)
SELECT CTE.country
FROM CTE 
WHERE CTE.countryCount >= 2
;

这将使新西兰和美国成为仅有的两个国家。美国有3个雅虎和1个非雅虎。新西兰有2个雅虎。 GB只有1个雅虎并被排除在外。