2

私は行き詰まっています。

次のクエリを実行すると、機能します。

 select DISTINCT l.Seating_Capacity - (select count(*)
                        from tblTrainings t1, tbllocations l
                        where l.locationId = t1.LocationId) as
                        availableSeats
                        from tblTrainings t1, tbllocations l
                        where l.locationId = t1.LocationId

ただし、Seating_Capacity - 上記の合計数 = 0 の場合は「FULL」メッセージを表示するという CASE ステートメントを追加したいと考えています。

それ以外の場合は、残りの数を表示します。

そのクエリは次のとおりです。

                 select DISTINCT case when l.Seating_Capacity - (select count(*)
                from tblTrainings t1, tbllocations l
                where l.locationId = t1.LocationId) = 0 then 'full' else STR(Seating_Capacity) end)
                availableSeats
                from tblTrainings t1, tbllocations l
                where l.locationId = t1.LocationId

「End」の近くにある「Incorrect syntax near ')」を取得しています

内部の Seating_Capacity が無効な列名であるというエラーも表示されます。

どうぞよろしくお願いいたします。

テスト中に動いていると思っていたので、夢の国にいたに違いありません。

現在、アプリはライブですが、機能していません。

事前にどうもありがとう

select DISTINCT l.LocationId,c.courseId, c.coursename, l.Seating_Capacity - (select count(*)
                        from tblTrainings t1
                        where l.locationId = t1.LocationId and c.courseId = t1.courseId) as
                        availableSeats,d.dateid,d.trainingDates,d.trainingtime,c.CourseDescription,
                        i.instructorName,l.location,l.seating_capacity 
                        from tblLocations l
                        Inner Join tblCourses c on l.locationId = c.locationId
                        left join tblTrainings t on l.locationId = t.LocationId and c.courseId = t.courseId
                        Inner Join tblTrainingDates d on c.dateid=d.dateid 
                        Inner Join tblCourseInstructor ic on c.courseId = ic.CourseId  
                        Inner Join tblInstructors i on ic.instructorId = i.instructorId
                        WHERE CONVERT(VARCHAR(10), d.trainingDates, 101) >= CONVERT(VARCHAR(10), GETDATE(), 101)
4

3 に答える 3

3

式の繰り返しを避けるために、WITHを使用してクエリを簡素化できます。

WITH (
   -- Start with your query that already works
   SELECT DISTINCT l.Seating_Capacity - (select count(*)
                    from tblTrainings t1, tbllocations l
                    where l.locationId = t1.LocationId) AS availableSeats
   FROM tblTrainings t1, tbllocations l
   WHERE l.locationId = t1.LocationId
) AS source
SELECT
    -- Add a CASE statement on top of it
    CASE WHEN availableSeats = 0 THEN 'Full'
    ELSE STR(availableSeats)
    END AS availableSeats
FROM source
于 2013-09-30T15:26:18.873 に答える
2

ケースステートメントの最後に余分なものがあり、)それを削除します。

 0 then 'full' else STR(Seating_Capacity) end)
                                            ^^^

Seating_Capacityようなテーブルエイリアスでアクセスしてみてくださいl.Seating_Capacity

于 2013-09-30T15:25:13.727 に答える
0

サブクエリでクエリを複雑にしすぎていると思います。私が理解しているように、必要に応じて以下が機能するはずです。

SELECT  AvailableSeats = CASE WHEN l.Seating_Capacity - COUNT(*) = 0 THEN 'Full' 
                            ELSE STR(l.Seating_Capacity - COUNT(*)) 
                        END
FROM    tblTrainings t1
        INNER JOIN tblLocations l
            ON l.LocationID = t1.LocationID
GROUP BY l.Seating_Capacity;

STR(l.Seating_Capacity - COUNT(*))キャパシティだけでなく、残りの座席数を知りたいと思われるため、else を に変更しました。要件を誤解した場合は、 に変更してSTR(l.Seating_Capacity)ください。

また、ANSI 89 の暗黙的な結合を ANSI 92 の明示的な結合に切り替えました。標準は 20 年以上にわたって変更されており、新しい構文に切り替える十分な理由があります。ただし、完全を期すために、上記のクエリの ANSI 89 バージョンは次のようになります。

SELECT  AvailableSeats = CASE WHEN l.Seating_Capacity - COUNT(*) = 0 THEN 'Full' 
                            ELSE STR(l.Seating_Capacity - COUNT(*)) 
                        END
FROM    tblTrainings t1, tblLocations l
WHERE   l.LocationID = t1.LocationID
GROUP BY l.Seating_Capacity;

編集

完全なクエリを適応させるには、select のサブクエリを結合されたサブクエリに置き換えるだけです。

SELECT  l.LocationId,
        c.courseId, 
        c.coursename, 
        CASE WHEN l.Seating_Capacity - t.SeatsTaken = 0 THEN 'Full' 
            ELSE STR(l.Seating_Capacity - t.SeatsTaken) 
            END AS availableSeats,
        d.dateid,
        d.trainingDates,
        d.trainingtime,
        c.CourseDescription,
        i.instructorName,
        l.location,
        l.seating_capacity 
FROM    tblLocations l
        INNER JOIN tblCourses c 
            ON l.locationId = c.locationId
        LEFT JOIN 
        (   SELECT  t.LocationID, t.CourseID, SeatsTaken = COUNT(*)
            FROM    tblTrainings t 
            GROUP BY t.LocationID, t.CourseID
        ) t
            ON l.locationId = t.LocationId 
            AND c.courseId = t.courseId
        INNER JOIN tblTrainingDates d 
            ON c.dateid=d.dateid 
        INNER JOIN tblCourseInstructor ic 
            ON c.courseId = ic.CourseId  
        INNER JOIN tblInstructors i 
            ON ic.instructorId = i.instructorId
WHERE   d.trainingDates >= CAST(GETDATE() AS DATE);

JOIN は、相関サブクエリよりも最適化する傾向があります (ただし、オプティマイザーは JOIN が代わりに機能すると判断する場合があります) 。これSeatsTakenは、サブクエリを再評価することなく結果 ( ) を複数回参照できることも意味します。

さらに、カウントをサブクエリに移動し、結合を削除することで、パフォーマンスが向上するtblTrainings必要がなくなると思います。DISTINCT

最後に、次の行を変更しました。

WHERE CONVERT(VARCHAR(10), d.trainingDates, 101) >= CONVERT(VARCHAR(10), GETDATE(), 101)

WHERE   d.trainingDates >= CAST(GETDATE() AS DATE);

あなたがそうしているかどうかはわかりませんが、d.TrainingDates にインデックスがある場合は、それを varchar に変換して今日と比較することで、オプティマイザーがこのインデックスを使用する機能を削除します>=。 d.TrainingDates で変換を実行する必要はなく、GETDATE() の時間部分を削除するだけで済みます。これは、DATE にキャストすることで実行できます。これについての詳細は、この記事に含まれています ( Aaron Bertrandからのもう 1 つの宝石)

于 2013-09-30T15:40:54.280 に答える