SQL - Group By не работает в этом коде - PullRequest
1 голос
/ 21 июня 2011
TRANSFORM Count(Details.Customer_ID) AS CountOfCustomer_ID
SELECT
  Switch(
    [Age] < 25,                  "Under 25",
    [Age] >= 25 And [Age] <= 32, "Between 25 And 32",
    [Age] >= 32 And [Age] <= 40, "Between 32 And 40",
    [Age] >= 40 And [Age] <= 45, "Between 40 And 45",
    [Age] > 45,                  "Over 45"
  ) AS Age_Range
FROM Details
  INNER JOIN [Account Status] ON Details.Customer_ID = [Account Status].Customer_ID
WHERE ((([Account Status].Account_Status)='Active'))
GROUP BY Details.Age, [Account Status].Account_Status
PIVOT Details.site;

Мои результаты подсчитывают Активные аккаунты следующим образом:

Age Range          Site 1  Site 2  Site 3
-----------------  ------  ------  ------
Under 25                   1
Under 25                   1
Between 25 And 32                  1
Between 25 And 32                  1
Between 25 And 32                  1
Between 25 And 32                  1

Когда это должно быть так:

Age Range          Site 1  Site 2  Site 3
-----------------  ------  ------  ------
Under 25                   2
Between 25 And 32                  4

Я также пытался группировать по оператору Switchи это не работает.Пожалуйста, помогите.

Ответы [ 4 ]

3 голосов
/ 22 июня 2011

Ответы, данные другими, верны по своей концепции. Вот SQL, который вы можете использовать, который будет работать

TRANSFORM Count(Details.Customer_ID) AS CountOfCustomer_ID
SELECT Switch(
        [Age] < 25,                  "Under 25",
        [Age] >= 25 And [Age] <= 32, "Between 25 And 32",
        [Age] >= 32 And [Age] <= 40, "Between 32 And 40",
        [Age] >= 40 And [Age] <= 45, "Between 40 And 45",
        [Age] > 45,                  "Over 45"
      ) AS Age_Range
FROM   details 
       INNER JOIN [Account Status] 
         ON details.customer_id = [Account Status].customer_id 
WHERE  (( ( [Account Status].account_status ) = 'Active' )) 
GROUP  BY Switch(
        [Age] < 25,                  "Under 25",
        [Age] >= 25 And [Age] <= 32, "Between 25 And 32",
        [Age] >= 32 And [Age] <= 40, "Between 32 And 40",
        [Age] >= 40 And [Age] <= 45, "Between 40 And 45",
        [Age] > 45,                  "Over 45"
      )
PIVOT Details.site;          

Если вы хотите упростить вещи с помощью встроенного запроса, это то, что сработает

TRANSFORM Count(Customer_ID) AS CountOfCustomer_ID
SELECT 
    Age_range 
 FROM 
(
SELECT Switch(
        [Age] < 25,                  "Under 25",
        [Age] >= 25 And [Age] <= 32, "Between 25 And 32",
        [Age] >= 32 And [Age] <= 40, "Between 32 And 40",
        [Age] >= 40 And [Age] <= 45, "Between 40 And 45",
        [Age] > 45,                  "Over 45"
      ) AS Age_Range, details.customer_id , details.site
FROM   details 
       INNER JOIN [Account Status] 
         ON details.customer_id = [Account Status].customer_id 
WHERE  (( ( [Account Status].account_status ) = 'Active' )) ) t
GROUP BY Age_range

PIVOT site;   
0 голосов
/ 22 июня 2011

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

Определенные вами диапазоны приведут к тому, что кто-то в возрасте 32 или 40 лет попадет в более чем один диапазон:

[Age] >= 25 And [Age] <= 32, "Between 25 And 32",
[Age] >= 32 And [Age] <= 40, "Between 32 And 40",
[Age] >= 40 And [Age] <= 45, "Between 40 And 45",

Диапазоны должны быть:

[Age] >= 25 And [Age] <= 32, "Between 25 And 32",
[Age] > 32 And [Age] <= 40, "Between 33 And 40",
[Age] > 40 And [Age] <= 45, "Between 41 And 45",

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: У меня нет MS Access, только SQL Server, что означает, что операция TRANSFORM недоступна для меня. Я публикую этот ответ, чтобы продемонстрировать другой способ получить желаемый результат без оператора SWITCH.

Вместо использования оператора SWITCH создайте таблицу поиска по возрастному диапазону; Это также дает преимущество в том, что его легче обновлять в случае изменения возрастного диапазона.

CREATE TABLE Age_Ranges
(
    age_range_name VARCHAR(20) NOT NULL PRIMARY KEY,
    age_lower TINYINT NOT NULL,
    age_upper TINYINT NOT NULL
)

INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Under 25', 0, 24)
INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Between 25 And 32', 25, 32)
INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Between 33 And 40', 33, 40)
INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Between 41 And 45', 41, 45)
INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Over 45', 46, 120)
INSERT Age_Ranges(age_range_name, age_lower, age_upper) VALUES ('Error! Bad age data', 121, 255)

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

CREATE TABLE Site_Matrix
(
    site_nbr TINYINT NOT NULL PRIMARY KEY ,
    site_1 TINYINT DEFAULT 0 NOT NULL,
    site_2 TINYINT DEFAULT 0 NOT NULL,
    site_3 TINYINT DEFAULT 0 NOT NULL
)

INSERT Site_Matrix(site_nbr,site_1) VALUES(1,1)
INSERT Site_Matrix(site_nbr,site_2) VALUES(2,1)
INSERT Site_Matrix(site_nbr,site_3) VALUES(3,1)

Наконец, некоторые данные испытаний клиентов.

CREATE TABLE Customer_Details
(
    customer_id INT NOT NULL PRIMARY KEY,
    customer_age TINYINT DEFAULT 255 NOT NULL,
    customer_site tinyint DEFAULT 0 NOT NULL
)

INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(1, 18, 2)
INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(2, 19, 2)
INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(3, 25, 3)
INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(4, 27, 3)
INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(5, 29, 3)
INSERT Customer_Details(customer_id, customer_age, customer_site) VALUES(6, 32, 3)

Используя эти таблицы, вы можете получить желаемый результат с этим запросом. Я пропустил статус присоединения к аккаунту, так как нет необходимости демонстрировать этот метод:

SELECT age_range_name, 
       SUM(site_1) AS site_1,
       SUM(site_2) AS site_2,
       SUM(site_3) AS site_3
FROM Customer_Details INNER JOIN Age_Ranges
    ON customer_age BETWEEN age_lower AND age_upper, Site_Matrix
WHERE customer_site = site_nbr
GROUP BY age_range_name

Вывод запроса:

age_range_name     site_1  site_2  site_3
Between 25 And 32  0       0       4
Under 25           0       2       0

Я уверен, что для работы SQL в Access потребуется внести изменения, извините, но надеюсь, что это даст вам некоторые идеи для решения вашей проблемы.

0 голосов
/ 22 июня 2011

Когда вы GROUP BY Details.Age, результаты будут сгруппированы ПЕРЕД выполнением оператора SELECT.Таким образом, вы на самом деле не группируете то, что вы думаете.Вместо этого он группируется по оригинальным возрастам.

Итак, если вы хотите, чтобы 18, 19 и 21 были сгруппированы вместе, они фактически группируются в свои отдельные группы.

Вам нужно будет получить Age_Range до GROUP BY .... возможно, во вложенном SELECT выражении в FROM?

SELECT a.Age_Range, COUNT(*)
FROM
    (TRANSFORM Count(Details.Customer_ID) AS CountOfCustomer_ID
    SELECT
      Switch(
        [Age] < 25,                  "Under 25",
        [Age] >= 25 And [Age] <= 32, "Between 25 And 32",
        [Age] >= 32 And [Age] <= 40, "Between 32 And 40",
        [Age] >= 40 And [Age] <= 45, "Between 40 And 45",
        [Age] > 45,                  "Over 45"
      ) AS Age_Range
    FROM Details
      INNER JOIN [Account Status] ON Details.Customer_ID = [Account Status].Customer_ID
    WHERE ((([Account Status].Account_Status)='Active'))
    PIVOT Details.site) a
GROUP BY a.Age_Range

ИзвинитеЯ никогда не использовал TRANSFORM или PIVOT, поэтому я не уверен, как это будет работать.Но вы можете увидеть идею.Вложенный SELECT захватывает ваши исходные результаты, затем внешний SELECT делает GROUP BY.

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

Вы пробовали:

GROUP BY Age_Range 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...