#sql #sql-server #modulus
#sql #sql-сервер #модуль
Вопрос:
Я просто освежаю некоторые SQL — другими словами, я действительно устал — и на данный момент немного застрял. Вероятно, это что-то тривиальное, но посмотрим.
Я хотел бы выбрать всех пользователей, которые обладают нечетным номером определенного атрибута, который не является целым числом (в этом примере TransactionType). Так, например, возьмите следующий тест / не реальную информацию, где эти люди покупают автомобиль или какую-то аналогичную крупную покупку.
Name TransactionType Date
John Buy 5/1
John Cancel 5/1
John Buy 5/2
Joseph Buy 5/25
Joseph Cancel 5/25
Tanya Buy 5/28
Я бы хотел, чтобы он возвращал людей, у которых было нечетное количество транзакций; другими словами, они в конечном итоге приобрели товар. Итак, в этом случае Джон и Таня будут выбраны, а Джозеф — нет.
Я знаю, что могу использовать здесь операнд модуля, но я немного не понимаю, как его правильно использовать. Я подумал об использовании
count(TransactionType) % 2 != 0
в предложении where, но это, очевидно, недопустимо. Любые указатели в правильном направлении были бы очень полезны. Дайте мне знать, если это неясно, и спасибо!
Комментарии:
1. это все столбцы, которые у вас есть? включено ли время в ваш столбец даты?
2. Нет, это не мои фактические данные. Но, чтобы быть точным с тем, что у меня есть, у меня есть sales_date, который по какой-то причине хранится как varchar -_-
3. включает ли это время?
4. Нет, это не так — это выглядит так: 12-MAY-14, например.
5. есть ли у него увеличивающийся идентификатор или что-то в этом роде, чтобы вы имели представление о том, какой элемент был добавлен первым? вам понадобится что-то вроде этого, чтобы принять мой подход.
Ответ №1:
Вы близки. Вам нужно предложение having вместо предложения where .
select Name
from table
group by Name
having count(TransactionType) % 2 != 0
Комментарии:
1. Спасибо за вашу помощь. Знал, что мне не хватает чего-то относительно очевидного 🙂
Ответ №2:
Не лучше ли вам получить последний статус по дате транзакции и использовать его, а не полагаться на подсчет TransactionType
для определения последнего статуса:
Что-то вроде этого:
SELECT b.Name, b.TransactionType, b.[Date]
FROM (
SELECT Name, MAX(t1.[DATE]) latestDate
FROM [Transactions] t1
GROUP BY t1.Name
) a
INNER JOIN [Transactions] b ON b.Name = a.Name AND a.latestDate = b.[Date]
WHERE b.TransactionType = 'Buy'
Предполагая, что ваши даты являются действительными датами с включенным временем, это должно сработать.
Пример скрипки SQL
Если вы сохраняете только часть даты, максимальная дата будет одинаковой для людей, которые покупают и отменяют в один и тот же день, поэтому будет возвращено больше данных и несколько неправильных записей.