задание по sql

nl0p0t
Дата: 18.02.2010 04:37:01
задание таково

Написать процедуру, которая для пользователей (таблица users), которые сделали в последние 20 дней более 2х заказов (таблица orders) с помощью инструкции select выводит зананную таблицу (userd_id, invitations) с invitations вида:
Уважаемый Иванов И.И. Вы являетесь нашим постоянным покупателем (5 заказов за 20 последних дней), поэтому приглашаем Вас на событие <<Концерт Мадонны>> бесплатно!

Наименование мероприятия (в примере- <<Концерт Мадонны>> содержится в таблице Events и должно выбираться на основании входного параметра хранимой процедуры @event_id int)

Структура таблиц:
Users
ID int, FirstName varchar(50), LastName varchar(50), MiddleName varchar(50)
Orders
ID int, OrderDate datetime, User_id int, Event_ID int
Events
ID int, Name varchar (50), EventDate datetime


я сделал следущее

создал таблицы,заполним, создал отношения

добавил ключи для связи User_ID в таблице Orders и ID в таблице Users

первичный
ALTER TABLE Users
WITH CHECK
ADD CONSTRAINT userid_P
PRIMARY KEY (ID)

ссылочный
ALTER TABLE Orders
WITH CHECK
ADD CONSTRAINT userid
FOREIGN KEY (User_ID)
REFERENCES Users(ID)

пишу саму процедуру

CREATE PROCEDURE pr_promo
@e_id int
AS
BEGIN
declare @date datetime
SELECT
'Уважаемый '+MiddleName+ +FirstName+ +LastName+', вы являетесь нашим постоянным покупателем ('+CAST(COUNT(FirstName) as VARCHAR) +' заказов за 20 дней). Поэтому вы приглашаетесь на событие '+Name+ ' бесплатно'as Text FROM Events, Tickets
JOIN Users ON Orders.User_ID = Users.ID
WHERE @date=Orders.OrderDate
AND 20 <= DATEADD(day, @date, 05-01-2010)
AND Events.ID=@e_id
-- 05-01-2010 is a test date
GROUP BY FirstName, Name

HAVING COUNT (t_ID)>=2

END

ошибки:

Сообщение 4104, уровень 16, состояние 1, процедура pr_promo, строка 8
Не удалось привязать составной идентификатор "Orders.User_ID".
Сообщение 4104, уровень 16, состояние 1, процедура pr_promo, строка 9
Не удалось привязать составной идентификатор "Orders.OrderDate".

пожалуйста,поправьте что не так
Guf
Дата: 18.02.2010 06:51:59
nl0p0t,
Как-то так...
DECLARE @e_name varchar (50)
SELECT @e_name = e.Name
    FROM Events e
    WHERE e.id = @e_id

SELECT MAX(u.LastName),
       COUNT(*),
       MAX(@e_name)
    FROM Orders o
         INNER JOIN Users u ON u.id = o.User_id
    WHERE o.OrderDate >= DATEADD(dd, -20, GETDATE())
    GROUP BY o.User_id
    HAVING COUNT(*) >= 2
nl0p0t
Дата: 18.02.2010 08:20:45
не до конца понял, зачем тут MAX ?

да и в результате хоть и сработало но получилось далеко от нужного результата.

ладно и на этом спасибо)
nl0p0t
Дата: 18.02.2010 08:31:59
в результате остановился на

CREATE PROCEDURE pr_promo_id
@e_id int
AS
BEGIN
declare @date datetime
SELECT
'Уважаемый '+MiddleName+ +FirstName+ +LastName+', вы являетесь нашим постоянным покупателем ('+CAST(COUNT(FirstName) as VARCHAR) +' заказов за 20 дней). Поэтому вы приглашаетесь на событие '+Name+ ' бесплатно'as Text FROM Events e, Orders o
JOIN Users ON o.User_ID = Users.ID
WHERE o.OrderDate >= DATEADD(day, -20, 20-01-2010)
AND e.ID=@e_id
-- 20-01-2010 is a test date
GROUP BY FirstName, MiddleName, LAstName, Name

HAVING COUNT (o.ID)>=2

END

единственное что пока работает некорректно это часть отвечающая за подсчет условия "за последние 20 дней", почему-неясно. (дата 20-01-2010 взята как тестовая так как вбитые даты заказов в основном 01-01-2010)
так,
Дата: 18.02.2010 08:39:23
nl0p0t
...
единственное что пока работает некорректно это часть отвечающая за подсчет условия "за последние 20 дней", почему-неясно. (дата 20-01-2010 взята как тестовая так как вбитые даты заказов в основном 01-01-2010)


...дык, 01-01-2010 - не "очень" дата (покрайней мере - не та что вы задумали)
select DATEADD(day, -20, 20-01-2010)
                                                       
------------------------------------------------------ 
1894-06-30 00:00:00.000

(1 row(s) affected)
так наверна
select DATEADD(day, -20, '20100120')
                                                       
------------------------------------------------------ 
2009-12-31 00:00:00.000

(1 row(s) affected)
nl0p0t
Дата: 18.02.2010 08:43:08
нет,с датами в таблице все ок,

ID OrderDate User_ID Event_ID
1 2010-01-01 00:00:00.000 1 1
2 2010-01-01 00:00:00.000 1 2
3 2010-01-01 00:00:00.000 1 3
4 2010-01-01 00:00:00.000 2 1
5 2010-01-01 00:00:00.000 2 2
6 2010-01-01 00:00:00.000 2 3
7 2010-01-01 00:00:00.000 2 4
8 2010-01-01 00:00:00.000 3 1
9 2010-01-01 00:00:00.000 3 2
10 2010-01-01 00:00:00.000 3 3
11 2010-01-01 00:00:00.000 3 4
12 2010-01-01 00:00:00.000 3 5
13 2010-01-01 00:00:00.000 4 1
14 2010-01-01 00:00:00.000 4 2
15 2009-01-01 00:00:00.000 4 3
16 2010-01-01 00:00:00.000 5 2

проблема в том что нужно чтобы заказов у пользователя было больше двух ЗА ПОСЛЕДНИЕ 20 ДНЕЙ,
надо править тут

JOIN Users ON o.User_ID = Users.ID
WHERE o.OrderDate >= DATEADD(day, -20, 20-01-2010)
AND e.ID=@e_id


но вот как
так,
Дата: 18.02.2010 08:47:49
nl0p0t
нет,с датами в таблице все ок,
...


я где-то говорил, что "с датами в таблице НЕ ок"??

в запросе, где вы тестовую дату пытаетесь использовать - НЕ ок
nl0p0t
Дата: 18.02.2010 08:57:55
проблема тут не в этом (или не только в этом)

проблема в том что в условии

BEGIN
declare @date datetime
SELECT
'Уважаемый '+MiddleName+ +FirstName+ +LastName+', вы являетесь нашим постоянным покупателем ('+CAST(COUNT(FirstName) as VARCHAR) +' заказов за 20 дней). Поэтому вы приглашаетесь на событие '+Name+ ' бесплатно'as Text FROM Events e, Orders o
JOIN Users ON o.User_ID = Users.ID
WHERE o.OrderDate >= DATEADD(day, -20, 20-05-2010)
AND e.ID=@e_id
-- 05-01-2010 is a test date
GROUP BY FirstName, MiddleName, LAstName, Name

HAVING COUNT (o.ID)>=2


END


логическая ошибка.
у меня в конце стоит HAVING...
тогда как мне нужен не фильтр.

в данный момент в самом теле условие только одно

WHERE o.OrderDate >= DATEADD(day, -20, 20-05-2010)

а как бы сделать так чтобы он считал СКОЛЬКО заказов ЗА ПОСЛЕДНИЕ 20 ДНЕЙ.
nl0p0t
Дата: 18.02.2010 08:59:23
а не
а)были ли заказы за последние 20 дней
б)было ли вообще заказов больше 2х.

надо чтобы он считал что больше 2х заказов именно за последние 20 дней
так,
Дата: 18.02.2010 09:15:29
nl0p0t
а не
а)были ли заказы за последние 20 дней
б)было ли вообще заказов больше 2х.

надо чтобы он считал что больше 2х заказов именно за последние 20 дней


a)
declare @date datetime
set @date = '20100120'
...
WHERE o.OrderDate between @date-20 and @date

б)
...
GROUP BY FirstName, MiddleName, LAstName, Name
HAVING COUNT (o.ID)>=2