2016-12-02 6 views
0

Я хочу выбрать все записи для клиентов, чей первый заказ с 2015 года. Я хочу, чтобы любые заказы они размещали после 2015 года, но я НЕ хочу записи для клиентов, чей первый заказ был в 2016 году. В конечном итоге я пытаюсь найти процент людей, которые заказывают более двух раз, но я хочу исключить новых пользователей в 2016 году.Выделите все записи для клиентов, которым следует помнить в 2015 году

Это не работает, потому что «mindate» является недопустимым столбцом но я не уверен, почему и как еще попробовать.

Select 
    od.CustomerID, OrderID, OrderDSC, OrderDTS 
From 
    OrderDetail OD 
Join 
    (Select 
     OrderID, Min(orderdts) as mindate 
    From 
     OrderDetail 
    Where 
     mindate Between '2015-1-1' and '2015-12-31' 
    Group By Orderid) b on od.OrderID = b.OrderID 

ответ

0

Поскольку execution phases - это seqency как QRY оценивается и двигателем. В том месте, где ваше мышление еще не существует.

Вы можете изменить MinDate по orderdts:

select OrderID, min(orderdts) as mindate 
from OrderDetail 
where orderdts between '2015-1-1' and '2015-12-31' 
group by Orderid 

Второй вариант заключается в использовании having заявление - это оценивали после group by.

0

Что я выбрал для идентификации отдельных идентификаторов клиентов, которые попадают между вашим датерангом и левым соединением со столом, поэтому он отфильтровывает всех, кто не попадает между вашим датерангом.

SELECT * FROM 
    (Select DISTINCT(CustomerID) as CustomerID 
     FROM OrderDetail WHERE OrderDTS between '2015-1-1' AND '2015-12-31') oIDs 

LEFT JOIN 

    OrderDetail OD 

ON oIDs.CustomerID = OD.CustomerID 
0

Попробуйте использовать предложение EXISTS. Это в основном подзапрос. Ниже приведен пример, который вы сможете адаптировать.

create table Test (Id int, aDate datetime) 

insert Test values (1,'04/04/2014') 
insert Test values (1,'05/05/2015') 
insert Test values (1,'06/06/2016') 
insert Test values (2,'04/30/2016') 
insert Test values (3,'02/27/2014') 


select t.* from Test t 
where 
    aDate>='01/01/2015' 
    and exists(select * from Test x where x.Id=t.Id and x.aDate >='01/01/2015' and x.aDate<'01/01/2016') 
0

Я не знаю, тип orderdts данных, но если это DateTime заказы на 2015-12-31 не будут включены (если дата заказа не 2015-12-31 00: 00:. 00,000 Примечание как это пропустит первую запись:

DECLARE @orders TABLE (CustomerID INT, orderDate DATETIME); 
INSERT @orders VALUES (1, '2015-12-31 00:00:01.000'), (1, '2015-12-30'), (2, '2015-01-04'); 
SELECT * FROM @orders WHERE orderDate BETWEEN '2015-01-01' AND '2015-12-31'; 

в этом случае вы хотите ИНЕКЕ фильтр выглядеть следующим образом:

WHERE orderDate BETWEEN '2015-01-01 00:00:00.000' AND '2015-12-31 23:59:59.999'; 

Или

WHERE CAST(orderDate AS date) BETWEEN '2015-01-01' AND '2015-12-31'; 

(первый пример почти наверняка будет работать лучше).

Теперь, используя этот образец данных:

-- Sample data 
CREATE TABLE #LIST (LISTName varchar(10) NOT NULL); 
INSERT #LIST 
SELECT TOP (100) LEFT(newid(), 8) 
FROM sys.all_columns a, sys.all_columns b; 

-- You will probably want LISTName to be indexed 
CREATE NONCLUSTERED INDEX nc_LISTName ON #LIST(LISTName); 

Вы можете реализовать решение Павла так:

DECLARE @LIST_Param varchar(8) = 'No List'; 

SELECT LISTName 
FROM 
(
    SELECT distinct LISTName 
    FROM #LIST 
    UNION ALL 
    SELECT 'No List' 
    WHERE (SELECT COUNT(DISTINCT LISTName) FROM #LIST) < 1000000 
) Distinct_LISTName 
WHERE (@LIST_Param = 'No List' or @LIST_Param = LISTName); 

В качестве альтернативы вы можете сделать это:

DECLARE @LIST_Param varchar(8) = 'No List'; 

WITH x AS 
(
    SELECT LISTName, c = COUNT(*) 
    FROM #LIST 
    WHERE (@LIST_Param = 'No List' or @LIST_Param = LISTName) 
    GROUP BY LISTName 
), 
c AS (SELECT s = SUM(c) FROM x) 
SELECT LISTName 
FROM x CROSS JOIN c 
WHERE s < 1000000;