将 HAVING 子句与 GROUP by 一起使用到 Return 个唯一记录
Using the HAVING Clause with GROUP by to Return Unique Records
大家好,
我很难理解 GROUP BY AND HAVING 子句的机制,希望得到一些建议。
我正在尝试查询两个 tables - PRODUCTS 和 ORDER_ITEMS。 PRODUCT_ID栏是用来link这两个table的。
我想查看已从某个供应商订购的产品(使用 SUPPLIER_ID 列过滤,该列位于 ORDER_ITEMS); (ORDER_STATUS 6 in ORDER_ITEMS)之前已成功下单,且未被删除的(RECORD_DELETED 列 ORDER_ITEMS)。我只使用 PRODUCTS table 来显示产品名称。此外,我只希望返回不同的产品,这意味着我想排除任何重复 PRODUCT_ID 列
的结果
这是我正在使用的查询:
SELECT
PD.PRODUCT_ID,
PD.PRODUCT_NAME,
PD.BARCODE,
PD.SUPPLIER_BARCODE,
COUNT(PD.PRODUCT_ID) AS COUNTED,
ODI.ORDER_ITEM_ID
FROM PRODUCTS PD
INNER JOIN ORDER_ITEMS ODI
ON PD.PRODUCT_ID = ODI.PRODUCT_ID
WHERE ODI.SUPPLIER_ID = 34359738399
AND ORDER_STATUS = 6
AND ODI.RECORD_DELETED = 0
GROUP BY PD.PRODUCT_ID,PD.PRODUCT_NAME,PD.BARCODE,PD.SUPPLIER_BARCODE,ODI.ORDER_ITEM_ID
HAVING COUNT(ODI.PRODUCT_ID) = 1
ORDER BY PRODUCT_ID ASC
不幸的是,这将返回 502 条记录,其中许多记录与 PRODUCT_ID 重复。如果我从查询中删除 ORDER_ITEM_ID 列,则会返回 175 记录。这 175 条记录是符合上述标准的产品。问题是我还需要从 ORDER_ITEMS 中提取 ORDER_ITEM_ID(以及其他一些列)。
我隐约了解到,当我包含 ORDER_ITEMS 时,查询将按 ORDER_ITEM[=56 对数据进行分组=] 列等将根据每个个体 ORDER_ITEM_ID 计算 PRODUCT_ID 值。这导致每个产品的计数始终为 1。
如何解决这个问题?另外,是否有更 suitable 的方式来执行此任务,允许我为每个重复的产品包含一个 ORDER_ITEM 记录?而不是像我上面那样完全省略它们?
这是上面查询返回的一些数据:
PRODUCT_ID,PRODUCT_NAME,BARCODE,SUPPLIER_BARCODE,COUNTED,ORDER_ITEM_ID
34359738628,ADCORTYL INTRA-ARTIC/DERMAL 10MG/ML 5ML,5099627022132,5012712000037,1,34359755708
34359739609,ARTELAC 3.2MG/ML EYE DROPS SOLN,5099627456722,5027519008933,1,34359741719
34359739626,ASACOLON 500MG SUPPOSITORIES,5099627516587,5015313012737,1,34359742783
34359739767,ATROVENT 250MCG/1ML UDV NEB SOLN,5099627639637,5012816012561,1,34359738421
34359739770,ATROVENT 500MCG/2ML UDV NEB SOLN,5099627460293,5012816012592,1,34359743524
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749091
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749687
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749715
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359754053
34359740053,BACTIGRAS MED DRSS 10CMX10CM STERILE GMS,5099627672368,5000223421984,1,34359748101
34359740062,BACTROBAN 2% OINTMENT,5099627053914,5099211003165,1,34359755226
34359740558,BETNOVATE RD CREAM,5099627005692,5099211001642,1,34359752422
34359740558,BETNOVATE RD CREAM,5099627005692,5099211001642,1,34359738487
34359741045,BISODOL ANTACID TABS,5099627057707,5014398001438,1,34359750542
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359746555
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359751650
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359751783
34359742132,BURINEX 1MG TABS,5099627551328,5702191004212,1,34359749705
34359742152,BUSCOPAN 20MG/ML SOLN FOR INJ,5099627006620,5012816018532,1,34359749083
在上面的示例中,返回了多个具有重复 PRODUCT_ID 值的记录,例如 ASACOLON 500MG SUPPOSITORIES
您需要 GROUP_CONCAT/LISTAGG
相当于 SQL Server
。您可以使用 XML, STUFF and correlated subquery
作为替换。
如果 PRODUCT_ID
是 UNIQUE
您可以使用:
WITH cte AS
(
SELECT
PD.PRODUCT_ID,
PD.PRODUCT_NAME,
PD.BARCODE,
PD.SUPPLIER_BARCODE,
ODI.ORDER_ITEM_ID
FROM PRODUCTS PD
JOIN ORDER_ITEMS ODI
ON PD.PRODUCT_ID = ODI.PRODUCT_ID
WHERE ODI.SUPPLIER_ID = 34359738399
AND ORDER_STATUS = 6
AND ODI.RECORD_DELETED = 0
)
SELECT PRODUCT_ID,
PRODUCT_NAME,
BARCODE,
SUPPLIER_BARCODE,
[COUNTED] = COUNT(PD.PRODUCT_ID),
[ORDER_ITEM_ID] = STUFF((SELECT CONCAT(',' , ORDER_ITEM_ID)
FROM cte c2
WHERE c2.PRODUCT_ID = c1.PRODUCT_ID
ORDER BY c2.ORDER_ITEM_ID
FOR XML PATH ('')), 1, 1, '')
FROM cte c1
GROUP BY PRODUCT_ID,PRODUCT_NAME,BARCODE,SUPPLIER_BARCODE
HAVING COUNT(PRODUCT_ID) = 1
ORDER BY PRODUCT_ID ASC;
否则使用多列关联:
SELECT CONCAT(',' , ORDER_ITEM_ID)
FROM cte c2
WHERE c2.PRODUCT_ID = c1.PRODUCT_ID
AND c2.PRODUCT_NAME = c1.PRODUCT_NAME
AND ...
ORDER BY c2.ORDER_ITEM_ID
FOR XML PATH ('')), 1, 1, '')
大家好,
我很难理解 GROUP BY AND HAVING 子句的机制,希望得到一些建议。
我正在尝试查询两个 tables - PRODUCTS 和 ORDER_ITEMS。 PRODUCT_ID栏是用来link这两个table的。
我想查看已从某个供应商订购的产品(使用 SUPPLIER_ID 列过滤,该列位于 ORDER_ITEMS); (ORDER_STATUS 6 in ORDER_ITEMS)之前已成功下单,且未被删除的(RECORD_DELETED 列 ORDER_ITEMS)。我只使用 PRODUCTS table 来显示产品名称。此外,我只希望返回不同的产品,这意味着我想排除任何重复 PRODUCT_ID 列
的结果这是我正在使用的查询:
SELECT
PD.PRODUCT_ID,
PD.PRODUCT_NAME,
PD.BARCODE,
PD.SUPPLIER_BARCODE,
COUNT(PD.PRODUCT_ID) AS COUNTED,
ODI.ORDER_ITEM_ID
FROM PRODUCTS PD
INNER JOIN ORDER_ITEMS ODI
ON PD.PRODUCT_ID = ODI.PRODUCT_ID
WHERE ODI.SUPPLIER_ID = 34359738399
AND ORDER_STATUS = 6
AND ODI.RECORD_DELETED = 0
GROUP BY PD.PRODUCT_ID,PD.PRODUCT_NAME,PD.BARCODE,PD.SUPPLIER_BARCODE,ODI.ORDER_ITEM_ID
HAVING COUNT(ODI.PRODUCT_ID) = 1
ORDER BY PRODUCT_ID ASC
不幸的是,这将返回 502 条记录,其中许多记录与 PRODUCT_ID 重复。如果我从查询中删除 ORDER_ITEM_ID 列,则会返回 175 记录。这 175 条记录是符合上述标准的产品。问题是我还需要从 ORDER_ITEMS 中提取 ORDER_ITEM_ID(以及其他一些列)。
我隐约了解到,当我包含 ORDER_ITEMS 时,查询将按 ORDER_ITEM[=56 对数据进行分组=] 列等将根据每个个体 ORDER_ITEM_ID 计算 PRODUCT_ID 值。这导致每个产品的计数始终为 1。
如何解决这个问题?另外,是否有更 suitable 的方式来执行此任务,允许我为每个重复的产品包含一个 ORDER_ITEM 记录?而不是像我上面那样完全省略它们?
这是上面查询返回的一些数据:
PRODUCT_ID,PRODUCT_NAME,BARCODE,SUPPLIER_BARCODE,COUNTED,ORDER_ITEM_ID
34359738628,ADCORTYL INTRA-ARTIC/DERMAL 10MG/ML 5ML,5099627022132,5012712000037,1,34359755708
34359739609,ARTELAC 3.2MG/ML EYE DROPS SOLN,5099627456722,5027519008933,1,34359741719
34359739626,ASACOLON 500MG SUPPOSITORIES,5099627516587,5015313012737,1,34359742783
34359739767,ATROVENT 250MCG/1ML UDV NEB SOLN,5099627639637,5012816012561,1,34359738421
34359739770,ATROVENT 500MCG/2ML UDV NEB SOLN,5099627460293,5012816012592,1,34359743524
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749091
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749687
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359749715
34359739893,AZOPT 10MG/ML EYE DROPS SUSP,5099627831543,5015664002753,1,34359754053
34359740053,BACTIGRAS MED DRSS 10CMX10CM STERILE GMS,5099627672368,5000223421984,1,34359748101
34359740062,BACTROBAN 2% OINTMENT,5099627053914,5099211003165,1,34359755226
34359740558,BETNOVATE RD CREAM,5099627005692,5099211001642,1,34359752422
34359740558,BETNOVATE RD CREAM,5099627005692,5099211001642,1,34359738487
34359741045,BISODOL ANTACID TABS,5099627057707,5014398001438,1,34359750542
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359746555
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359751650
34359741995,BROLENE 0.1% EYE DROPS SOLN,5099627006323,50982790,1,34359751783
34359742132,BURINEX 1MG TABS,5099627551328,5702191004212,1,34359749705
34359742152,BUSCOPAN 20MG/ML SOLN FOR INJ,5099627006620,5012816018532,1,34359749083
在上面的示例中,返回了多个具有重复 PRODUCT_ID 值的记录,例如 ASACOLON 500MG SUPPOSITORIES
您需要 GROUP_CONCAT/LISTAGG
相当于 SQL Server
。您可以使用 XML, STUFF and correlated subquery
作为替换。
如果 PRODUCT_ID
是 UNIQUE
您可以使用:
WITH cte AS
(
SELECT
PD.PRODUCT_ID,
PD.PRODUCT_NAME,
PD.BARCODE,
PD.SUPPLIER_BARCODE,
ODI.ORDER_ITEM_ID
FROM PRODUCTS PD
JOIN ORDER_ITEMS ODI
ON PD.PRODUCT_ID = ODI.PRODUCT_ID
WHERE ODI.SUPPLIER_ID = 34359738399
AND ORDER_STATUS = 6
AND ODI.RECORD_DELETED = 0
)
SELECT PRODUCT_ID,
PRODUCT_NAME,
BARCODE,
SUPPLIER_BARCODE,
[COUNTED] = COUNT(PD.PRODUCT_ID),
[ORDER_ITEM_ID] = STUFF((SELECT CONCAT(',' , ORDER_ITEM_ID)
FROM cte c2
WHERE c2.PRODUCT_ID = c1.PRODUCT_ID
ORDER BY c2.ORDER_ITEM_ID
FOR XML PATH ('')), 1, 1, '')
FROM cte c1
GROUP BY PRODUCT_ID,PRODUCT_NAME,BARCODE,SUPPLIER_BARCODE
HAVING COUNT(PRODUCT_ID) = 1
ORDER BY PRODUCT_ID ASC;
否则使用多列关联:
SELECT CONCAT(',' , ORDER_ITEM_ID)
FROM cte c2
WHERE c2.PRODUCT_ID = c1.PRODUCT_ID
AND c2.PRODUCT_NAME = c1.PRODUCT_NAME
AND ...
ORDER BY c2.ORDER_ITEM_ID
FOR XML PATH ('')), 1, 1, '')