update one column based on other column value - db2

I have a table where if same name comes it should have same id if not then I need to update the Id column with lowest id number if the name is same.
My data looks like this
Name | Id
AAA | 1
AAA | 2
BBB | 4
BBB | 4
BBB | 5
the output should be
Name | Id
AAA | 1
AAA | 1
BBB | 4
BBB | 4
BBB | 4

You can use OLAP functions for that.
http://www-01.ibm.com/support/knowledgecenter/SSEPGG_10.5.0/com.ibm.db2.luw.sql.ref.doc/doc/r0023461.html

Related

How to perform select group by with max in PowerShell?

I have an object containing the following in PowerShell:
Date Item Total
---- ---- -----
20190505 AAA 2
20190505 BBB 1
20190514 AAA 6
20190514 BBB 1
20190514 CCC 2
20190524 AAA 5
20190524 BBB 1
20190524 CCC 1
20190524 DDD 2
I want to select the maximum total for each type of item. The result should look something like this:
Item Total
---- -----
AAA 6
BBB 1
CCC 2
DDD 2
I found a solution:
$myObject | Group-Object -Property Item | Foreach {
$_.Group | Sort Total -Descending | Select -First 1
}

PostgreSQL COUNT DISTINCT on one column while checking duplicates of another column

I have a query that results in such a table:
guardian_id | child_id | guardian_name | relation | child_name |
------------|----------|---------------|----------|------------|
1 | 1 | John Doe | father | Doe Son |
2 | 1 | Jane Doe | mother | Doe Son |
3 | 2 | Peter Pan | father | Pan Dghter |
4 | 2 | Pet Pan | mother | Pan Dghter |
1 | 3 | John Doe | father | Doe Dghter |
2 | 3 | Jane Doe | mother | Doe Dghter |
So from these results, I need to count the families. That is, distinct children with the same guardians. From the results above, There are 3 children but 2 families. How can I achieve this?
If I do:
SELECT COUNT(DISTINCT child_id) as families FROM (
//larger query
)a
I'll get 3 which is not correct.
Alternatively, how can I incorporate a WHERE clause that checks DISTINCT guardian_id's? Any other approaches?
Also note that there are instances where a child may have one guardian only.
To get the distinct family you can try the following approach.
select distinct array_agg(distinct guardian_id)
from family
group by child_id;
The above query will return the list of unique families.
eg.
{1,2}
{3,4}
Now you can apply the count on top of it.

How print Horizontally on ireport dynamically while printing on next page when reached column limit for single page?

I think the the question can be reworded properly please kindly edit if necessary. I've also checked other questions and answers over the internet but it didn't help.
Below is what I'm trying to achieve, basically I want the columns to display horizontally; and if they reach lets say 3 columns(name) it will start on another page. These columns have subcolumns below.
I've already tried setting the Print Order to horizontal and set the columns to 3. However its showing the unexpected output.
This my table structure(These have thousands of records). I've also tried to turn this into array but it doesnt work.
How can I achieve the ouput above on the report? If you can provide documents or links about this is really helpful. Im using Postgres and ireport 3.7.6.
date | name
------+--------
1 | Name 1
2 | Name 1
3 | Name 1
4 | Name 1
5 | Name 1
6 | Name 1
7 | Name 1
8 | Name 1
9 | Name 1
10 | Name 1
1 | Name 2
2 | Name 2
3 | Name 2
4 | Name 2
5 | Name 2
6 | Name 2
7 | Name 2
8 | Name 2
9 | Name 2
10 | Name 2
1 | Name 3
2 | Name 3
3 | Name 3
4 | Name 3
5 | Name 3
6 | Name 3
7 | Name 3
8 | Name 3
9 | Name 3
10 | Name 3
(30 rows)
I'm not really familiar with ireport, but from the PostgreSQL perspective, I believe you're looking for crosstab. Bellow an example:
(If you haven't installed the extension yet, just execute this command)
CREATE EXTENSION tablefunc
Considering the following table (I believe it's close to your structure):
CREATE TEMPORARY TABLE t (id INT, name TEXT,val INT);
And the following values ...
db=#INSERT INTO t VALUES (1,'Name1',10),
(2,'Name1',20),
(3,'Name1',80),
(1,'Name2',30),
(2,'Name2',52),
(3,'Name2',40);
db=# SELECT * FROM t;
id | name | val
----+-------+-----
1 | Name1 | 10
2 | Name1 | 20
3 | Name1 | 80
1 | Name2 | 30
2 | Name2 | 52
3 | Name2 | 40
(6 Zeilen)
... you can use crosstab to display your results horizontally:
db=# SELECT *
FROM crosstab( 'SELECT name,id,val FROM t')
AS j(name text, val1 int, val2 int, val3 int);
name | val1 | val2 | val3
-------+------+------+------
Name1 | 10 | 20 | 80
Name2 | 30 | 52 | 40
(2 Zeilen)

Informix - concatenating data contained in same column based on id

I have a need to concatenate strings in the same field based on id in Informix. I realize this can be done easily in MSSQL.
Here is an example of my current table:
id | doc_num | page_num | description
-------------------------------------------------
1 | 1 | 1 | This is the story about
1 | 1 | 2 | a girl named Daisy.
1 | 2 | 1 | Daisy had a dog named
1 | 2 | 2 | Rover.
2 | 1 | 1 | This story is about Bob.
2 | 2 | 1 | Bob is a DBA who works
2 | 2 | 2 | at an important company
2 | 2 | 3 | that develops important
2 | 2 | 4 | software.
Desired output:
id | description
------------------------------------------------------------
1 | This is a story about a girl named Daisy.
| Daisy has a dog named Rover.
------------------------------------------------------------
2 | This story is about Bob. Bob is a DB who works at an
| important company that develops important software.
------------------------------------------------------------
I found my answer here:
https://dba.stackexchange.com/questions/65101/multiple-table-rows-in-one-row-informix
Since I am running Informix 12, it works using rank() over() sys_connect_by_path().

PostgreSQL update from subquery

I have a following PostgreSQL table:
CREATE TABLE users (
user_id INTEGER DEFAULT nextval('users_user_id_seq') NOT NULL,
user_old_id CHARACTER VARYING(36),
created_by INTEGER,
created_by_old character varying(36),
last_updated_by INTEGER,
last_updated_by_old character varying(36),
CONSTRAINT users_pkey PRIMARY KEY (user_id)
);
Based on data in this table I need to update:
created_by field with user_id from this table for every row
where created_by_old = user_old_id Please note that created_by_old can be NULL and therefore must be avoided in this case.
last_updated_by field with user_id from this table for every
row where last_updated_by_old = user_old_id Please note that last_updated_by_old can be NULL and therefore must be avoided in this case.
This is a sample data:
Actual:
user_id | user_old_id | created_by | created_by_old | last_updated_by | last_updated_by_old
--------------------------------------------------------------------------------------------
1 | aaa | | ccc | | bbb
--------------------------------------------------------------------------------------------
2 | bbb | | ddd | | aaa
--------------------------------------------------------------------------------------------
3 | ccc | | | | ddd
--------------------------------------------------------------------------------------------
4 | ddd | | aaa | |
Expected:
user_id | user_old_id | created_by | created_by_old | last_updated_by | last_updated_by_old
--------------------------------------------------------------------------------------------
1 | aaa | 3 | ccc | 2 | bbb
--------------------------------------------------------------------------------------------
2 | bbb | 4 | ddd | 1 | aaa
--------------------------------------------------------------------------------------------
3 | ccc | | | 4 | ddd
--------------------------------------------------------------------------------------------
4 | ddd | 1 | aaa | |
I think it can be implemented with a subquery but can't figure out by myself right now how to implement this query. Please help.
If you want a more efficient update statement you can use a derived table that gets the information you want as the source of your update statement:
update users u1
set created_by = t.new_created_by,
last_updated_by = t.new_updated_by
from (
select u2.user_id, u2.user_old_id,
cr.user_id as new_created_by,
lu.user_id as new_updated_by
from users u2
left join users cr on cr.user_old_id = u2.created_by_old
left join users lu on lu.user_old_id = u2.last_updated_by_old
) t
where t.user_id = u1.user_id;
Usually the target table of the update should never be repeated in the from clause, but this case is a rare example where it can't be avoided.
But this will only work properly if user_old_id is also unique, not only user_id.
Online example: http://rextester.com/HKM21985
Not too efficient ,but if that's not an issue you can do this :
UPDATE users u
SET u.created_by = (SELECT t.user_id FROM users t
WHERE u.created_by_old = t.user_old_id),
u.last_updated_by = (SELECT s.user_id FROM users s
WHERE u.last_updated_by = s.user_old_id)