1

假设我有一个去年购物的亚马逊客户数据库。它非常详细,有姓名、年龄、邮政编码、收入水平、喜欢的颜色、食物、音乐等列。现在,假设我运行一个查询,返回所有购买 Book X 的亚马逊客户。

SELECT NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
FROM [Amazon].[dbo].[Customers]
WHERE BOOK = "X"

此查询将返回一堆购买了 Book X 的客户。现在,我想遍历每个结果(遍历每个客户)并根据每个客户的个人年龄、邮政编码和收入创建一个查询。

因此,如果第一个结果是 Bob,32 岁,居住在邮政编码 90210,年收入 45,000 美元,则创建一个查询以查找所有与 Bob 具有相同年龄、邮政编码和收入的其他人。如果第二个结果是 Mary,41 岁,居住在邮政编码 10004,年收入 55,000 美元,请创建一个查询以查找所有与 Mary 相同年龄、邮政编码和收入的其他人。

如何遍历购买了 Book X 的客户并运行多个值(年龄、邮政编码、收入)正在变化的查询?在查看结果方面,如果我能看到 Bob,然后是所有像 Bob 的客户,然后是 Mary,以及所有像 Mary 的客户,那就太好了。

这在 SQL 中甚至可能吗?我知道如何在 C# 中执行此操作(for/next 循环,其中包含 if/then 语句),但我是 SQL 新手,并且数据在 SQL 中。

我使用 SQL Server 2008。

4

4 回答 4

1

如果我正确理解了您的要求,那么嵌套查询应该可以完成这项工作。像这样的东西:

SELECT distinct NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
FROM [Amazon].[dbo].[Customers] a, (SELECT NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
FROM [Amazon].[dbo].[Customers]
WHERE BOOK = "X" and name = 'Bob') b
WHERE BOOK = "X" and a.age=b.age and a.zipcode= b.zipcode and a.income=b.income

编辑:通用查询将是[这将包含所有用户的列表]:

SELECT distinct NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
    FROM [Amazon].[dbo].[Customers] a, (SELECT distinct NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
    FROM [Amazon].[dbo].[Customers]
    WHERE BOOK = "X" ) b
    WHERE a.BOOK = b.book and a.age=b.age and a.zipcode= b.zipcode and a.income=b.income 
order by name
于 2013-06-17T15:35:08.917 回答
0

我认为您需要两个单独的查询。第一个带回客户,一旦选择了 Bob 等客户,第二个查询将基于 Bob 的属性执行。

一个简单的示例是具有两个网格的表单应用程序。第一个显示用户列表。当您选择其中一个用户时,第二个网格将填充第二个查询的结果。

第二个查询类似于:

SELECT NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
FROM [Amazon].[dbo].[Customers]
WHERE Age = @BobsAge AND ZipCode = @BobsZipCode AND Income = @BobsIncome

听起来你想要一个简单的自加入:

SELECT 
    MatchingCustomers.NAME, 
    MatchingCustomers.AGE, 
    MatchingCustomers.ZIPCODE, 
    MatchingCustomers.INCOME, 
    MatchingCustomers.FAVECOLOR, 
    MatchingCustomers.FAVEFOOD, 
    MatchingCustomers.FAVEMUSIC
FROM 
    [Amazon].[dbo].[Customers] SourceCustomer
    LEFT JOIN [Amazon].[dbo].[Customers] MatchingCustomers
        ON  SourceCustomer.Age = MatchingCustomer.Age
        AND SourceCustomer.ZipCode = MatchingCustomer.ZipCode 
        AND SourceCustomer.Income = MatchingCustomer.Income 
WHERE
    SourceCustomer.Book = 'X'

如果您想在单个结果集中查看所有源客户及其所有匹配项,您可以删除 where 子句并选择数据 SourceCustomer:

SELECT 
    SourceCustomer.Name SourceName,
    SourceCustomer.Age SourceAge 
    SourceCustomer.ZipCode SourceZipCode,
    SourceCustomer.Income SourceIncome,
    MatchingCustomers.NAME, 
    MatchingCustomers.AGE, 
    MatchingCustomers.ZIPCODE, 
    MatchingCustomers.INCOME, 
    MatchingCustomers.FAVECOLOR, 
    MatchingCustomers.FAVEFOOD, 
    MatchingCustomers.FAVEMUSIC
FROM 
    [Amazon].[dbo].[Customers] SourceCustomer
    LEFT JOIN [Amazon].[dbo].[Customers] MatchingCustomers
        ON  SourceCustomer.Age = MatchingCustomer.Age
        AND SourceCustomer.ZipCode = MatchingCustomer.ZipCode 
        AND SourceCustomer.Income = MatchingCustomer.Income 
WHERE
    SourceCustomer.Book = 'X'
于 2013-06-17T15:36:08.357 回答
0

这样的事情可以在一个查询中完成:

;WITH cteSource as
(
    SELECT NAME, AGE, ZIPCODE, INCOME, FAVECOLOR, FAVEFOOD, FAVEMUSIC
    FROM [Amazon].[dbo].[Customers]
    WHERE BOOK = "X"
)
SELECT sr.NAME AS SrcName, cu.NAME AS LikeName
FROM [Amazon].[dbo].[Customers] AS cu
JOIN cteSource As sr
    ON  cu.AGE      = sr.AGE
    And cu.ZIPCODE  = sr.ZIPCODE
    And cu.INCOME   = sr.INCOME
于 2013-06-17T15:58:35.337 回答
0

这样的事情会让您将相关客户追逐到任意的,例如这里的5,分离度。通过正确构建 JOIN,您可以执行诸如匹配某个范围内的收入之类的操作,...。

with Book as (
  select Id, Name, Age, ZIPCode, Income -- ...
    from Amazon.dbo.Customers
    where Book = 'X' ),
  RelatedCustomers as (
  select C.Id, C.Name, C.Age, C.ZIPCode, C.Income, 1 as Depth -- ...
    from Amazon.dbo.Customers as C inner join
      Book as B on B.Id <> C.Id and Abs( B.Income - C.Income ) < 2000 -- and ...
  union all
  select C.Id, C.Name, C.Age, C.ZIPCode, C.Income, RC.Depth + 1-- ...
    from Amazon.dbo.Customers as C inner join
      RelatedCustomers as RC on RC.Id <> C.Id and Abs( RC.Income - C.Income ) < 2000 -- and ...
      where Depth < 5 )
  select *
    from RelatedCustomers
于 2013-06-17T16:12:40.947 回答