0

これが私の状況のワークフローです:

登録ユーザーが地元の賞スポンサー(例:企業)からの賞を登録できるウェブサイトを持っています。たとえば、ピザハットを賞スポンサーとして持つページがあり、登録/認証されたユーザーは[Enter the描画」し、一度実行すると、再度クリックすることはできません。

3つの表は次のとおりです。

  1. BD_Listing(このテーブルは賞のスポンサー用であり、ListingID、Title、ContactPerson、Email、Prizeなどの基本的な列が含まれています)

  2. ユーザー(この表はサイトの登録ユーザー用であり、UserID、FirstName、LastName、Eメールなどが含まれています)

  3. PrizeEntry(このテーブルは登録者データが入る場所です:EntryID、ListingID、User_ID、Date_Created)

これで、データベースにデータを保存する限り、これはすべて正常に機能します。私の問題はSELECTです。Webサイトの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人がPizzaHutに登録すると、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'

さて、このデータを表示するテーブルでは、ピザハットを1回だけ表示したいのですが、代わりに、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

しかし、代わりに、賞品が登録されるたびに、ビジネスごとに複数の行が表示されます。

長さをお詫びします...私はここで新しいです、そしてこれは私の2番目の投稿です。そして、SQLの最初の学習曲線をたどります。

アドバイスありがとうございます。

4

3 に答える 3

1

まず、ユーザーが20人の場合、21行ではなく20行を期待する必要があります。

ユーザーへの外部結合を削除するだけで、クエリを単純化して、必要なものを取得できると思います。

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

結合の構造により、一致するすべての組み合わせを取得することになります。現状では、他に何も取得できません。

あなたがする必要があるのは、最初に参加者を獲得し、勝者を見つけ出し、次にこれをリストに関連付けることです。

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 に答える
0

最も簡単な方法は、2つのクエリを実行することです。最初のクエリはスポンサー情報を取得し、2番目のクエリはエントリを取得します。

技術的には、これはN + 1の場合です(「SELECTN + 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 に答える