I have two tables: TableA and TableB.
I need to compare two particular column(AnsId & Content) from two tables and get their difference.
In case there is no difference is found then I should return 'process success', else return 'Failure'
TableA
+--------+-----------+---------+-------------+
| Id | RSCId | AnsId | Content |
+--------+-----------+---------+-------------+
| 1 | 12 | 1 | Test data. |
| 2 | 12 | 0 | Sample Test.|
| 3 | 12 | 5 | Test data. |
| 4 | 12 | 7 | Test Data. |
| 5 | 12 | 46 | Test datas. |
+--------+-----------+---------+-------------+
TableB
+--------+-----------+---------+-------------+
| Id | RSCId | AnsId | Content |
+--------+-----------+---------+-------------+
| 1 | 35 | 2 | Test . |
| 2 | 35 | 0 | Sample Test.|
| 3 | 35 | 5 | Test data. |
| 4 | 35 | 7 | Test Data. |
| 5 | 35 | 46 | Test datas. |
+--------+-----------+---------+-------------+
Please help me out.
select case when sum(case when a.ansid is null or b.ansid is null
then 1
end) > 0
then 'mismatch'
else 'ok'
end as result
from tableA a
full outer join tableB b on a.ansid = b.ansid and a.content = b.content
Related
I have two tables.
One have userid and email (users table). The other have payments information (payments table) from the userid in users.
users
+--------+------------+
| Userid | Name |
+--------+------------+
| 1 | Alex T |
| 2 | Jeremy T |
| 3 | Frederic A |
+--------+------------+
payments
+--------+-----------+------------+----------+
| Userid | ValuePaid | PaidMonths | Refunded |
+--------+-----------+------------+----------+
| 1 | 1 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 12 | null |
| 1 | 20 | 1 | null |
| 2 | 1 | 1 | null |
| 2 | 20 | 12 | 1 |
| 2 | 20 | 12 | null |
| 2 | 20 | 1 | null |
| 3 | 1 | 12 | null |
| 3 | 20 | 1 | 1 |
| 3 | 20 | 1 | null |
+--------+-----------+------------+----------+
I want to count the PaidMonths taking in consideration the following rules:
If ValuePaid < 10 PaidMonths should be = 0.23 (even if in the column the value seen is any other mumber).
If Refund=1 the PaidMonths should be = 0.
Based on this when i join both tables by userid, and sum the PaidMonths based in the previousrules, i expect to see as result:
+--------+------------+------------+
| userid | Name | paidMonths |
+--------+------------+------------+
| 1 | Alex T | 25.23 |
| 2 | Jeremy T | 13.23 |
| 3 | Frederic A | 1.23 |
+--------+------------+------------+
Can you help me to achieve this in the most elegant way? Should a temporary table be used?
The following gives your desired results, using apply with case expression to map your values:
select u.UserID, u.Name, Sum(pm) PaidMonths
from users u join payments p on p.userid=u.userid
cross apply (values(
case
when valuepaid <10 then 0.23
when Refunded=1 then 0
else PaidMonths end
))x(pm)
group by u.UserID, u.Name
See Working Fiddle
While going through SQL columns, if we find text match "NEW" in Calc column, update the incrementing a count starting with 1 in Results column.
It should look like this on the output:
The following uses an id column to resolve the order issue. Replace that with your corresponding expression. This also addresses the requirement to start the display sequence with 1 and also show 0 for the 'NEW' rows.
The SQL (updated):
SELECT logs.*
, CASE WHEN text = 'NEW' THEN 0
ELSE
COALESCE(SUM(CASE WHEN text = 'NEW' THEN 1 END) OVER (PARTITION BY xrank ORDER BY id)+1, 1)
END AS display
FROM logs
ORDER BY id
The result:
+----+-------+------+---------+
| id | xrank | text | display |
+----+-------+------+---------+
| 1 | 1 | A | 1 |
| 2 | 1 | B | 1 |
| 3 | 1 | C | 1 |
| 4 | 1 | NEW | 0 |
| 5 | 1 | D | 2 |
| 6 | 1 | Q | 2 |
| 7 | 1 | B | 2 |
| 8 | 1 | NEW | 0 |
| 9 | 1 | D | 3 |
| 10 | 1 | Z | 3 |
| 11 | 2 | A | 1 |
| 12 | 2 | B | 1 |
| 13 | 2 | C | 1 |
| 14 | 2 | NEW | 0 |
| 15 | 2 | D | 2 |
| 16 | 2 | Q | 2 |
| 17 | 2 | B | 2 |
| 18 | 2 | NEW | 0 |
| 19 | 2 | D | 3 |
| 20 | 2 | Z | 3 |
+----+-------+------+---------+
You need a column that specifies the ordering for the table. With that, just use a cumulative sum:
select t.*,
1 + sum(case when Calc = 'NEW' then 1 else 0 end) over (partition by Rank_Id order by Seq) as display
from t;
Can anhone help me out or point me in the right direction? What is simplest way to get from current table to output table??
Current Table
ID | type | amount |
2 | A | 19 |
2 | B | 6 |
3 | A | 5 |
3 | B | 11 |
4 | A | 1 |
4 | B | 23 |
Desires output
ID | type | amount | change |
2 | A | 19 | 13 |
2 | B | 6 | -6 |
3 | A | 5 | -22 |
3 | B | 11 | |
4 | A | 1 | |
4 | B | 23 | |
I don't get how the values are put on rows. You can, for instance, subtract the "B" value from the "A" value for any given id. For instance:
select t.*,
(case when type = 'A'
then amount - max(amount) filter (type = 'B') over (partition by id)
end) as diff_a_b
from t;
I have table like this called, table test:
+------------------------+--------+
| id_laporan_rekomendasi | status |
+------------------------+--------+
| 1 | 2 |
| 1 | 2 |
| 1 | 2 |
| 1 | 3 |
| 2 | 2 |
| 2 | 2 |
| 2 | 2 |
| 2 | 3 |
| 3 | 2 |
| 3 | 3 |
| 4 | 2 |
| 5 | 2 |
| 5 | 3 |
| 6 | 2 |
+------------------------+--------+
I want to group by id_laporan_rekomendasi and make a new column when in column status there is value 3. so if there is no value 3 in column status, then the value would be 0, but if there is value 3 than 1.
I expect the result would be like this
+------------------------+------+
| id_laporan_rekomendasi | test |
+------------------------+------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 0 |
| 5 | 1 |
| 6 | 0 |
+------------------------+------+
I have tried this query
SELECT t1.id_laporan_rekomendasi,
COUNT(distinct case when t1.status = 3 then 1 else 0 end) as test
FROM test t1
GROUP BY t1.id_laporan_rekomendasi
But i got the result like below
+------------------------+------+
| id_laporan_rekomendasi | test |
+------------------------+------+
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
| 4 | 1 |
| 5 | 2 |
| 6 | 1 |
+------------------------+------+
Does anyone could help me with this table ?
You are close. In MariaDB, you can simplify this to:
SELECT t1.id_laporan_rekomendasi,
MAX( t1.status = 3 ) as test
FROM test t1
GROUP BY t1.id_laporan_rekomendasi;
MariaDB (and MySQL) treat boolean expressions as numbers, with "1" for true and "0" for false. So this does what you want.
I trying to get the result table to contain rows where
Condition1: A.pc=B.pc AND
Condition2: (preferred (A.sub = B.Sub) or
else any one row that satisfy only Condition1)
I have tried the following inner join query and few other join and sub-query but can not figure out exact way to write a query with above strange condition.
SELECT * FROM tblA AS A INNER JOIN tblB AS B
ON A.sub=B.sub
WHERE A.pc=B.pc
tblA
-------------------
| id | pc | sub |
-------------------
| 0 | 5 | abc |
| 1 | 8 | def |
| 2 | 6 | ghi |
| 3 | 2 | jkl |
| 4 | 7 | mno |
| 5 | 19 | pqr |
-------------------
tblB
-------------------------
| pc | sub | uml | ull |
-------------------------
| 3 |arm | 1 | 1 |
| 3 |gtk | 1 | 2 |
| 3 |lmn | 1 | 3 |
| 3 |pop | 1 | 4 |
| 5 |abc | 1 | 5 |
| 5 |hlq | 1 | 6 |
| 5 |pon | 2 | 1 |
| 5 |qrt | 2 | 2 |
| 7 |alo | 2 | 3 |
| 7 |mno | 2 | 4 |
| 7 |ghm | 2 | 5 |
| 7 |stm | 2 | 6 |
| 9 |mck | 2 | 7 |
| 9 |plo | 3 | 1 |
| 9 |rtk | 3 | 2 |
| 9 |ert | 3 | 3 |
| 6 |gji | 3 | 4 |
| 6 |ghi | 3 | 5 |
| 6 |yux | 4 | 1 |
| 6 |del | 4 | 2 |
| 2 |jkl | 4 | 3 |
| 2 |jll | 5 | 4 |
| 2 |uin | 6 | 1 |
| 2 |tro | 6 | 2 |
| 19 |ppm | 6 | 3 |
| 19 |kde | 6 | 4 |
| 19 |grp | 6 | 5 |
| 19 |sho | 6 | 6 |
-------------------------
Expected Result Table:
-------------------------------
| id | pc | sub | uml | ull |
-------------------------------
| 0 | 5 |abc | 1 | 5 |
| 2 | 6 |ghi | 3 | 5 |
| 3 | 2 |jkl | 4 | 3 |
| 4 | 7 |mno | 2 | 4 |
| 5 | 19 |ppm | 6 | 3 | *
-------------------------------
* notice this is a arbitrary row as (A.sub=B.sub) not found
** notice there is no result for id=1 as pc=8 do not exist in tblB
Until someone comes up with a better answer, here is some code that does what you want.
Please, note it might not be a good solution in terms of performance (espcially as your tables grow).
SELECT *
FROM (
SELECT tblA.id, tblB.*
FROM tblA INNER JOIN tblB
ON tblA.pc = tblB.pc AND
tblA.id NOT IN (SELECT tblA.id
FROM tblA INNER JOIN tblB
ON tblA.sub = tblB.sub)
GROUP BY tblA.id
UNION
SELECT tblA.id, tblB.*
FROM tblA INNER JOIN tblB
ON tblA.sub = tblB.sub
GROUP BY tblA.id
) AS tu
ORDER BY id ASC;
See, also, this short demo.
One way of doing it I came up with is to repeat a join condition in where clause:
SELECT *
FROM tblA AS A
INNER JOIN tblB AS B
ON A.pc = B.pc
WHERE A.sub = B.sub
OR A.pc = B.pc