MySQL查询按国家/地区对客户进行排名

时间:2017-05-20 12:48:06

标签: mysql

我的目标很简单:我希望根据预订号码按国家/地区对客户进行排名。

这是我的表:

___ BillableDatas

|--------|---------------|------------|----------|
| BIL_Id | BIL_BookingId | BIL_Date   | BIL_Type |
|--------|---------------|------------|----------|
| 1      | 90            | 2017-05-04 | Night    |
| 2      | 90            | 2017-05-05 | Night    |
| 3      | 90            | 2017-05-06 | Night    |
| 4      | 91            | 2017-05-14 | Night    |
| 5      | 92            | 2017-05-20 | Night    |
| 6      | 93            | 2017-05-28 | Night    |
|--------|---------------|------------|----------|

___预订

|--------|--------------|
| BOO_Id | BOO_ClientId |
|--------|--------------|
| 90     | 30           |
| 91     | 31           |
| 92     | 32           |
| 93     | 33           |
|--------|--------------|

___卡迪斯

|--------|---------------------------|
| KDX_Id | KDX_PostalAddress_Country |
|--------|---------------------------|
| 30     | FR                        |
| 31     | CA                        |
| 32     | CA                        |
| 33     | ES                        |
|--------|---------------------------|

___ CountryList

|----------|---------|
| CTY_Code | CTY_en  |
|----------|---------|
| FR       | France  |
| CA       | Canada  |
| ES       | Spain   |
|----------|---------|

我希望2017-05-012017-05-30之间的时间段为:

|------|---------|----------|-----------|------------|-------------|
| Rank | Country | night_nb | night_pct | booking_nb | booking_pct |
|------|---------|----------|-----------|------------|-------------|
| 1    | Canada  | 2        | 33.33     | 2          | 50          |
| 2    | France  | 3        | 50.00     | 1          | 25          |
| 3    | Espagne | 1        | 16.66     | 1          | 25          |
|------|---------|----------|-----------|------------|-------------|

这是我尝试过的代码:

SELECT CTY_Code, CTY_en
   , night_nb 
   , 100*night_nb/@sum_night_nb AS night_pct
   , booking_nb 
   , 100*booking_nb/@sum_booking_nb AS booking_pct
FROM     (
     SELECT     CTY_Code, CTY_en
              , @sum_night_nb := count(BIL_Id) night_nb
              , @sum_booking_nb := count(distinct BIL_BookingId) booking_nb
     FROM       ___CountryList cty 
     INNER JOIN ___Kardex kdx
             ON KDX_PostalAddress_Country = CTY_Code
     LEFT JOIN  (___Bookings boo
     INNER JOIN ___BillableDatas bil
             ON BIL_BookingId = BOO_Id
            AND BIL_Type = "Night")
             ON KDX_Id = BOO_ClientId 
            AND BIL_Date between "2017-05-01" AND "2017-05-30"
     GROUP BY   CTY_en with rollup
     ) base
WHERE CTY_en is not null
ORDER BY booking_nb DESC
, CTY_en ASC

1 个答案:

答案 0 :(得分:0)

您可以在外部查询中为行号添加变量

SELECT 
   (@row := ifnull(@row, 0) + 1) as row_number
   , CTY_en
   , night_nb 
   , 100*night_nb/@sum_night_nb AS night_pct
   , booking_nb 
   , 100*booking_nb/@sum_booking_nb AS booking_pct
FROM     (
     SELECT     CTY_Code, CTY_en
              , @sum_night_nb := count(BIL_Id) night_nb
              , @sum_booking_nb := count(distinct BIL_BookingId) booking_nb
     FROM       ___CountryList cty 
     JOIN ___Kardex kdx
       ON KDX_PostalAddress_Country = CTY_Code
     LEFT JOIN (
         ___Bookings boo
         JOIN ___BillableDatas bil 
           ON (BIL_BookingId = BOO_Id AND BIL_Type = "Night")
     )
     ON (KDX_Id = BOO_ClientId AND BIL_Date between "2017-05-01" AND "2017-05-30")
     GROUP BY CTY_en with rollup
     ) base
JOIN (select @row := 0) r
WHERE CTY_en is not null
ORDER BY booking_nb DESC, CTY_en ASC;

测试数据:

drop table if exists ___BillableDatas;
drop table if exists ___Bookings;
drop table if exists ___Kardex;
drop table if exists ___CountryList;

create table ___BillableDatas (BIL_Id int, BIL_BookingId int,BIL_Date date, BIL_Type varchar(30));
insert into ___BillableDatas (BIL_Id, BIL_BookingId, BIL_Date, BIL_Type) values
(1,90,'2017-05-04','Night'),(2,90,'2017-05-05','Night'),
(3,90,'2017-05-06','Night'),(4,91,'2017-05-14','Night'),
(5,92,'2017-05-20','Night'),(6,93,'2017-05-28','Night');

create table ___Bookings (BOO_Id int, BOO_ClientId int);
insert into ___Bookings (BOO_Id, BOO_ClientId) values
(90,30),(91,31),(92,32),(93,33);

create table ___Kardex (KDX_Id int, KDX_PostalAddress_Country char(2));
insert into ___Kardex (KDX_Id, KDX_PostalAddress_Country) values
(30,'FR'),(31,'CA'),(32,'CA'),(33,'ES');

create table ___CountryList (CTY_Code char(2), CTY_en varchar(30));
insert into ___CountryList (CTY_Code, CTY_en) values
('FR','France'),('CA','Canada'),('ES','Spain');