2012-02-23 1 views
1

Вкратце, я хочу создать запрос, который поможет мне найти лучшие доступные места для концертного типа, Ticketmaster.com «Найдите лучшие доступные места», где необходимо найти требуемое количество мест, наиболее близких к сцене, и места должны быть в порядке.Как вы получите наибольший/MAX COUNT из последовательных/непрерывных записей, удовлетворяющих критериям, используя T-SQL

Учитывая этот пример таблицу:

DECLARE @Seats TABLE 
(
    SectionId INT   NOT NULL, 
    RowId  VARCHAR(2) NOT NULL, 
    SeatId  INT   NOT NULL, 
    Priority INT   NOT NULL, /* Used to determine closeness to the stage and/or order to search in */ 
    StatusCd CHAR(1)  NOT NULL, /* A for Available, H for Held, P for Purchased, etc. */ 
    Cost  MONEY  NOT NULL 
) 

И учитывая этот сценарий, чтобы заполнить таблицу:

DECLARE @SectionCounter INT 
DECLARE @RowCounter INT 
DECLARE @SeatCounter INT 

SET  @SectionCounter = 1 
SET  @RowCounter = 1 

WHILE @SectionCounter <= 10 
BEGIN 

    WHILE @RowCounter <= 26 
    BEGIN 

     SET @SeatCounter = 1 

     WHILE @SeatCounter <= 26 
     BEGIN  

      INSERT INTO @Seats 
      (SectionId , 
       RowId , 
       SeatId , 
       Priority , 
       StatusCd , 
       Cost 
      ) 
      VALUES 
      (@SectionCounter , 
       CHAR(64 + @RowCounter) , 
       @SeatCounter , 
       1 , 
       (
       /* Randomly setting certain seats as purchased */ 
       SELECT CASE 
         WHEN @SeatCounter IN 
         (
          1,2,9,10, 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)), 
          (ROUND(((26 - 1 -1) * RAND() + 1), 0)) 
         ) 
         THEN 'P' ELSE 'A' END) , 
       (
       SELECT CASE 
         WHEN @SectionCounter IN (1,2) 
         THEN 75.00 ELSE 25.00 END 
      ) 
      ) 

      SET @SeatCounter = @SeatCounter + 1 

     END 

     SET @RowCounter = @RowCounter + 1 

    END 

    SET  @RowCounter = 1 
    SET @SectionCounter = @SectionCounter + 1 

END 

Что такое лучший запрос, чтобы найти й число последовательных/смежных мест?

Ниже представлено мое текущее решение, требующее от моего приложения как минимум 3 запроса.

Например, если клиент просил 8 из следующих лучших доступных мест, я бы запустить этот запрос:

/* Get each sections available seat count */ 
SELECT SectionId, 
     Priority, 
     COUNT(SeatId) AS 'Seat Count' 
FROM @Seats 
WHERE StatusCd = 'A' /* A = Available. */ 
GROUP BY SectionId, Priority 
ORDER BY Priority 

Какой будет производить набор результатов, таких, как это:

| SectionId | Priority | SeatCount | 
|-----------|----------|-----------| 
| 1   | 1  | 544  | 
| 2   | 2  | 554  | 
| 3   | 3  | 552  | 

приложение скажет: «Доступно ли 8 мест с приоритетом 1?» и выше результирующем наборе, ответ будет да, так что давайте доступные число строк в соответствующем разделе, который Раздел 1. Вот запрос для этого:

SELECT RowId, 
     COUNT(SeatId) AS 'Seat Count' 
FROM @Seats 
WHERE SectionId = 1 
     AND StatusCd = 'A' 
GROUP BY RowId 

Какой будет производить набор результатов, таких как это: «есть 8 свободных мест в строке A»

| RowId | SeatCount | 
|-------|-----------| 
| A  | 21  | 
| B  | 18  | 
| C  | 22  | 

Приложение будет смотреть на эти результаты и задать тот же вопрос, начиная с первой строки, С учетом указанных выше результатов, то ответ будет да, так в то время приложение будет запрашивать для всех мест в ряду А с этим запросом:

SELECT * 
FROM @Seats 
WHERE SectionId = 1 
AND  RowId = 'A' 

Какой будет производить набор результатов, таких, как это:

| SectionId | RowId | SeatId | Priority | StatusCd | Cost | 
|-----------|-------|--------|----------|----------|-------| 
| 1   | A  | 1  | 1  | P  | 75.00 | 
| 1   | A  | 2  | 1  | P  | 75.00 | 
| 1   | A  | 3  | 1  | A  | 75.00 | 
| 1   | A  | 4  | 1  | A  | 75.00 | 
| 1   | A  | 5  | 1  | A  | 75.00 | 

В это время приложение выполнило бы повторение результатов, пытаясь найти 8 мест подряд с статусом StatusCd «A» для доступных.

Я уверен, что существует гораздо более эффективный метод запроса последовательных записей в базе данных без необходимости загружать целые строки и делать это в коде.

Мое лучшее предположение для оптимального решения состояло в том, чтобы сделать самостоятельное присоединение к таблице и сделать какое-то увеличение SeatId или что-то в этом направлении.

Любая помощь или предложения приветствуются.

ответ

1

Это должно заставить вас начать. Вы были на правильном пути, пока я сам присоединился, это еще один способ.

Это даст вам первые 8 мест с одинаковым приоритетом, секцией, рядом со статусом «А» в порядке очередности по приоритету, разделу, строке. Поправьте меня, если я ничего не понял.

DECLARE @number_seats AS INTEGER = 8; 

WITH T1 AS (
    SELECT S.*, 
      SeatId - ROW_NUMBER() OVER(PARTITION BY Priority, SectionId, RowId, StatusCd ORDER BY SeatId) AS grp 
    FROM #seats AS S 
), 

T2 AS (
SELECT Priority AS Priority, 
     SectionId AS Section, 
     RowId  AS RowId, 
     StatusCd AS StatusCd, 
     MIN(SeatId) AS StartingSeat, 
     MAX(SeatId) AS EndingSeat, 
     COUNT(*) AS Seats  
FROM T1 
GROUP BY Priority, SectionId, RowId, StatusCd, grp 
), 

T3 AS (
    SELECT TOP 1 * 
    FROM T2 
    WHERE T2.Seats >= @number_seats and StatusCd = 'A' 
    ORDER BY Priority, Section, RowId, StartingSeat 
) 
SELECT S.* 
FROM T3 JOIN #seats AS S ON 
(
    T3.Priority = S.Priority AND 
    T3.Section = S.SectionId AND 
    T3.RowId = S.RowId AND 
    S.SeatId BETWEEN T3.StartingSeat AND T3.StartingSeat + @number_seats - 1 
) 
ORDER BY Priority, Section, RowId, StartingSeat 

Результаты:

SectionId RowId SeatId  Priority StatusCd Cost 
----------- ----- ----------- ----------- -------- --------------------- 
1   A  11   1   A  75.00 
1   A  12   1   A  75.00 
1   A  13   1   A  75.00 
1   A  14   1   A  75.00 
1   A  15   1   A  75.00 
1   A  16   1   A  75.00 
1   A  17   1   A  75.00 
1   A  18   1   A  75.00 
+0

Великий ответ! Я действительно поражен тем, насколько быстро это происходит. Ваш ответ ТОЧНО, что я искал. Вы действительно воссоздали функцию «Найти лучшие доступные места» Ticketmaster.com. Браво! –

+0

@ RandyBurden - Без проблем, я рад, что это сработало для вас - просто убедитесь, что я получаю скидки при покупке TicketMaster –

Смежные вопросы