RANK () Функция на ДАТА В SQL - PullRequest
0 голосов
/ 03 апреля 2020

Я использую Po pSQL для этого.

Пожалуйста, учтите следующее: Я пытаюсь присвоить каждой стране рейтинг PayDate. Для каждой PayDate существует более одной связанной страны. Мой wi sh состоит в том, чтобы сгруппировать каждую страну с указанием c PayDate или его счетчиком и соответствующим образом ранжировать их.

CREATE TABLE Country
(
    CountryID INT PRIMARY KEY,
    CountryName VARCHAR(40)
);

CREATE TABLE State
(
    StateID INT PRIMARY KEY,
    StateName VARCHAR(40),
    CountryID INT,
    FOREIGN KEY(CountryID) REFERENCES Country(CountryID)
);

CREATE TABLE City
(
    CityID INT PRIMARY KEY,
    CityName VARCHAR(40),
    StateID INT,
    FOREIGN KEY(StateID) REFERENCES State(StateID)
);

CREATE TABLE Rooms 
(
    RoomID INT PRIMARY KEY,
    RoomTypeID INT,
    RoomBandID INT,
    RoomFacilityID INT,
    CityID INT,
    Floor INT,
    AddionalNotes VARCHAR(255),
    FOREIGN KEY(RoomTypeID) REFERENCES RoomType(RoomTypeID),
    FOREIGN KEY(RoomBandID) REFERENCES RoomBand(RoomBandID),
    FOREIGN KEY(RoomFacilityID) REFERENCES RoomFacility(RoomFacilityID),
    FOREIGN KEY(CityID) REFERENCES City(CityID)
);

CREATE TABLE DT_Date
(
    DateID INT NOT NULL,
    FullDate Datetime NOT NULL, 
    DateMonth INT NOT NULL, 
    Quarter INT NOT NULL,
    DateYear year NOT NULL, 
    PRIMARY KEY(DateID)
);

CREATE TABLE Customer
(
    CustomerID INT PRIMARY KEY,
    CustomerForename VARCHAR(20),
    CustomerSurname VARCHAR(20),
    CustomerDOB DATetime,
    CustomerHomePhone INT,
    CustomerMobilePhone INT,
    CustomerWorkPhone INT,
    CustomerEmail VARCHAR(40),
    CityID INT,
    FOREIGN KEY (CityID) REFERENCES City(CityID)

);

CREATE TABLE Payments
(
    PaymentID INT PRIMARY KEY, 
    PaymentComment VARCHAR(255), 
    PaymentsMethodID INT, 
    PayDate Datetime,
    RoomID INT,
    DateID INT,
    CustomerID INT,
    Price INT,
    PaymentAmount INT,
    FOREIGN KEY(RoomID) REFERENCES Rooms(RoomID),
    FOREIGN KEY(PaymentsMethodID) REFERENCES PaymentsMethod(PaymentsMethodID),
    FOREIGN KEY(DateID) REFERENCES DT_Date(DateID),
    FOREIGN KEY(CustomerID) REFERENCES Customer(CustomerID)
);

Пожалуйста, посмотрите на мою последнюю попытку:

select 
    rank() over (PARTITION BY CountryName order by count(PayDate)),
    CountryName, PayDate, count(Paydate)
from 
    City, Payments, Rooms, Customer, State, Country, DT_Date
where
    Payments.PayDate >= "2010-00-00 00:00:00" 
    and Payments.CustomerID = Customer.CustomerID
    and State.CountryID = Country.CountryID
    and City.StateID = State.StateID
    and Customer.CityID = City.CityID
    and Payments.DateID = DT_Date.DateID
group by 
    CountryName, PayDate;

Запрос сработал. Тем не менее, результаты не верны, потому что есть две PayDates для Великобритании и одна PayDate для США. Ниже показан результат:

Rank CountryName         PayDate       count(Paydate)
1       UK        2015-12-31 00:00:00    4
1       UK        2014-06-10 00:00:00    4
1       USA       2011-11-25 00:00:00    4

Ожидаемый результат:

Rank CountryName        
1       UK        

2       USA       

1 Ответ

0 голосов
/ 03 апреля 2020

Не группировать по PayDate, только по CountryName. Это означает, что вы не можете включить PayDate в результаты, но вы все равно этого не хотите.

Также удалите CountryName из вашего раздела. Ваш ранг только что упорядочен по количеству PayDate.

И для того, чтобы наибольшее количество мест заняло первое место, используйте нисходящий порядок.

select
  rank() over (order by count(PayDate) desc ) as "rank",
  CountryName
from City , Payments,Rooms,Customer,State,Country,DT_Date
WHERE Payments.PayDate >= '2010-00-00 00:00:00'
ANd Payments.CustomerID = Customer.CustomerID
And State.CountryID = Country.CountryID
AND City.StateID = State.StateID
And Customer.CityID = City.CityID
and Payments.DateID = DT_Date.DateID
GROUP by CountryName

Вот упрощенная демонстрация .

Несколько примечаний.

Хотя это может работать в вашей реализации SQL, 2010-00-00 00:00:00 - хитрая дата-время. Используйте 2010-01-01 00:00:00 или лучше эквивалент вашей базы данных year(Payments.PayDate) >= 2010

Не группировать по CountryName, группировать по Country.CountryId. Группировка по имени позволяет случайно сгруппировать две вещи вместе, и уникальные имена стран в схеме не применяются (они должны быть).

Наконец, явные объединения облегчают понимание и обслуживание запроса.

...