从SQL Server表中检索每个类别的不同行数

时间:2011-08-11 18:02:15

标签: sql sql-server

我需要生成一个我的客户要发送商品目录的地址列表。他们想要将特定数量的目录(X)发送到特定的邮政编码(Y)[这与这些邮政编码中的平均收入有关]

我在SQL Server 2008 R2中有2个表:CatalogRequestsAddressList

CatalogRequests是我们应该向客户数据库中的每个邮政编码发送多少目录的列表:

|  Zip  |  QuantityRequested  |
-------------------------------
| 12345 |         150         |
| 13445 |         800         |
| 45678 |         200         |
| 41871 |         350         |
| 77777 |         125         |

AddressList只是一个地址列表=)

|  Name  |     Address1    |  Address2  |      City     |  State  |  Zip  |
---------------------------------------------------------------------------
|  Bruce | 1 BatCave Dr    |            |  Gotham City  |   IL    | 12345 |
|  Clark | 9 Smallville St |   Apt A    |  Metropolis   |   NY    | 45678 |
|  Thor  | 5 Valhalla Way  |            |    Asgard     |   ??    | 77777 |

我试着用SQL查询做了一会儿,然后放弃并编写了一个小的C#程序来完成我需要做的事情(基本上,生成一堆SQL查询 - 每个记录一个在CatalogRequests)。

我的问题是,我怎么能用一个SQL查询完成这个?我只是好奇这一点,好像有办法做到这一点而我只是失踪了一些东西。或者可能不可能,我很疯狂=)

结果集将是满足AddressList中要求的CatalogRequest的记录(例如,150条邮政编码为12345的记录,800条记录,邮政编码为13445等)。

3 个答案:

答案 0 :(得分:11)

嗯......这样的事情怎么样:

;with addressListWithID 
AS 
(
    SELECT name, address1, adress2, city, state, zip, 
           ROW_NUMBER() OVER(partition by zip   order by newid()) as Row
    FROM AddressList 
)
SELECT A.name, A.address1, A.adress2, A.city, A.state, A.zip
FROM addressListWithID A 
    INNER JOIN CatalogRequests C
        ON C.zip = A.zip 
            AND A.row <= C.QuantityRequested 

请求数量的随机地址。

答案 1 :(得分:5)

未经测试,因为没有DDL且没有测试数据:

SELECT  A.name ,
        A.address1 ,
        A.adress2 ,
        A.city ,
        A.[state] ,
        A.zip
FROM    CatalogRequests AS C
        CROSS APPLY ( SELECT TOP ( C.QuantityRequested )
                                A.name ,
                                A.address1 ,
                                A.adress2 ,
                                A.city ,
                                A.[state] ,
                                A.zip
                      FROM      addressListWithID AS A
                      WHERE     C.zip = A.zip
                    ) AS A

答案 2 :(得分:4)

一种方法是使用动态SQL (which is dangerous and not to be taken lightly)

DECLARE @SQL varchar(max)

SET @SQL = 'USE Database'

SELECT @SQL = @SQL + 'SELECT TOP ' 
            + QuantityRequired
            + ' * FROM AddressList WHERE Zip = '
            + Zip
            + ' UNION ALL'
FROM CatalogRequests

SET @SQL = LEFT(@SQL, (LEN(@SQL - 10))) -- remove last UNION ALL 

PRINT (@SQL)

-- EXEC (@SQL)

检查有关动态SQL的规范参考的链接。