Совет по SQL-запросу - последний элемент

У меня есть таблица, в которой я храню данные о продажах клиентов (в периодических изданиях, например, в газетах). Товар хранится по выдаче. Пример

custid  prodid  issue   qty     datesold
1       123     2       12      01052008
2       234     1       5       01022008
1       123     1       5       01012008
2       444     2       3       02052008

Как я могу получить (что быстрее) последнюю проблему для всех продуктов для конкретного клиента? Могу ли я получить образцы как для SQL Server 2000, так и для 2005? Обратите внимание, что в таблице более 500 тыс. Строк.

Спасибо

Одно уточнение: является ли столбец "Продано" типом даты в базе данных?

JohnFx 12.12.2008 00:58

Что вы имеете в виду под «последним выпуском»?

Patrick Harrington 12.12.2008 00:59

Я хочу иметь возможность для каждого продукта получать номер последнего выпуска (недавний).

Saif Khan 12.12.2008 01:01

Определите «недавний»: может ли выпуск с меньшим номером продаваться после выпуска с более высоким номером, и если да, то что вас волнует?

Joel Coehoorn 12.12.2008 01:04

Меня волнует более высокий номер выпуска, теперь один и тот же выпуск повторяется каждый год (1-52).

Saif Khan 12.12.2008 01:21

Может ли кто-нибудь изменить заголовок этого вопроса, чтобы он точно отражал вопрос и не был таким общим?

mmcdole 12.12.2008 01:22

Я хотел бы, какой заголовок мне использовать?

Saif Khan 12.12.2008 01:26

Каков самый быстрый способ запросить элемент по дате? Я не знаю ... это не мой домен, поэтому я не менял его сам. Когда кто-то в будущем будет искать проблемы, подобные вашей, «Совет по SQL-запросам» ничего не скажет им о содержании вопроса.

mmcdole 12.12.2008 01:33
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
8
951
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Общий SQL; Синтаксис SQL Server не должен сильно отличаться:

SELECT prodid, max(issue) FROM sales WHERE custid = ? GROUP BY prodid;

Если он слишком медленный, добавьте индекс на custid, prodid и issue. Думаю, именно в таком порядке.

pipTheGeek 12.12.2008 01:11

Запрос на существующую растущую историческую таблицу - это слишком медленно!

Настоятельно рекомендуем вам создать новую таблицу tblCustomerSalesLatest, в которой будут храниться данные о последних проблемах каждого клиента. и выберите оттуда.

Эта «оптимизация» приведет к тому, что схема базы данных больше не будет нормализована. Преждевременная оптимизация - корень всех зол. С соответствующими индексами ответ «max / group by» должен быть нормальным.

Diomidis Spinellis 12.12.2008 01:09

Похоже, что аналитическая база данных olap, а не транзакционная база данных oltp, должна быть денормализована.

dkretz 12.12.2008 01:11

По варианту использования! Это то, за что заплатил заказчик. Чистое решение не нормализовано на 100%, но быстрое и практичное.

Ray Lu 12.12.2008 01:12

А что, если у tblCustomerSales 100 миллионов записей ??

Ray Lu 12.12.2008 01:13

Я рассматривал это как альтернативу, проблема в том, что на это потребуется время.

Saif Khan 12.12.2008 01:25

Это новый проект? Если это так, я бы с осторожностью относился к настройке вашей базы данных таким образом и немного почитал бы о нормализации, чтобы вы могли получить что-то вроде этого:

CustID LastName FirstName
------ -------- ---------
1      Woman    Test
2      Man      Test

ProdID ProdName
------ --------
123    NY Times
234    Boston Globe

ProdID IssueID PublishDate
------ ------- -----------
123    1       12/05/2008
123    2       12/06/2008

CustID OrderID OrderDate
------ ------- ---------
1      1       12/04/2008

OrderID ProdID IssueID Quantity
------- ------ ------- --------
1       123    1       5
2       123    2       12

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

Это 95% моей схемы. В вашей последней таблице мне нужно получить последний выпуск по каждому продукту для клиента.

Saif Khan 12.12.2008 01:23

Буду признателен за ваш отзыв.

Saif Khan 12.12.2008 05:43

Если вы ищете самую последнюю распродажу по дате, возможно, это то, что вам нужно:

SELECT prodid, issue
  FROM Sales 
WHERE custid = @custid 
      AND datesold = SELECT MAX(datesold) 
                       FROM Sales s 
                      WHERE s.prodid = Sales.prodid
                         AND s.issue = Sales.issue
                        AND s.custid = @custid 
Ответ принят как подходящий

Предполагая, что "последний" определяется по дате (а не по номеру выпуска), этот метод обычно довольно быстрый, предполагая приличные индексы:

SELECT
     T1.prodid,
     T1.issue
FROM
     Sales T1
LEFT OUTER JOIN dbo.Sales T2 ON
     T2.custid = T1.custid AND
     T2.prodid = T1.prodid AND
     T2.datesold > T1.datesold
WHERE
     T1.custid = @custid AND
     T2.custid IS NULL

Обработка 500 тыс. Строк - это то, с чем, вероятно, без проблем справится ноутбук, не говоря уже о реальном сервере, поэтому я бы не стал денормализовать вашу базу данных для «производительности». Не добавляйте лишнего обслуживания, неточностей и, прежде всего, головной боли, отслеживая "последний проданный" где-то еще.

Обновлено: я забыл упомянуть ... это специально не обрабатывает случаи, когда две проблемы имеют одинаковые точные даты. Возможно, вам придется настроить его в соответствии с вашими бизнес-правилами для этой ситуации.

Другие вопросы по теме