Whats wrong with this query? i am getting null result - mysql

SELECT `acart`.`order_number` AS `admin_order_number`,
`acart`.`user_id` AS `admin_user_id`,
`acart`.`created_by` AS `admin_created_by`,
`rcart`.`order_number` AS `renew_order_number`,
`rcart`.`user_id` AS `renew_user_id`,
`rcart`.`created_by` AS `renew_created_by`,
`scart`.`order_number` AS `shopping_order_number`,
`scart`.`user_id` AS `shopping_user_id`,
`scart`.`created_by` AS `shopping_created_by`
FROM `cdp_order_transaction_master` AS `master`
LEFT JOIN `cdp_admin_shopping_cart` AS `acart`
ON `acart`.`order_number`=`master`.`order_number`
LEFT JOIN `cdp_renew_cart` AS `rcart`
ON `rcart`.`order_number`=`master`.`order_number`
LEFT JOIN `cdp_shopping_cart` AS `scart`
ON `scart`.`order_number`=`master`.`order_number`
WHERE master.order_number IS NULL
Let me explain my problem,if the order is successfull then it will goes to cdp_order_transaction_master table and any other 3 table (cdp_admin_shopping_cart,cdp_renew_cart,cdp_shopping_cart) depending on the situation but if the order fails then it will not go to cdp_order_transaction_master table and remain in other tables,
so i want the failed order which is not present in cdp_order_transaction_master and can present in any other tables(cdp_admin_shopping_cart,cdp_renew_cart,cdp_shopping_c‌​art)

WHERE master.order_number IS NULL
This is your primary table, and the join condition for all other tables are on this column.
You are trying to join null to null
Based on your comment, try:
select 'cdp_admin_shopping_cart' as `err_table`, a1.order_number
from cdp_admin_shopping_cart a1
where not exists (select 1 from cdp_order_transaction_master a2 where a2.order_number = a1.order_number)
union all
select 'cdp_renew_cart' as `err_table`, a1.order_number
from cdp_renew_cart a1
where not exists (select 1 from cdp_order_transaction_master a2 where a2.order_number = a1.order_number)
union all
select 'cdp_shopping_c‌​art' as `err_table`, a1.order_number
from cdp_shopping_c‌​art a1
where not exists (select 1 from cdp_order_transaction_master a2 where a2.order_number = a1.order_number)

Related

repeated rows in json_agg() in query with 2 lateral joins

I have a strange result when performing a lateral join on a query
I have the following table structure
task->id
comment -> id , taskId, comment
tasklink -> taskId, type, userid
with a single task record (id 10), 1 comment record ("row1", "a test comment") and 5 tasklink records (all with taskid 10)
I expected this query
select task.id,
json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments,
json_agg(json_build_object('type',b.type, 'user',b.userid)) as users
FROM task
left join lateral (select c.* from comment c where task.id = c.taskid) c on true
left join lateral (select b.* from taskuserlink b where task.id = b.taskid) b on true
where task.id = 10
GROUP BY task.id ;
to return
id | comments | users
---------------------------------------------------------------------
10 "[{"id":"row1","user":"a test comment"}]" "[{"type":"updatedBy","user":1},"type":"closedBy","user":5},"type":"updatedBy","user":5},"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"
instead, I got this
id | comments | users
10 "[{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"},{"id":"row1","user":"a test comment"}]" "[{"type":"updatedBy","user":1},{"type":"closedBy","user":5},{"type":"updatedBy","user":5},{"type":"createdBy","user":5},{"type":"ownedBy","user":5}]"
ie , for every link row, the comment row is duplicated
I am thinking that I am missing something really obvious, but as I have only just started using Postgres (and sql ) I'm a little stumped
I would appreciate some guidance on where I'm going wrong
Move the aggregates into subqueries:
select id, comments, users
from task t
left join lateral (
select json_agg(json_build_object('id',c.id, 'user',c.comment)) as comments
from comment c
where t.id = c.taskid
) c on true
left join lateral (
select json_agg(json_build_object('type',b.type, 'user',b.userid)) as users
from taskuserlink b
where t.id = b.taskid
) b on true
DbFiddle.

How to get the union of 2 fields values from 2 tables in one field?

Am looking for the help of some sql query experts.
Having some hard time for me to fix the issue in below sql statement. This is a join sql statement of 3 tables. and i need similar kind of data from people and alumni table. And the field name also same in both table. So my question is- is there any for me to get the similar data in a single field?
SELECT DISTINCT P.people_id, P.Name,P.Journal_name, N.People_id, N.Name, N.Journal_name
FROM `Paper_Author` AS A
LEFT JOIN `People` AS P ON ( A.Author_id = P.people_id )
LEFT JOIN `Alumni` AS N ON ( A.Author_id = N.People_id )
WHERE A.Paper_id =2067
ORDER BY A.Author_sortorder
LIMIT 0 , 30
Eg of Current Result is:
Id-- Name-- Journal_name-- ID2-- Name-- Journal_name
1 Name1 A1 NULL NULL NULL
2 Name2 B1 5 Name10 NULL
3 Name3 C1 3 Name3 C1
Expected Result :
Id-- Name-- Journal_name--
1 Name1 A1
2 Name2 B1
3 Name3 C1
5 Name10 NULL
I want to know whether i can get similar values in single filed? eg:both Journal_name in single field?
A UNION should work for this task. With a UNION statement you'll get both results in a single result set:
SELECT DISTINCT P.people_id, P.Name, P.Journal_name, AP.Author_sortorder
FROM `Paper_Author` AS AP
LEFT JOIN `People` AS P ON ( A.Author_id = P.people_id )
WHERE AP.Paper_id = 2067
UNION
SELECT DISTINCT N.People_id, N.Name, N.Journal_name, AN.Author_sortorder
FROM `Paper_Author` AS AN
LEFT JOIN `Alumni` AS N ON ( A.Author_id = N.People_id )
WHERE AN.Paper_id = 2067
ORDER BY Author_sortorder

SQL , get difference b/w to id's

I want to get result from two tables:
Table A
create table A
( propertyId int not null
,PRIMARY KEY (propertyId))
Table B
create table B
( Id int not null
, propertyId int
, FOREIGN KEY (propertyId ) REFERENCES A(propertyId))
Now I want to get the result total count id of Table A exist in Table B AND total count id that does not exist in Table B
SELECT COUNT(property.propertyId) AS 'Occupied'
,(
SELECT COUNT(property.propertyId)
FROM property
INNER JOIN agreement ON property.`propertyId` <> agreement.`propertyId`
) AS 'Vacant'
FROM property
INNER JOIN agreement ON property.`propertyId` = agreement.`propertyId`
WHERE agreement.`isActive` = '1'
You can do a Left join to get the proper result.
select
sum (
case when a.propertyId is not null then 1
else 0
end
) as present_cnt,
sum (
case when a.propertyId is null then 1
else 0
end
) as not_present_cnt
from property p
left join agreement a on p.propertyId = a.propertyId
where a.isActive = '1';
left join will fetch data for a.propertyId from agreement corresponding to p.propertyId, if no match found then null
Your solution should be based on this principle, also exemplified in this SQLFiddle:
SELECT count(CASE
WHEN propertyID IS NOT NULL
AND fk_propertyID IS NOT NULL
THEN 1
ELSE NULL
END) 'exist_in_both_tables'
,count(CASE
WHEN propertyID IS NOT NULL
AND fk_propertyID IS NULL
THEN 1
ELSE NULL
END) 'does_not_exist_in_b'
FROM (
SELECT *
FROM tablea a
LEFT JOIN tableb b ON a.propertyID = b.fk_propertyID
UNION
SELECT *
FROM tablea a
RIGHT JOIN tableb b ON a.propertyID = b.fk_propertyID
) result
You need to duplicate your query and use both LEFT and RIGHT joins and UNION the results of those two separate queries to simulate the result of a FULL JOIN.
After simulating this, you need to go over this result set again, by making this a sub-query and then using aggregate functions, COUNT(), along with CASE statements to count how many matches you have in both tables.
Hence, your final queries should look something like this:
SELECT count(CASE
WHEN Property_PropertyID IS NOT NULL
AND Agreement_PropertyID IS NOT NULL
THEN 1
ELSE NULL
END) 'Occupied'
,count(CASE
WHEN Property_PropertyID IS NOT NULL
AND Agreement_PropertyID IS NULL
THEN 1
ELSE NULL
END) 'Vacant'
FROM (
SELECT property.propertyID 'Property_PropertyID'
FROM property
LEFT JOIN agreement ON property.`propertyId` = agreement.`propertyId`
WHERE agreement.`isActive` = '1'
UNION
SELECT agreement.propertyID 'Agreement_PropertyID'
FROM property
RIGHT JOIN agreement ON property.`propertyId` = agreement.`propertyId`
WHERE agreement.`isActive` = '1'
) ResultSet

Mapping table MySQL / Access

I have a short access/mySQL question. I have a mapping table on the format below.
ID Category_A Category_B Category_C Team
1 a b T1
2 a d T2
I have a second table which also includes Category_A, Category_B, and Category_C. I would like to join the Team value to the my second table based on the mappingtable. My problem is that when there is a blank (e.g. ID=2, Category_B) the mapping should assign the T2 to any row that contains Category_A=a and Category_C=d regardless of the value in Category_B.
Can this type of mapping be done?
Grateful for your help!
In MS Access, I think you would need something on the lines of:
SELECT t.ID, m.Team
FROM Team t
INNER JOIN Mapping m
ON (m.Category_C = t.Category_C)
AND (m.Category_B = t.Category_B)
AND (m.Category_A = t.Category_A)
WHERE m.Category_C Is Not Null
AND m.Category_B Is Not Null
AND m.Category_A Is Not Null
UNION ALL
SELECT t.ID, m.Team
FROM Team t
INNER JOIN Mapping m
ON (m.Category_B = t.Category_B)
AND (m.Category_A = t.Category_A)
WHERE m.Category_C Is Null
AND m.Category_B Is Not Null
AND m.Category_A Is Not Null
UNION ALL
SELECT t.ID, m.Team
FROM Team t
INNER JOIN Mapping m
ON (m.Category_C = t.Category_C)
AND (m.Category_A = t.Category_A)
WHERE m.Category_C Is Not Null
AND m.Category_B Is Null
AND m.Category_A Is Not Null
UNION ALL
SELECT t.ID, m.Team
FROM Team t
INNER JOIN Mapping m
ON (m.Category_C = t.Category_C)
AND (m.Category_B = t.Category_B)
WHERE m.Category_C Is Not Null
AND m.Category_B Is Not Null
AND m.Category_A Is Null

How to left join or inner join a table itself

I have this data in a table, for instance,
id name parent parent_id
1 add self 100
2 manage null 100
3 add 10 200
4 manage null 200
5 add 20 300
6 manage null 300
How can I left join or inner join this table itself so I get this result below?
id name parent
2 manage self
4 manage 10
6 manage 20
As you can I that I just want to query the row with the keyword of 'manage' but I want the column parent's data in add's row as the as in manage's row in the result.
Is it possible?
EDIT:
the simplified version of my actual table - system,
system_id parent_id type function_name name main_parent make_accessible sort
31 30 left main Main NULL 0 1
32 31 left page_main_add Add self 0 1
33 31 left page_main_manage Manage NULL 0 2
my actual query and it is quite messy already...
SELECT
a.system_id,
a.main_parent,
b.name,
b.make_accessible,
b.sort
FROM system AS a
INNER JOIN -- self --
(
SELECT system_id, name, make_accessible, sort
FROM system AS s2
LEFT JOIN -- search --
(
SELECT system_id AS parent_id
FROM system AS s1
WHERE s1.function_name = 'page'
) AS s1
ON s1.parent_id = s2.parent_id
WHERE s2.parent_id = s1.parent_id
AND s2.system_id != s1.parent_id
ORDER BY s2.sort ASC
) b
ON b.system_id = a.parent_id
WHERE a.function_name LIKE '%manage%'
ORDER BY b.sort ASC
result I get currently,
system_id main_parent name make_accessible sort
33 NULL Main 0 1
but I am after this,
system_id main_parent name make_accessible sort
33 self Main 0 1
You just need to reference the table twice:
select t1.id, t1.name, t2.id, t2.name
from TableA t1
inner join TableA t2
on t1.parent_id = t2.Id
Replace inner with left join if you want to see roots in the list.
UPDATE:
I misread your question. It seems to me that you always have two rows, manage one and add one. To get to "Add" from manage:
select system.*, (select parent
from system s2
where s2.parent_id = system.parent_id
and s2.name = 'add')
AS parent
from system
where name = 'manage'
Or, you might split the table into two derived tables and join them by parent_id:
select *
from system
inner join
(
select * from system where name = 'add'
) s2
on system.parent_id = s2.parent_id
where system.name = 'manage'
This will allow you to use all the columns from s2.
Your data does not abide to a child-parent hierarchical structure. For example, your column parent holds the value 10, which is not the value of any id, so a child-parent association is not possible.
In other words, there's nothing that relates the record 2,manage,null to the record 1,add,self, or the record 4,manage,null to 3,add,10, as you intend to do in your query.
To represent hierarchical data, you usually need a table that has a foreign key referencing it's own primary key. So your column parent must reference the column id, then you can express a child-parent relationship between manage and add. Currently, that's not possible.
UPDATED: Joining by parent_id, try:
select m.id, m.name, a.parent
from myTable m
join myTable a on m.parent_id = a.parent_id and a.name = 'add'
where m.name = 'manage'
Change the inner join to a left join if there may not be a corresponding add row.