Question

I have a table in a DB2 database containing customer information that I need to retrieve along with a count of how many times a specific column in the table is duplicated. Here is an example of the data.

CUSTOMERID | CUSTOMERGROUP | PRODUCTID | PRODUCTNAME | ALERTNAME | ALERTLEVEL | XXX | YYY | ZZZ
12345        ABC             987654      ProductA      Alert1      4            More  Data  Here

A customer is identified by the CustomerID and CustomerGroup columns. They can have any number of products and these products get different types of alerts (ProductA, ProductC and ProductQ could all get Alert1). I need to retrieve the customer information for each row along with a count of how many times that customer got a specific alertname.

In our old MySQL database, this was not too difficult as I would do something like this

SELECT customerID, customerGroup, ProductID, ProductName, AlertName, count(AlertName), AlertLevel, more data....
FROM TABLE
WHERE customerID = XXX and customerGroup = YYY
GROUP BY alertname
ORDER BY AlertLevel, AlertName, ProductName

The group by did not include every column in the select statement so I would get back rows for the customer that included the customer information and a count of the number of times they received a specific alert.

Now that we have migrated to DB2, I am required to put every column from the SELECT into the GROUP BY and this (obviously) makes each row distinct and therefore the count is now returning 1 for every row regardless of whether an alert name matches another row for this customer.

Is there a way to recreate this functionality that will not require a significant overhaul of the way data is retrieved? As the developer of the front end, I have the ability to change the way I manipulate data on the PHP side and I can write SQL statements but I have no option for changing the way the data is stored.

Was it helpful?

Solution

You can do what you want with analytic functions:

SELECT customerID, customerGroup, ProductID, ProductName, AlertName, AlertCount,
       AlertLevel, more data....
FROM (SELECT t.*,
             COUNT(*) OVER (PARTITION BY AlertName) as AlertCount,
             ROW_NUMBER() OVER (PARTITION BY AlertName ORDER BY customerID) as seqnum
      FROM TABLE t
      WHERE customerID = XXX and customerGroup = YYY
     ) t
WHERE seqnum = 1
ORDER BY AlertLevel, AlertName, ProductName;

OTHER TIPS

You can compute counts in separate query and then join it to the original query:

SELECT customerID, customerGroup, ProductID, ProductName, AlertName, t2.alert_count as AlertName, AlertLevel, more data....
  FROM TABLE t1 JOIN (
       SELECT customerid, customergroup, count(AlertName) alert_count 
         FROM table
        GROUP BY alertname) t2 
    ON t1.customerid = t2.customerid
   AND t1.customergroup = t2.customergroup
 WHERE customerID = XXX
   AND customerGroup = YYY
 ORDER BY AlertLevel, AlertName, ProductName

In DB2SQL, group by columns should be in select as well. However, there is Query/400 that can be used to achieve such goal. In order to do that, ensure

  • "Select report summary functions "
  • "Define report breaks"

are properly selected. Save this query and call it, like runqry for example.

OR try this:

With CTE1 (customerid, customergroup, Nbr_of_rows) as (
SELECT t1.customerid, t1.customergroup, count(t1.AlertName)
         FROM table t1
        WHERE t1.customerID = selected_Id
   AND t1.customerGroup = Selected_grp)
select * from CTE1
join table t2 on customerid = t2.customerid and customergroup = t2.customergroup
Order by columns_of_your_choice;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top