PostgreSQL按新定义的具有不明确名称的列分组

时间:2019-06-19 22:20:00

标签: postgresql

我正在尝试创建一个具有与原始表同名的列的视图。查询看起来像这样。

SELECT
  mmo.model_id AS model_id,
  mmo.location_id AS location_id,
  COALESCE(
    sp.replacement,
    mmo.part_number) AS part_number,
  SUM(mmo.attr) AS attr
FROM model mmo
  LEFT JOIN part sp
    ON mmo.part_number = sp.part_number
GROUP BY
  mmo.location_id,
  part_number

但是,GROUP BY中的part_number列不明确。

如果我分配了不同的列名,例如part_id,它就可以正常工作。

SELECT
  mmo.model_id AS model_id,
  mmo.location_id AS location_id,
  COALESCE(
    sp.replacement,
    mmo.part_number) AS part_id,
  SUM(mmo.attr) AS attr
FROM model mmo
  LEFT JOIN part sp
    ON mmo.part_number = sp.part_number
GROUP BY
  mmo.location_id,
  part_id

但是,我试图使用此查询来定义与原始模型表具有相同结构的视图,因此替换列名并不理想。

我可以进行子查询来实现

SELECT
  model_id,
  location_id,
  part_id AS part_number,
  attr
FROM (
  SELECT
    mmo.model_id AS model_id,
    mmo.location_id AS location_id,
    COALESCE(
      sp.replacement,
      mmo.part_number) AS part_id,
    SUM(mmo.attr) AS attr
  FROM model mmo
    LEFT JOIN part sp
      ON mmo.part_number = sp.part_number
  GROUP BY
    mmo.location_id,
    part_id
)

但是它并不优雅。我想知道是否有更好的解决方案可以参考COALESCE定义的列。也许像这样:

SELECT
  mmo.model_id AS model_id,
  mmo.location_id AS location_id,
  COALESCE(
    sp.replacement,
    mmo.part_number) AS part_number,
  SUM(mmo.attr) AS attr
FROM model mmo
  LEFT JOIN part sp
    ON mmo.part_number = sp.part_number
GROUP BY
  mmo.location_id,
  this.part_number

2 个答案:

答案 0 :(得分:1)

GROUP BY子句中,您可以通过列号标识列:

SELECT
  mmo.model_id AS model_id,
  mmo.location_id AS location_id,
  COALESCE(
    sp.replacement,
    mmo.part_number) AS part_number,
  SUM(mmo.attr) AS attr
FROM model mmo
  LEFT JOIN part sp
    ON mmo.part_number = sp.part_number
GROUP BY
  2, 3

请参见the relevant section of the documentation.

中的第一段

答案 1 :(得分:1)

您可以通过选择列表中列的位置来引用它:

#include <windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <string>

int main() {

    MODULEENTRY32A me32;
    HWND hwnd = FindWindow(0, L"Window Name");
    DWORD dwPID;
    GetWindowThreadProcessId(hwnd, &dwPID);

    HANDLE hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID);

    me32.dwSize = sizeof(MODULEENTRY32A);
    if (Module32FirstA(hModuleSnap, &me32))
    {
        do
        {
            std::string moduleName = me32.szModule;
            std::cout << moduleName << std::endl; // important line
        }
        while (Module32NextA(hModuleSnap, &me32));
    }

    return 0;
}

您可能会说这比使用子查询来重新标记事物(或只是在GROUP BY中重复合并调用)还要优雅,但它肯定会更短。