Reputation: 9
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.
Upvotes: 0
Views: 26780
Reputation: 36
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
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;
Upvotes: 0
Reputation: 4684
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
Upvotes: 1
Reputation: 1269483
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;
Upvotes: 4