0

这是我的情况的工作流程:

我有一个网站,允许注册用户注册当地奖品赞助商(即:企业)的奖品例如,可能有一个页面将必胜客作为奖品赞助商,注册/认证用户只需点击“输入绘图”,一旦他们这样做,他们就不能再次点击它。

以下是3张表:

  1. BD_Listing(此表为奖品赞助商,包括ListingID、Title、ContactPerson、Email、奖品等基本列)

  2. 用户(此表是网站上的注册用户,包括用户ID、名字、姓氏、电子邮件等)

  3. PrizeEntry(此表是注册人数据所在的位置:EntryID、ListingID、User_ID、Date_Created)

现在所有这些都可以正常工作,只要将数据存储在数据库中。我的问题是选择。我在网站的 ADMIN 端构建了一个自定义模块,我想执行以下操作:

这是我的有效查询:

SELECT ListingID, Title, ContactEmail, PrizeSponsor
FROM [BD_Listing]
WHERE PrizeSponsor = 'True'

如果我在网站上的表格中显示这些数据,它工作正常。问题是,我需要更多数据,特别是 PrizeEntry 表中的 User_ID。这个 User_ID 需要与 Users 表中的 UserID 连接,因为我需要从中提取他们的其他信息。

SELECT a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor
       b.ListingID, b.User_ID
       FROM BD_Listing a INNER JOIN PrizeEntry b ON a.ListingID = b.ListingID
       WHERE a.PrizeSponsor = 'True'

现在,第一个问题出现了。如果有 20 个人注册必胜客,那么我将获得 21 行数据,这不是我想要的。这最终是我加入所有信息的代码及其推理,然后你可以告诉我我做错了多么愚蠢:)

SELECT a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor
       b.ListingID, b.User_ID
       c.UserID, c.FirstName, c.LastName, c.Email
       ,(SELECT COUNT(ListingID) AS EntryCount FROM PrizeEntry WHERE (ListingID = a.ListingID)) AS EntryCount
       ,(SELECT TOP 1 User_ID AS RandomWinner FROM PrizeEntry WHERE (ListingID = a.ListingID)ORDER BY NEWID()) as RandomWinner

       FROM BD_Listing a INNER JOIN PrizeEntry B on a.ListingID = b.ListingID
                         INNER JOIN Users C on b.User_ID = c.UserID
       WHERE a.PrizeSponsor = 'True'

好的,所以在显示此数据的表中,我只希望必胜客显示一次,但因为它与 PrizeEntry 表连接,所以它显示了多次。

我想看看:

Business: Pizza Hut // comes from the BD_Listing table
Contact: John Doe  // comes from the BD_Listing table
Total Registrations: 20 // count from the PrizeEntry table
Random Winner: John Smith (UserID:10) // result from the subquery

但是,每次注册奖品时,我都会看到每个企业的多行。

我为篇幅道歉......我是新来的,这是我的第二篇文章。并通过 SQL 的开始学习曲线。

非常感谢您的任何建议。

4

3 回答 3

1

首先,如果有 20 个用户,您应该期望 20 行,而不是 21 行。

我认为您可以简化查询,只需删除用户的外部连接,即可获得您想要的:

SELECT a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor,
       (SELECT COUNT(ListingID) AS EntryCount FROM PrizeEntry pe WHERE (pe.ListingID = a.ListingID)) AS EntryCount,
       (SELECT TOP 1 User_ID AS RandomWinner FROM PrizeEntry pe WHERE (pe.ListingID = a.ListingID) ORDER BY NEWID()) as RandomWinner
FROM BD_Listing a
WHERE a.PrizeSponsor = 'True'

您需要奖品赞助商的信息。相关的子查询获得附加信息。要获取有关获胜者的更多信息,只需将其设为子查询并加入相应的表,如下所示:

with t as (
         SELECT a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor,
                (SELECT COUNT(ListingID) AS EntryCount FROM PrizeEntry pe WHERE (pe.ListingID = a.ListingID)) AS EntryCount,
                (SELECT TOP 1 User_ID AS RandomWinner FROM PrizeEntry pe WHERE (pe.ListingID = a.ListingID) ORDER BY NEWID()) as RandomWinner
         FROM BD_Listing a
         WHERE a.PrizeSponsor = 'True'
        )
select t.*, u.Firstname, u.LastName, u.Email
from t join
     users u
     on t.RandomWinner = u.user_id
于 2012-08-14T22:05:40.827 回答
0

最简单的方法是两个做两个查询。第一个获取赞助商信息,第二个查询获取条目。

从技术上讲,这是 N+1 的情况(请参阅:什么是 SELECT N+1?),但我不会在这里担心。

从理论上讲,您可以一次获得所有内容,然后在前端循环遍历它,看看您是否已经打印了赞助商。问题是工作量太大,做 N+1 实际上要好得多。

现在,如果您想要不同的赞助商的摘要信息 - 您可以通过GROUP BY声明来做到这一点。

像这样:

SELECT a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor, COUNT(*) AS EntryCount
   FROM BD_Listing a INNER JOIN PrizeEntry B on a.ListingID = b.ListingID
                     INNER JOIN Users C on b.User_ID = c.UserID
   WHERE a.PrizeSponsor = 'True'
   GROUP BY a.ListingID
于 2012-08-14T21:58:28.083 回答
0

由于连接的结构,您将获得所有匹配的组合:就目前情况而言,您无法获得其他任何东西。

您需要做的是首先获得参赛者并计算出您的获胜者,然后将其与列表相关联:

select a.ListingID, a.Title, a.ContactEmail, a.PrizeSponsor, d.userid, d.firstname, d.lastname, d.email
from BD_Listing a inner join (
    select top 1 listingid, userid, firstname, lastname, email from (
        select b.ListingID, c.UserID, c.FirstName, c.LastName, c.Email, newid() as ordering
        from PrizeEntry B INNER JOIN Users C on b.User_ID = c.UserID                    
    ) x order by ordering
) d on a.listingid = d.listingid
于 2012-08-14T22:05:56.737 回答