сгруппировать по городам - PullRequest
0 голосов
/ 07 июля 2011

Как мне посоветовал хороший человек и программист Я должен упростить свою таблицу. До сих пор я создал новую таблицу (x-month, y-towns, value-Nettotal), она работает, но все же я не понял, почему он не может сгруппировать значения (nettotal) по городам. С месяцем все в порядке, но значения начинаются слева направо, без нуля. В любом случае, надеюсь, вы все поймете из источника:

вот запросы:

<cfquery name="GET_SALES_TOTAL" datasource="#dsn#">
SELECT
    SUM(COALESCE(nettotal,0)) nettotal,
    SC.CITY_ID,
    DATEPART(MM,INVOICE_DATE) AY,
    C.FULLNAME,
    SC.CITY_NAME
FROM    
    #DSN2_ALIAS#.INVOICE I,
    SETUP_CITY SC,
    COMPANY C
WHERE
    C.COMPANY_ID=I.COMPANY_ID
    AND SC.CITY_ID=C.CITY
    AND PURCHASE_SALES=1
GROUP BY
    DATEPART(MM,INVOICE_DATE),
    SC.CITY_ID,
    C.FULLNAME,
    SC.CITY_NAME
ORDER BY 
      AY,CITY_ID
</cfquery>

<cfquery name="GET_SALES_GRAND_TOTAL" datasource="#dsn#">
SELECT SUM(NETTOTAL) NETTOTAL,SC.CITY_ID,SC.CITY_NAME
FROM #DSN2_ALIAS#.INVOICE I,SETUP_CITY SC,COMPANY C
WHERE C.COMPANY_ID=I.COMPANY_ID AND SC.CITY_ID=C.CITY AND PURCHASE_SALES=1
GROUP BY SC.CITY_ID, SC.CITY_NAME
ORDER BY CITY_ID,CITY_NAME
</cfquery>

а вот и сама таблица:

<table cellpadding="3" cellspacing="1" class="color-border">
<tr class="color-header">
    <td></td>
    <cfoutput query="GET_SALES_GRAND_TOTAL" group="city_id">
        <td>#city_name#</td>
    </cfoutput>
</tr>
<cfoutput query="GET_SALES_TOTAL" group="AY"><!--- months first --->
    <tr class="color-row"><!--- month-specific stuff goes here --->
        <td>#ay#</td>
        <cfoutput group="city_id"><!--- city-specific stuff --->
            <td>#tlformat(nettotal,2)#<!--- format NETTOTAL however you want here ---></td>
        </cfoutput>
    </tr>
</cfoutput>
<tr class="color-header">
    <td>City Overal</td>
    <cfoutput query="GET_SALES_GRAND_TOTAL" group="city_id">
        <td>#tlformat(nettotal,2)#<!--- format NETTOTAL here ---></td>
    </cfoutput>
</tr>
</table>

Вот скриншот, чтобы сделать его более понятным:

screenshot

Все остальное, кроме группировки городов, работает отлично!

Ответы [ 3 ]

2 голосов
/ 07 июля 2011

Похоже, проблема в том, что нет записи для каждой комбинации месяца и города.Теперь все в порядке, если каждый город имеет продажи каждый месяц, но мы можем улучшить этот код, чтобы он правильно обрабатывал «пропущенные» записи.

Некоторые базы данных имеют специальный синтаксис, который поможет вам составить таблицунапример: Access имеет TRANSFORM, сервер Oracle и SQL имеет CUBE и ROLLUP, MySQL имеет WITH ROLLUP.Однако вам, возможно, все же придется настроить свой CF даже после корректировки запроса, поэтому давайте попробуем поработать с тем, что у вас есть, в более общей форме.

Вместо внутреннего соединения нам нужно внешнее соединение: все городаплюс продажи для любого города, в котором есть продажи.Однако нам тоже нужны все месяцы.В данном конкретном случае мы можем использовать декартово произведение, чтобы получить месяцы и города.(Будьте очень осторожны с этим: вы должны использовать их только в ситуациях, когда вам действительно нужна одна запись для каждой комбинации поля A и поля B. Легко использовать одну запись в неправильном месте и получить 10000 записей вместо 100).

Давайте возьмем предложение Йохана и изменим его немного:

SELECT SUM(COALESCE(NETTOTAL,0)) NETTOTAL
  ,SC.CITY_ID
  ,SC.CITY_NAME
  ,M.INVOICE_MONTH                     
FROM SETUP_CITY SC
  LEFT OUTER JOIN COMPANY C ON SC.CITY_ID = C.CITY                   
  LEFT OUTER JOIN #DSN2_ALIAS#.INVOICE I ON C.COMPANY_ID = I.COMPANY_ID
  , (SELECT DISTINCT DATEPART(MM,INVOICE_DATE) INVOICE_MONTH FROM #DSN2_ALIAS#.INVOICE) M
WHERE PURCHASE_SALES = 1   
  AND DATEPART(MM,I.INVOICE_DATE) = M.INVOICE_MONTH                  
GROUP BY SC.CITY_ID, SC.CITY_NAME, M.INVOICE_MONTH
ORDER BY SC.CITY_NAME, M.INVOICE_MONTH 

Я немного нечеткий формат для декартового произведения с другими присутствующими внутренними объединениями, поэтому давайтеэто попытка, и мы можем изменить ее по мере необходимости.

Это должно дать вам запрос со значением для каждого города за каждый месяц с продажами.Точная форма внешнего объединения может потребоваться изменить в зависимости от базы данных, которую вы используете, но это должно, по крайней мере, привести вас в правильном направлении.

Обратите внимание, что вам нужно будет изменить свой CF, чтобы он соответствовал пересмотренному запросу, но я думаю, что только эта часть:

<cfoutput query="GET_SALES_TOTAL" group="AY"><!--- months first --->
    <tr class="color-row"><!--- month-specific stuff goes here --->
        <td>#ay#</td>

становится

<cfoutput query="GET_SALES_TOTAL" group="INVOICE_MONTH"><!--- months first --->
    <tr class="color-row"><!--- month-specific stuff goes here --->
        <td>#invoice_month#</td>
0 голосов
/ 07 июля 2011

В ColdFusion, при использовании сгруппированного cfoutput, столбцы, по которым вы группируете, также должны быть в части ORDER BY вашего запроса.Поэтому измените первый запрос на ORDER BY AY, city_id И измените второй запрос на ORDER BY SC.CITY_NAME, city_id

0 голосов
/ 07 июля 2011

SUM имеет раздражающую особенность оценки до нуля, если одно из суммированных значений равно нулю.

Попробуйте изменить SELECT SUM(NETTOTAL) NETTOTAL на SELECT SUM(COALESCE(nettotal,0)) nettotal

Замечание по синтаксису запроса

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

SELECT SUM(NETTOTAL) NETTOTAL
  ,SC.CITY_ID
  ,SC.CITY_NAME                     
FROM #DSN2_ALIAS#.INVOICE I
  INNER JOIN SETUP_CITY SC ON SC.CITY_ID = C.CITY
  INNER JOIN COMPANY C ON C.COMPANY_ID = I.COMPANY_ID                   
WHERE PURCHASE_SALES = 1                     
GROUP BY SC.CITY_ID, SC.CITY_NAME                     
ORDER BY SC.CITY_NAME 

Таким образом, вы можете отделить условия объединения от условий фильтра, и ваш запрос будет гораздо проще поддерживать и расширять, если вам нужно объединить множество таблиц.
И в качестве бонуса вы открепитесь от SQL '89, чтобы наконец-то покинуть Loveshack .

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