SQL INNER JOIN with MULTIPLE CONDITION in CodeIgniter - mysql

I have the following table.
table cards
------------------------------------
| card_no | approval_code |
------------------------------------
| 999999xxxxxx1234 | 111111 |
----------------------------------
| 888888xxxxxx5678 | 222222 |
------------------------------------
| 777777xxxxxx9012 | 333333 |
-----------------------------------
| 666666xxxxxx3456 | 444444 |
-----------------------------------
table transactions
---------------------------------------------
| trans_id | pan | approval code | amount |
---------------------------------------------
| A1 | 9012 | 333333 | 9.9|
----------------------------------------------
| A2 | 9012 | 333333 | 10.0|
----------------------------------------------
| B1 | 1233 | 111111 | 11.0|
----------------------------------------------
| B2 | 1234 | 111111 | 12.0|
----------------------------------------------
| C1 | 5678 | 222222 | 13.0|
----------------------------------------------
| C2 | 5678 | 444444 | 13.0|
----------------------------------------------
My output is to display 3 types of output.
1st output is to display matched data and 2nd output is to display unmatched data from cards table and 3rd output is to display unmatched data from transactions table. the following are my codes. transaction table only store pan (last 4 digit from card_no) therefore i need to substr to get the last 4 digit.
for matched data:
$query = $this->db->select (array(
'c.card_no', 'c.approval_code',
't.trans_id','t.pan','t.approval_code','amount'
),false)
-> join('transactions t','t.approval_code = c.approval_code','inner')
-> join('transactions t','t.pan = substr(c.card_no,12)','inner')
-> get('cards c');
for unmatched data from cards table;
$query = $this->db->select (array(
'c.card_no', 'c.approval_code',
't.trans_id','t.pan','t.approval_code','amount'
),false)
-> join('transactions t','t.approval_code != c.approval_code','inner')
-> join('transactions t','t.pan != substr(c.card_no,12)','inner')
-> where ('t.approval_code' IS NULL,NULL,FALSE)
-> where ('t.pan' IS NULL,NULL,FALSE)
-> get('cards c');
for unmatched data from transactions table;
$query = $this->db->select (array(
'c.card_no', 'c.approval_code',
't.trans_id','t.pan','t.approval_code','amount'
),false)
-> join('cards c','t.approval_code = c.approval_code','inner')
-> join('cards c','t.pan != substr(c.card_no,12)','inner')
-> where ('c.approval_code' IS NULL,NULL,FALSE)
-> where ('c.card_no' IS NULL,NULL,FALSE)
-> get('cards c');
Both seems not working.. hmmmm
my expected outputs are:
output matched data
--------------------------------------------------------
| card_no | approval_code | trans_id | amount |
--------------------------------------------------------
| 999999xxxxxx1234 | 111111 | B2 | 12.0 |
-------------------------------------------------------
| 888888xxxxxx5678 | 222222 | C1 | 13.0 |
--------------------------------------------------------
| 777777xxxxxx9012 | 333333 | A1 | 9.9 |
-------------------------------------------------------
| 777777xxxxxx9012 | 333333 | A2 | 10.0 |
-------------------------------------------------------
output unmatched data from table cards
------------------------------------
| card_no | approval_code |
------------------------------------
| 666666xxxxxx3456 | 444444 |
-----------------------------------
output unmatched data from table transactions
---------------------------------------------
| trans_id | pan | approval code | amount |
---------------------------------------------
| B1 | 1233 | 111111 | 11.0|
----------------------------------------------
| C2 | 5678 | 444444 | 13.0|
----------------------------------------------

To get unmatched data from cards table replace join by right join. And for unmatched data from transactions table replace join by left join in respective queries.

Related

mysql sub-query cannot refer top table

I have below table/column arrangement in MySQL database. (FK denotes foreign key)
SCHEDULES [id(INT), next_date(DATE), notification_id(FK)]
NOTIFICATIONS [id(INT), col_1(...), col_2(...), ...]
NOTIFICATION_LINES [id(INT), notification_id(FK), no_of_days(INT)]
Relationships:
Multiple SCHEDULES can have same NOTIFICATION (i.e n:1) whereas One NOTIFICATION can have multiple NOTIFICATION_LINES.
Sample Data set
SCHEDULES
-------------------------------------
| id | next_date | notification_id |
-------------------------------------
| 1 | 07-08-2017 | N01 |
| 2 | 18-08-2017 | N01 |
-------------------------------------
NOTIFICATIONS
-----------------------
| id | col_1 | col_2 |
-----------------------
| N01 | AA | XX |
| N02 | BB | YY |
-----------------------
NOTIFICATION_LINES
--------------------------------------
| id | notification_id | no_of_days |
--------------------------------------
| 1 | N01 | 14 |
| 2 | N01 | 5 |
-------------------------------------
Requirement:
I need to get the MAX(no_of_days) of a particular SCHEDULE.
I used below subquery:
SELECT sch.schedule_id, sch.notification_id, x.max_no_of_days
FROM SCHEDULES sch,
(SELECT nt.notification_id, max(lt.no_of_days) AS max_no_of_days
FROM NOTIFICATION_LINES lt, NOTIFICATIONS nt
WHERE lt.parent_id = nt.id
AND nt.notification_id = sch.notification_id) x
WHERE sch.notification_id = x.notification_id;
and it returns:
#1054 - Unknown column 'sch.notification_rule' in 'where clause'
If I substitute sch.notification_rule with a value, it returns correct result.
--------------------------------------------------------
| id | schedule_id | notification_id | max_no_of_days |
--------------------------------------------------------
| 1 | 1 | N01 | 14 |
--------------------------------------------------------
If I cannot use parent query's alias, if anyone can let me know even a different SQL, I would be thankful to you.

count record from two tables which has no relation

I have two tables tbl_user1 and tbl_user2 both are field name are same but there is no relation between that tables now I want to find total referred count from both table for example...
tbl_user1
-----------------------
UID | referenceBy | firstName | lastName | emailAddress
----------------------------------------------------------------------------
1 | NULL | aa1 | ab1 | aa1#email.com
2 | aa1#email.com | aa2 | ab2 | aa2#email.com
3 | NULL | aa3 | ab3 | aa3#email.com
4 | aa2#email.com | aa4 | ab4 | aa4#email.com
5 | aa2#email.com | aa5 | ab5 | aa5#email.com
6 | bb1#email.com | aa6 | ab6 | aa6#email.com
7 | bb2#email.com | aa7 | ab7 | aa7#email.com
8 | bb3#email.com | aa8 | ab8 | aa8#email.com
9 | bb3#email.com | aa9 | ab9 | aa9#email.com
and second one table is somthing like...
tbl_user2
-----------------------
UID | referenceBy | firstName | lastName | emailAddress
----------------------------------------------------------------------------
1 | NULL | bb1 | bc1 | bb1#email.com
2 | bb1#email.com | bb2 | bc2 | bb2#email.com
3 | NULL | bb3 | bc3 | bb3#email.com
4 | bb3#email.com | bb4 | bc4 | bb4#email.com
5 | bb2#email.com | bb5 | bc5 | bb5#email.com
6 | bb1#email.com | bb6 | bc6 | bb6#email.com
7 | aa2#email.com | bb7 | bc7 | bb7#email.com
8 | aa3#email.com | bb8 | bc8 | bb8#email.com
9 | bb5#email.com | bb9 | bc9 | bb9#email.com
now, as you can see there is no relation between these two tables and I want result like following..
MAIN_RESULT_THAT_I_WANT
-----------------------
referenceEmail | referenceEmailCount
----------------------------------------------------------------------------
aa1#email.com | 1
aa2#email.com | 3
aa3#email.com | 1
aa4#email.com | 0
aa5#email.com | 0
aa6#email.com | 0
aa7#email.com | 0
aa8#email.com | 0
aa9#email.com | 0
bb1#email.com | 3
bb2#email.com | 2
bb3#email.com | 3
bb4#email.com | 0
bb5#email.com | 1
bb6#email.com | 0
bb7#email.com | 0
bb8#email.com | 0
bb9#email.com | 0
here in result all emailAddress of all user and total of how many user(s) registered by that particular emailAddress.
I am guessing that the result you want is just copy and pasted since it seems inaccurate. Like HoneyBadger says it is strange that aa6 is missing and still in the result, that indicates you have another list you are not telling us about? Or you just write the result in notepad...
If you just want a list of emails and count this will work:
select referenceBy, count(1) as referenceEmailCount from (
select referenceBy from tbl_user1
union all
select referenceBy from tbl_user2
) as t
group by referenceBy
Otherwise give us more info if this is not what you need.
Since the schema is same for 2 tables so you can perform union to get combined results and can perform an outer query to get the total count.
select referenceEmail, count(*) as referenceEmailCount from (
select * from table1
union all
select * from table2
) as alias
group by alias.referenceEmail

Merging two columns in MYSQL

I'am working on attendance project. In that i am storing students who are absent on the particular date in the table 'attendance' with fields -> sno,rollno,subject_code,date. And if all the students are present then i will store subject_code, date and rollno as NULL which means'all students are present'
------|--------|------------|-----------|
sno |rollno |subject_code| date |
1 | 1234 | a110 | 12-12-2012|
2 | 1235 | a110 | 12-12-2012|
3 | 1235 | a111 | 14-12-2012|
iam taking the students details from table 'students' with fields -> rollno,name
|--------|-------|
| rollno | name |
| 1234 | xyz |
| 1235 | abc |
| 1236 | mno |
| 1237 | qrs |
Now I want to list the students attendance such that output should be like this for particular date assume list for the date "12-12-2012"
list of "12-12-2012" for subject a110 list of "14-12-2012" for subject a111
|-------|------|---------| |-------|------|---------|
|rollno | name | status | |rollno | name | status |
| 1234 | xyz | Absent | | 1234 | xyz | Present |
| 1235 | abc | Absent | | 1235 | abc | Absent |
| 1236 | mno | Present | | 1236 | mno | Present |
| 1237 | qrs | Present | | 1237 | qrs | Present |
Please Help me..
Use LEFT JOIN to find out which student doesnt have a row in the attendance table. (those where present)
SELECT s.rollno,
s.name,
CASE WHEN a.rollno IS NULL THEN 'Present'
ELSE 'Absent'
END as status
FROM student s
LEFT JOIN attendance a
ON s.rollno = a.rollno

MySQL - Use Header Name as Part of Query Filter

I'm relatively new to MySQL and have come across a problem to which I cannot seem to find a solution. I have searched but could not find an answer. I'm open to the possibility that I'm not asking the question correctly. Here goes:
I'm trying to use the name of a given column and the values within that column from one table to pull values from another table. The first table contains 3 columns with the response codified. The second table contains the definitions for each code for each item. The same number code is associated with different meanings depending on the item. For example:
table1 (this table cannot change):
--------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------
| 1 | j | doe | 1 | 3 | 2 |
| 2 | k | smith | 3 | 1 | 2 |
| 3 | l | williams | 2 | 2 | 1 |
--------------------------------------------------------------
table2 (this table can be modified, split, or whatever needs to be done):
-------------------------------------------
|item_id | item_name | score | definition |
-------------------------------------------
| 1 | item_A | 1 | agree |
| 2 | item_A | 2 | neutral |
| 3 | item_A | 3 | disagree |
| 4 | item_B | 1 | likely |
| 5 | item_B | 2 | not likely |
| 6 | item_B | 3 | no reply |
| 7 | item_C | 1 | yes |
| 8 | item_C | 2 | no |
-------------------------------------------
My goal is for the query to output the following:
--------------------------------------------------------------------
|result_id | f_initial | l_name | item_A | item_B | item_C |
--------------------------------------------------------------------
| 1 | j | doe | agree | no reply | no |
| 2 | k | smith | disagree | likely | no |
| 3 | l | williams | neutral | not likely | yes |
--------------------------------------------------------------------
Any assistance or guidance is greatly appreciated. Thank you in advance.
You must join the two tables on the item_A/B/C and score columns
select t1.result_id, t1.f_initial, t1.l_name,
t2a.definition as item_a,
t2b.definition as item_b,
t2c.definition as item_c
from table1 t1
join table2 t2a on t2a.score = t1.item_a
join table2 t2b on t2b.score = t1.item_b
join table2 t2c on t2c.score = t1.item_c
where t2a.item_name = 'item_A'
and t2b.item_name = 'item_B'
and t2c.item_name = 'item_C'

Fixing Joined Many-to-Many MySQL Query

I have two tables that look like this:
Table A:
+-----+-----+------+-------+
| aID | uID | attr | value |
+-----+-----+------+-------+
| 1 | 1 | fn | john |
+-----+-----+------+-------+
| 2 | 1 | ln | smith |
+-----+-----+------+-------+
| 3 | 2 | fn | jim |
+-----+-----+------+-------+
| 4 | 2 | ln | bean |
+-----+-----+------+-------+
Table B:
+-----+-----+-------+-------+
| bID | uID | perm | value |
+-----+-----+-------+-------+
| 1 | 1 | admin | 1 |
+-----+-----+-------+-------+
| 2 | 2 | news | 1 |
+-----+-----+-------+-------+
| 3 | 2 | cms | 1 |
+-----+-----+-------+-------+
As it shows, Table A holds attribute data for a user uID, and Table B holds permission data for a user uID.
At the moment, I am using,:
SELECT GROUP_CONCAT(`a`.`attr`) AS `attrs`
, GROUP_CONCAT(`a`.`value`) AS `values`
, GROUP_CONCAT(`b`.`perm`) AS `perms`
FROM `a`
JOIN `b`
ON `a`.`uID` = `b`.`uID`
GROUP BY `a`.`uID`, `b`.`uID`
But it is giving me a result:
+-------------+-------------------+-------------------+
| attrs | values | perms |
+-------------+-------------------+-------------------+
| fn,ln | John,Smith | admin,admin |
+-------------+-------------------+-------------------+
| fn,fn,ln,ln | Jim,Jim,Bean,Bean | news,cms,news,cms |
+-------------+-------------------+-------------------+
What do I need to change in my query to get:
+-------+------------+----------+
| attrs | values | perms |
+-------+------------+----------+
| fn,ln | John,Smith | admin |
+-------+------------+----------+
| fn,fn | Jim,Bean | news,cms |
+-------+------------+----------+
GROUP_CONCAT takes additional arguments, as explained on its documentation page here.
The one you want is distinct:
SELECT GROUP_CONCAT(distinct `a`.`attr`) AS `attrs` . . .