DateDiff как c и по убыванию - PullRequest
2 голосов
/ 21 июня 2020
SELECT DISTINCT 
    at.AccountId AS AccountId, 
    a.FirstName + ' ' + a.LastName AS [FullName],
    DATEDIFF(day, T.ArrivalDate, T.ReturnDate) AS LongestTrip,
    DATEDIFF(day, T.ArrivalDate, T.ReturnDate) AS ShortestTrip  
FROM 
    Accounts a
JOIN 
    AccountsTrips at ON a.Id = AT.AccountId
JOIN 
    Trips t ON T.Id = AT.TripId
WHERE 
    a.MiddleName IS NULL AND t.CancelDate IS NULL
ORDER BY 
    DATEDIFF(day, T.ArrivalDate, T.ReturnDate) DESC, ShortestTrip ASC

Код упорядочивает только таблицы в порядке убывания LongestTrip и ShortestTrip

ДАННЫЕ ОБРАЗЦА!

Найдите самую длинную и самую короткую поездку для каждой учетной записи в днях. Отфильтруйте результаты по учетным записям без отчества и поездок, которые не отменяются (CancelDate имеет значение null).

Отсортируйте результаты по дням самой длинной поездки (по убыванию), затем по самой короткой поездке (по возрастанию).

Примеры

AccountId   FullName             LongestTrip    ShortestTrip
------------------------------------------------------------
    40      Winna Maisey             7              1
    56      Tillie Windress          7              1
    57      Eadith Gull              7              1
    66      Sargent Rockhall         7              1
    69      Jerome Flory             7              2
     …  …   …   …

Таблицы -

CREATE TABLE Cities
(
    Id INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(20) NOT NULL,
    CountryCode CHAR(2) NOT NULL
)

CREATE TABLE Hotels
(
    Id INT PRIMARY KEY IDENTITY,
    Name NVARCHAR(30) NOT NULL,
    CityId INT FOREIGN KEY REFERENCES Cities(Id) NOT NULL,
    EmployeeCount INT NOT NULL,
    BaseRate DECIMAL(10,2)
)

CREATE TABLE Rooms
(
    Id INT PRIMARY KEY IDENTITY,
    Price DECIMAL(10,2) NOT NULL,
    Type NVARCHAR(20) NOT NULL,
    Beds INT NOT NULL,
    HotelId INT FOREIGN KEY REFERENCES Hotels(Id) NOT NULL
)

CREATE TABLE Trips
(
    Id INT PRIMARY KEY IDENTITY,
    RoomId INT FOREIGN KEY REFERENCES Rooms(Id) NOT NULL,
    BookDate DATE NOT NULL, CHECK(BookDate<ArrivalDate),
    ArrivalDate DATE NOT NULL, CHECK(ArrivalDate<ReturnDate),
    ReturnDate DATE NOT NULL,
    CancelDate DATE
)

CREATE TABLE Accounts
(
    Id INT PRIMARY KEY IDENTITY,
    FirstName NVARCHAR(50) NOT NULL,
    MiddleName NVARCHAR(20),
    LastName NVARCHAR(50) NOT NULL,
    CityId INT  NOT NULL,
    BirthDate DATE NOT NULL,
    Email VARCHAR(100) UNIQUE NOT NULL
   
    CONSTRAINT FK_CityId FOREIGN KEY (CityId)
        REFERENCES Cities(Id)
)

CREATE TABLE AccountsTrips
(
    AccountId INT FOREIGN KEY REFERENCES Accounts(Id) NOT NULL,
    TripId INT FOREIGN KEY REFERENCES Trips(Id) NOT NULL,
    Luggage INT NOT NULL, CHECK(Luggage >= 0)
)

1 Ответ

0 голосов
/ 21 июня 2020

Вы хотите выбрать самые длинные и самые короткие поездки для каждой учетной записи из своих данных. Поскольку все, что вы хотите получить от поездок, - это продолжительность, вы можете просто объединить и отобразить MIN и MAX длительность:

SELECT
    a.Id AS AccountId, 
    a.FirstName + ' ' + a.LastName AS [FullName],
    MIN(DATEDIFF(day, T.ArrivalDate, T.ReturnDate)) AS LongestTrip,
    MAXD(ATEDIFF(day, T.ArrivalDate, T.ReturnDate)) AS ShortestTrip  
FROM 
    Accounts a
JOIN 
    AccountsTrips at ON a.Id = AT.AccountId
JOIN 
    Trips t ON T.Id = AT.TripId
WHERE 
    a.MiddleName IS NULL AND t.CancelDate IS NULL
GROUP BY
    a.Id, a.FirstName, a.LastName
ORDER BY 
    LongestTrip DESC, ShortestTrip ASC;

Если вы хотите показать дополнительные данные из поездок, вы должны использовать оконные функции (возможно, MIN OVER и MAX OVER) и затем либо отображать две строки для каждой учетной записи, либо агрегировать эти две строки.

...