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