I have 2 tables, custom_leads_fields and custom_leads_fields_option. The primary key of custom_leads_fields is saved in custom_leads_fields_option table as c_id.
I need to fetch all the records from custom_leads_fields table where status = 1 and then I also needs matching records from custom_leads_fields_option where status = 1
custom_leads_fields table
c_id | user_id | label | status |
1 | 591 | A | 1 |
2 | 591 | B | 1 |
3 | 591 | C | 0 |
custom_leads_fields_option table
id | c_id | option | status
1 | 2 | yes | 1
2 | 2 | no | 1
3 | 2 | may | 0
4 | 3 | yy | 1
5 | 3 | zz | 1
Output required:
c_id | label | option
1 | A |
2 | B | yes
2 | B | no
It should return records from first table if status = 1 even if records are not available in second table, but if records are available in second table then only those records should be fetched whose status = 1.
I have written a query but it does not return label 'A' because matching records are not available in other table.
SELECT
`custom_leads_fields`.`c_id` AS `field_id`,
`custom_leads_fields_option`.`id` AS `option_id`,
`custom_leads_fields`.`label`,
`custom_leads_fields_option`.`option`
FROM
`custom_leads_fields`
LEFT JOIN
`custom_leads_fields_option`
ON custom_leads_fields.id = custom_leads_fields_option.custom_leads_field_id
WHERE
(`custom_leads_fields`.`user_id`=591)
AND (`custom_leads_fields`.`status`=1)
AND (`custom_leads_fields_option`.`status`= 1)
I think is left join and the label A doesn't have any relationship with custom_leads_fields_option table. So you can't use custom_leads_fields_option.status = 1. You can try this
select clf.*, clfo.*
from custom_leads_fields clf
left join custom_leads_fields_option clfo
on clf.id = clfo.c_id
where clf.status = 1
and (clfo.status = 1 or clfo.status is null);
sqlfiddle
you need to move status condition to join condition , this will give your desired output. All the records from left table and matched record (with status =1 condition) from right table
SELECT
`custom_leads_fields`.`c_id` AS `field_id`,
`custom_leads_fields_option`.`id` AS `option_id`,
`custom_leads_fields`.`label`,
`custom_leads_fields_option`.`option`
FROM
`custom_leads_fields`
LEFT JOIN
`custom_leads_fields_option`
ON custom_leads_fields.id = custom_leads_fields_option.custom_leads_field_id
AND (`custom_leads_fields_option`.`status`= 1) // changed line
// ^^^^^^^^^^^^^^^^^^
WHERE
(`custom_leads_fields`.`user_id`=591)
AND (`custom_leads_fields`.`status`=1)
Related
I have two tables and need to get all rows from the first one and then check which values from the second table match the first table.
My goal is to get all so called 'achievements' and then check which one the user has reached.
achievements
+---------------+-------------+
| achievementID | description |
+---------------+-------------+
| 1 | goal1 |
| 2 | goal2 |
| 3 | goal3 |
+---------------+-------------+
achievement_user
+---------------------+---------------+--------+
| achievementRecordID | achievementID | userID |
+---------------------+---------------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 3 |
| 3 | 4 | 2 |
| 4 | 3 | 1 |
+---------------------+---------------+--------+
My desired result for a query where I check the results for userID = 1 would be something like
+---------------+---------------+--------------+
| achievementID | description | solvedByUser |
+---------------+---------------+--------------+
| 1 | goal1 | true |
| 2 | goal2 | false |
| 3 | goal3 | true |
+---------------+---------------+--------------+
The new column solvedByUser could be basically any datatype (boolean, int, ...).
I just need a list of all available achievements and then see which one the user has reached.
You can left join the achievments table with achievement_user:
select a.*, (au.userID is not null) solvedByUser
from achievements a
left join achievement_user au
on au.achievementID = a.achievementID
and au.userID = 1
solvedByUser is a 0/1 flag that indicates whether the given achievement was reached by the given user.
I think you need a left join -
SELECT A.achievementID, A.description, CASE WHEN AU.userID IS NOT NULL THEN 'true' ELSE 'false' solvedByUser
FROM achievements A
LEFT JOIN achievement_user AU ON A.achievementID = AU.achievementID
AND userID = 1; -- YOUR INPUT ID
You need a left join:
select a.*,
case when u.achievementID is null then 'false' else 'true' end solvedByUser
from achievements a left join achievement_user u
on u.achievementID = a.achievementID and u.userid = 1
I have a table with multiple records have the same ID but different values. I want copy records from other table to this table. I want to update if record is null to the minimum position, or insert into the next position if the value does not exist.
Here is my Target table:
ID | Position | Value
1 | 1 | A
2 | 1 | B
2 | 2 | null
2 | 3 | null
2 | 4 | C
3 | 1 | A
4 | 1 | D
4 | 2 | B
Source table:
ID | Value
1 | C
2 | N
3 | B
4 | D
5 | A
6 | null
7 | B
Wanted result table:
ID | Position | Value
1 | 1 | A
1 | 2 | C
2 | 1 | B
2 | 2 | N
2 | 3 | null
2 | 4 | C
3 | 1 | A
3 | 2 | B
4 | 1 | D
4 | 2 | B
5 | 1 | A
7 | 1 | B
My query is:
MERGE Target AS T
USING (SELECT S.ID, MAX(E.POS) AS PosMax, MIN(E.POS) as PosMin, S.Value
FROM Source S
LEFT OUTER JOIN Target E ON S.ID = E.ID
WHERE S.Value IS NOT NULL AND E.Value IS NULL
GROUP BY S.ID, S.Value) AS SC
ON T.ID = SC.ID
WHEN MATCHED AND SC.Value IS NOT NULL AND EG.Value IS NULL AND T.POS = SC.PosMin
THEN
UPDATE SET
EG.Value = SC.Value
WHEN NOT MATCHED AND SC.Value IS NOT NULL
THEN
INSERT (ID, Position, Value)
VALUES (SC.D, ISNULL(SC.PosMax, 0) + 1, SC.Value);
This only updates the null value with the minimum position and insert the value if there is not exist ID. If the ID existed. It will not insert because the Match T.ID = SC.ID.
Example of ID 3, It does not inser value B in position 2.
Does anyone have different approach or strategy? Or I have to write a second query to insert if the ID is the same and value not.
Thanks,
Jay
I think your ON needs the position as well.
ON T.ID = SC.ID and T.pos=SC.minpos.
And the subquery to build SC should be an inner join. You don't want records if you don't have matching values in target.
I have some issues with multiple joins in MysQL
I have 3 tables:
cms_data_company
cms_data_company_categories
cms_datasrc_category
Sample records from: cms_data_company:
+----+-----------+------------+
| id | name | address |
+----+-----------+------------+
| 1 | Name1 | Samplestr1 |
+----+-----------+------------+
| 2 | Name2 | Samplestr2 |
+----+-----------+------------+
| 3 | Name3 | Samplestr3 |
+----+-----------+------------+
Sample records from: cms_data_company_categories ( It contains Company_id field and category_id ) Point is that there is serveral records for one company_id )
+----+-----------+------------+
| id | company_id| category_id|
+----+-----------+------------+
| 1 | 2 | 14 |
+----+-----------+------------+
| 2 | 2 | 11 |
+----+-----------+------------+
| 3 | 1 | 15 |
+----+-----------+------------+
Sample records from: cms_datasrc_category ( Here is a issue that i need only that rows where:
datasrc = 1 AND parent = 0
+----+-----------+------------+-----------+
| id | datasrc | parent |name |
+----+-----------+------------+-----------+
| 1 | 1 | 0 |category1 |
+----+-----------+------------+-----------+
| 2 | 2 | 0 |category2 |
+----+-----------+------------+-----------+
| 3 | 3 | 5 |category3 |
+----+-----------+------------+-----------+
What i would like to recive is that:
All fields from cms_data_company and field name from cms_datasrc_company
I need to join it as follows:
id from cms_data_company match with company_id from cms_data_company_categories
Then matched category_id from
cms_data_company_categories with ID from cms_datasrc_category (only these records where datasrc=0 and parent=0)
Return name as new column with all field from cms_data_company
I think I could make it messy, but my MySQL statement is as follows:
select * ,cms_datasrc_category.name_en
from cms_data_company
LEFT JOIN cms_data_company_categories.company_id
ON cms_data_company.id = cms_data_company_categories.company_id
LEFT JOIN cms_datasrc_category
ON cms_data_company_categories.category_id = cms_datasrc_category.id
WHERE cms_datasrc_category.datasrc = 1 AND cms_datasrc_category.parent = 0
It seems It is working somehow but, there is only records from cms_data_company where query can find something. I would like to change my statemat to show NULLs when There is no matching fields.
It is because WHERE applies to all Query ?
When you use left joins, conditions on all but the first table should be in the on clauses:
SELECT *, cdc.name_en
FROM cms_data_company dc LEFT JOIN
cms_data_company_categories.company_id c
ON dc.id = c.company_id LEFT JOIN
cms_datasrc_category cdc
ON c.category_id = cdc.id AND
cdc.datasrc = 1 AND cdc.parent = 0;
Notes:
Table aliases make a query easier to write and to read.
You should use table aliases for all column references, when your query has more than one table.
The select * already selects all columns from all tables. There is no need to include another column. Or, better yet, list the columns you really need.
The filtering conditions are on the last table, so they are now in the on clause.
I'm struggling to work out how to join a couple of tables to get a certain result in a query.
I've got 2 tables:
A [T_Prog] table that has all possible ID1 & ID2 records with the amount of
PRGCASH for each record against its respective MONTHNUMBER.
A [T_ALS] table that contains a proportion of all possible ID1 & ID2 records with the ALSCASH for each of
those records against its respective MONTHNUMBER.
What I want to do is bring the PRGCASH and ALSCASH fields into a single query, matched appropriately to their respective ID1, ID2 and MONTHNUMBER fields.
The uniqueness of a record in each table is a combination of ID1, ID2 and MONTHNUMBER fields.
The problem I have is that the [T_ALS] table contains more entries on MONTHNUMBER against each unique ID1 and ID2 combination than it does in the [T_Prog] table.
So if I do it this way...
SELECT [T_Prog].ID1, [T_Prog].ID2, [T_Prog].MONTHNUMBER, [T_Prog].PRGCASH, [T_ALS].ALSCASH
FROM [T_Prog]
LEFT JOIN [T_ALS] ON ([T_Prog].ID1 = [T_ALS].ID1) AND ([T_Prog].ID2 = [T_ALS].ID2) AND ([T_Prog].MONTHNUMBER = [T_ALS].MONTHNUMBER)
...I get all possible records, but any additional records from [T_ALS] on MONTHNUMBER will be lost as the [T_Prog] table does not have an equivalent record.
If I do it this way...
SELECT [T_ALS].ID1, [T_ALS].ID2, [T_ALS].MONTHNUMBER, [T_Prog].PRGCASH, [T_ALS].ALSCASH
FROM [T_ALS]
LEFT JOIN [T_Prog] ON ([T_ALS].ID1 = [T_Prog].ID1) AND ([T_ALS].ID2 = [T_Prog].ID2) AND ([T_ALS].MONTHNUMBER = [T_Prog].MONTHNUMBER)
...I won't get all possible records as the [T_ALS] table contains only a proportion of all possible records.
Here's a illustration of the 2 tables with example data and the final query table I'm trying to achieve:
Prog table:
|[ID1]|[ID2]|[MONTHNUMBER]|[PRGCASH]|
| 1 | A | 1 | 600 |
| 1 | B | 1 | 500 |
ALS table:
|[ID1]|[ID2]|[MONTHNUMBER]|[ALSCASH]|
| 1 | A | 1 | 100 |
| 1 | A | 2 | 100 |
| 1 | A | 3 | 100 |
Ideal Result:
|[ID1]|[ID2]|[MONTHNUMBER]|[PRGCASH]|[ALSCASH]|
| 1 | A | 1 | 600 | 100 |
| 1 | A | 2 | | 100 |
| 1 | A | 3 | | 100 |
| 1 | B | 1 | 500 | |
This query, tested with Access 2007, returns the result set you want.
SELECT
p1.ID1,
p1.ID2,
p1.MONTHNUMBER,
p1.PRGCASH,
a1.ALSCASH
FROM
T_Prog AS p1
LEFT JOIN T_ALS AS a1
ON
p1.MONTHNUMBER = a1.MONTHNUMBER
AND p1.ID2 = a1.ID2
AND p1.ID1 = a1.ID1
UNION
SELECT
a2.ID1,
a2.ID2,
a2.MONTHNUMBER,
p2.PRGCASH,
a2.ALSCASH
FROM
T_ALS AS a2
LEFT JOIN T_Prog AS p2
ON
a2.MONTHNUMBER = p2.MONTHNUMBER
AND a2.ID2 = p2.ID2
AND a2.ID1 = p2.ID1;
Hello there I have a following table
------------------------------------------
| id | language | parentid | no_daughter |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 1 | 1 | 0 | 2 |
------------------------------------------
| 2 | 1 | 1 | 1 |
------------------------------------------
| 2 | 2 | 1 | 1 |
------------------------------------------
| 3 | 1 | 1 | 0 |
------------------------------------------
| 3 | 2 | 1 | 0 |
------------------------------------------
| 4 | 1 | 2 | 0 |
------------------------------------------
| 4 | 2 | 2 | 0 |
------------------------------------------
| 5 | 1 | 2 | 0 |
------------------------------------------
| 5 | 2 | 2 | 1 |
-----------------------------------------
| 5 | 1 | 4 | 1 |
------------------------------------------
| 5 | 2 | 4 | 1 |
------------------------------------------
Scenario
Every record has more than one rows in table with different language ids. parentid tells who is the parent of this record. no_daughter columns tells against each record that how many child one record has. Means in Ideal scenario If no_daughter has value 2 of id = 1 , it means 1 should be parentid of 2 records in same table. But If a record has more than one exitance with respect to language, it will be considered as one record.
My Problem
I need to find out those records where no_daughter value is not correct. It means if no_daughter is 2, there must be two records whoes parentid has that id. In above case record with id = 1 is valid. But record having id = 2 is not valid because the no_daughter = 1 but actual daughter of this record is 2. Same is the case with id=4
Can any body tell me how can I find these faulty records?
Updated after answers
Ken Clark has and shola has given answer which return same result for example shola query is
SELECT DISTINCT
id
FROM
tbl_info t
INNER JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
AND t.no_daughters != parentchildrelation.childs
This query is returning those ids who have been used as parentid somewhere in table but having wrong no_daughter values. But not returning ids that has value in no_daugter columns but have not been used as parentid any where in table. For exampl id = 5 has no_daughter = 1 but it is not used as parentid in table. So it is also a faulty record. But above query is not capturing such records.
Any help will be much appreciated.
Try this:
SELECT DISTINCT
id
FROM
tbl_info t
Left JOIN
(SELECT
parentid,
COUNT(DISTINCT id) AS childs
FROM
tbl_info
GROUP BY parentid) AS parentchildrelation
ON t.id = parentchildrelation.parentid
Where t.no_daughters != parentchildrelation.childs
Try this:
SELECT id FROM tinfo t inner join
(SELECT parentid, COUNT(distinct language ) as childs FROM tinfo group by parentid) as summary
on t.id=summary.parentid and t.no_daughters!= summary.childs
try this
Select Distinct * From tablename t
Left Join
(
Select COUNT(t1.Id) Doughter,t1.parentid,t1.language From tablename t1 Group By t1.parentid,t1.language
)tbl
On t.id=tbl.parentid And tbl.language=t.language And t.no_daughter<>tbl.Doughter