Common records for 2 fields in a table? - db2

I have a Table which has 2 fields say A,B. Suppose A has values a1,a2.
Corresponding records for a1 in B are 1,2,3,x,y,z.
Corresponding records for a2 in B are 1,2,3,4,d,e,f
I need a a query to be written in DB2, so that it will fetch the common records in B for each record in A (a1 and a2).
So here the output would be :
A B
a1 1
a1 2
a1 3
a2 1
a2 2
a2 3
Can someone please help on this?

Try something like:
SELECT A, B
FROM Table t1
WHERE (SELECT COUNT(*) FROM Table t2 WHERE t2.B = t1.B)
= (SELECT COUNT(DISTINCT t3.A) FROM Table t3)
ORDER BY A, B

This might not be 100% accurate as I can't test it out in DB2 so you might have to tweak the query a little bit to make it work.
with t(num) as (select count(distinct A) from table)
select t1.A, t1.B
from table t1, table t2, t
where t1.B = t2.B
group by t1.A, t1.B, num
having count(*) = num
Basically, the idea is to join the same table with column B and filter out just the ones that match exactly the same number of times as the number of elements in column A, which indicates that it is a common record out of all the A values.

Related

DB2: SQL to return all rows in a group having a particular value of a column in two latest records of this group

I have a DB2 table having one of the columns (A) which has either value PQR or XYZ.
I need output where the latest two records based on col C date have value A = PQR.
Sample Table
A B C
--- ----- ----------
PQR Mark 08/08/2019
PQR Mark 08/01/2019
XYZ Mark 07/01/2019
PQR Joe 10/11/2019
XYZ Joe 10/01/2019
PQR Craig 06/06/2019
PQR Craig 06/20/2019
In this sample table, my output would be Mark and Craig records
Since 11.1
You may use the nth_value OLAP function.
Refer to OLAP specification.
SELECT A, B, C
FROM
(
SELECT
A, B, C
, NTH_VALUE (A, 1) OVER (PARTITION BY B ORDER BY C DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) C1
, NTH_VALUE (A, 2) OVER (PARTITION BY B ORDER BY C DESC ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) C2
FROM TAB
)
WHERE C1 = 'PQR' AND C2 = 'PQR'
dbfiddle link.
Older versions
SELECT T.*
FROM TAB T
JOIN
(
SELECT B
FROM
(
SELECT
A, B
, ROWNUMBER() OVER (PARTITION BY B ORDER BY C DESC) RN
FROM TAB
)
WHERE RN IN (1, 2)
GROUP BY B
HAVING MIN(A) = MAX(A) AND COUNT(1) = 2 AND MIN(A) = 'PQR'
) G ON G.B = T.B;
A simple solution could be
SELECT A,B,C
FROM tab
WHERE A = 'PQR'
ORDER BY C DESC FETCH FIRST 2 ROWS only

Product of regular field and computed field in an ORDER BY clause

The following query works fine:
SELECT a, b, c,
(SELECT COUNT(*) AS COUNT FROM table_b WHERE field_a = p.a) AS d
FROM table_a AS p
ORDER BY b DESC
And this also works:
SELECT a, b, c,
(SELECT COUNT(*) AS COUNT FROM table_b WHERE field_a = p.a) AS d
FROM table_a AS p
ORDER BY d DESC
But the following produces a ERROR; column 'd' does not exist error:
SELECT a, b, c,
(SELECT COUNT(*) AS COUNT FROM table_b WHERE field_a = p.a) AS d
FROM table_a AS p
ORDER BY (b * d) DESC
Only difference between the three queries above is the ORDER BY clause. In the first two queries, results are ordered by either the b field or by the dynamic d field. In the last query, results are (should be) ordered by the product of b times d.
How comes, in the last query, PostgreSQL says that d does not exist while it can find it without issue in the second query?
Arbitrary expressions in the order by clause can only be formed from input columns:
Each expression can be the name or ordinal number of an output column (SELECT list item), or it can be an arbitrary expression formed from input-column values.
You will need to subquery it:
select *
from (select 1 as a, 2 as b) s
order by a * b

Full Join on multiple tables (postgresql)

In postgresql I got 4 tables
Table A:
-----------
a_id
a_date
Table B
-----------
a_id b_id
Table C:
-------------------
c_id
b_id
invoice_number
Table D
-------------------
d_id
invoice_number
value_D
Multiple records have value_D
I would like to select Table A, Table B, Table C and Table D, where a_date BETWEEN X AND Y.
However, I would also like to select all the other value_D that are not included in my selection (so A innerjoin B innerjoin C full outerjoin D)
my code
SELECT
Table A, Table B, Table C, Table D
FROM
Table A
JOIN
Table B ON A.a_id = B.a_id
JOIN
Table C ON B.b_id = C.b_id
FULL OUTER JOIN
Table D ON C.invoice_number = D.invoice_number
WHERE
A.a_date BETWEEN X AND Y;
It only shows D.value_d for the A.a_id, where A.a_date BETWEEN X and Y.
I would like however that D.value_d would also be shown for A.a_id, where A.a_date is also other.
I am kinda a newbie, so hopefully it is understandable and you could help me.
Thanks in advance
You can also add more conditions to the Where clause, for example:
"a_date BETWEEN X AND Y OR a_date > '2015-04-21'". This will retrieve the union of both conditions.
Regards
I think I solved it.
SELECT Table A, Table B, Table C, Table D
FROM Table A
JOIN Table B ON A.a_id = B.a_id
JOIN Table C ON B.b_id = C.b_id
JOIN Table D ON C.invoice_number = D.invoice_number
WHERE A.a_date BETWEEN X AND Y OR
D.value_D IN (SELECT D.value_D
FROM Table D
JOIN Table C ON D.invoice_number on C.invoice_number
JOIN Table B ON C.b_id = B.b_id
JOIN Table A ON B.a_id = A.a_id
WHERE A.a_date BETWEEN X AND Y);
Thank you all for the help guys!

Browse two tables using a cursor

In my procedure I have two tables with the same data. I go through my first table through a cursor. Which compares with the second table that I find much the same data. What if, for example in my table_1 I have ten in my data and I have 12 data table2 how to detect missing data in my two table_1 which is traversed by the cursor?
Thx.
Sounds very much like you'd be better off using the MINUS operator.
SELECT a, b, c
FROM table1
MINUS
SELECT a, b, c
FROM table2
This will show you all results that exist in table1 which are not present in table2. In order to show discrepancies both ways, you could do something like this:
SELECT z.*, 'In table1, not in table2' problem_description
FROM (
SELECT a, b, c
FROM table1
MINUS
SELECT a, b, c
FROM table2
) z
UNION ALL
SELECT z.*, 'In table2, not in table1' problem_description
FROM (
SELECT a, b, c
FROM table2
MINUS
SELECT a, b, c
FROM table1
) z
SQL Fiddle for this answer

How to select multiple columns values same rows from single table

I have a SQL Server table. Now this table has columns like primary key Id, A, B, C, D, E, F, G
Now I want to select rows from this table like this
A=A, B=B, C=C, D=D and G > 132
So I am trying to select rows from this table which rows A,B,C,D columns has same data and G column data > 132.
So how can I do that ? Thank you.
I tried this query but returning same Id rows
SELECT TableA.Id,TableA.UserId,TableA.MaximumHp,TableA.Attack,TableA.Defense,TableA.SpAttack,TableA.SpDefense,TableA.Speed
FROM myTable as TableA
Inner Join myTable as TableB on
TableA.MaximumHp = TableB.MaximumHp
AND TableA.Attack = TableB.Attack
AND TableA.Defense = TableB.Defense
AND TableA.SpAttack = TableB.SpAttack
AND TableA.SpDefense = TableB.SpDefense
AND TableA.Speed = TableB.Speed
AND TableA.Id != TableB.Id
SQL Server 2008 R2
Sounds like you want to join the table to itself
SELECT *
FROM Table t1
Inner Join Table t2 on t1.A = t2.A
AND t1.B = t2.B
AND t1.C = t2.C
AND t1.D = t2.D
AND t1.G > 132
AND t1.ID <> t2.ID
I THINK what you mean is duplicates. Tell me if this is what you are looking for.
SELECT [Table].A, [Table].B, [Table].C, [Table].D, [Table].E, [Table].F, [Table].G
FROM [Table] LEFT JOIN (SELECT A, B, C, D FROM [Table]
GROUP BY A, B, C, D
HAVING count(*) > 1)
AS sub ON ([Table].A=sub.A) AND ([Table].B=sub.B) AND ([Table].C=sub.C) AND ([Table].D=sub.D)
WHERE G>132 and sub.A is not null;
This will give you all the rows where a,b,c, and D are equal to another row in the table...and G > 132