SELECT *
FROM `all_salary_slip_details` `assd`
INNER JOIN `employee_master` `em` ON `assd`.`EMPLOYEE_ID` = `em`.`EMPLOYEE_ID`
INNER JOIN `employee_details` `ed` ON `assd`.`EMPLOYEE_ID` = `ed`.`EMPLOYEE_ID`
INNER JOIN `organizations` `o` ON `o`.`ORG_ID` = `assd`.`ORG_ID`
INNER JOIN `months` `mo` ON `mo`.`id` = `assd`.`PAY_MONTH`
This is my query to fetch data from db. I have only 4 rows but in my view I get 48 rows. I dont understand why this happens.
You need to use a GROUP BY clause on a column, then your query will only return a single row for each unique entry in that column.
In your case I'm guessing it would make sense to use the employee name.
What result does this query output?
SELECT assd.PAY_YEAR, assd.PDF, em.EMPLOYEE_NAME, o.ORG_NAME, mo.month_name
FROM all_salary_slip_details assd
INNER JOIN employee_master em
ON assd.EMPLOYEE_ID = em.EMPLOYEE_ID
INNER JOIN organizations o
ON o.ORG_ID = assd.ORG_ID
INNER JOIN months mo
ON mo.id = assd.PAY_MONTH
GROUP BY em.EMPLOYEE_NAME
You will get 1 row returned in your query for each record in a joined table that matches the join condition.
So, if you have multiple records in any one of the employee_master, employee_details, organisations or months tables that match those in all_salary_slip_details you will get additional rows returned. Look at the rows returned, you will see differences in each and where they differ will tell you where the join condition for the table isn't specific enough to return a single row.
I had a SELECT query with a LEFT JOIN working as desired. I then added one more table via a smilar LEFT JOIN and now I am getting a wierd result. Basically, for a group_concat where I was getting one item for every record, I am getting eight records. I don't see why this is happening because the join to the new table is analagous to several other joins that do not have this problem (that I have omitted from the example for clarity).
Here is the query that is fine:
$sql = "SELECT t.*,
group_concat(tf.todoid) as `tftodoid`,
group_concat(tf.id) as `tfid`,
group_concat(tf.filedescript) as `tffiledescript`,
group_concat(tf.filename) as `tffilename`,
group_concat(tf.founderid) as `tffounderid`,
group_concat(tf.ext) as `tfext`,
group_concat(tf.lasttouched) as `tilt`
FROM titles `t`
LEFT JOIN titlefiles `tf`
ON (tf.todoid = t.id AND tf.founderid = '$userid')
WHERE t.userid='$userid'
GROUP BY t.id";
And here is the query with the extra join that is now spilling out the multiple copies of the items:
$sql = "SELECT t.*,
group_concat(tf.todoid) as `tftodoid`,
group_concat(tf.id) as `tfid`,
group_concat(tf.filedescript) as `tffiledescript`,
group_concat(tf.filename) as `tffilename`,
group_concat(tf.founderid) as `tffounderid`,
group_concat(tf.ext) as `tfext`,
group_concat(tf.lasttouched) as `tilt`,
group_concat(s.id) as `stepid`,
group_concat(s.step) as `steps`
FROM titles `t`
LEFT JOIN titlefiles `tf`
ON (tf.titleid = t.id AND tf.founderid = '$userid')
LEFT JOIN steps `s`
ON s.titleid = t.id
WHERE t.userid='$userid'
GROUP BY t.id";
Here is an example of output in JSON showing the difference:
First query:
"tfid":"56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81"
Second query:
"tfid":"56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81,56,57,58,59,60,61,62,63,64,65,66,67,68,75,76,81",
I suspect the problem has something to do with the JOIN or with the Group By statements but I can't see how to fix.
How can I ensure that I get only one fileid per file as opposed to eight?
Alter the line as follows:
group_concat(DISTINCT tf.id) as `tfid`,
This then only gets you the unique ids.
If you want them ordered add:
group_concat(DISTINCT tf.id ORDER BY tf.id ASC) as `tfid`,
Hello I would like to know how I can realizes query selection inside echo of already processed query.
This is my firs Mysql Query
SELECT * FROM cursos_modulos
foreach($result as $row)
{
$id = $row['id'];
echo"
Here where the echo goes I have to make the other query which is:
SELECT COUNT(users.userID)
FROM users
INNER JOIN subscriptions
ON users.userID = subscriptions.user_id
WHERE subscriptions.curso_id = $id
and at the end to put the result of this query
foreach($result as $rowc)
.$rowc[0]."};
Any help how I can achive this goal will be very welcome. Question is simple. First Select Selects the Cours with it's unique ID. which ID have to be used in the second, third and else... queries. Which queries are like the second one. So First Select Course and then Select different parameters from this course based on this ID. at the end dump results of each of the selections with different indications"
Do it all in one query:
SELECT c.*, count(s.curso_id) as count
FROM cursos_modulos AS c
LEFT JOIN subscriptions AS s ON s.curso_id = c.id
LEFT JOIN users AS u ON u.userID = s.user_id
The LEFT JOIN is needed to get 0 for the count if there are no matching rows in subscriptions.
To include a second count of approved subscriptions:
SELECT c.*, count(s.curso_id) as count, SUM(IF(s.approved = 'approved', 1, 0)) AS count_approved
FROM cursos_modulos AS c
LEFT JOIN subscriptions AS s ON s.curso_id = c.id
LEFT JOIN users AS u ON u.userID = s.user_id
So the situation is I have a query that involves 9 tables and I need to write it so it returns all records even when the impactid in the workorderstates table is NULL.
Previous to the below query I noticed I wasn't getting all results that were "open" because initially I just had where workorderstates.impactid = impactdefiniton.impactid and in the situations where impactid is NULL in the workorderstates table this condition would not be true, thus eliminating records that should be returned because they are in fact "open".
So I devised this query below but every time I run it it will not work. It will will return not unique table alias workorder. If I use aliases for tables it just moves on the right tables in the join as not being unique. Can anyone offer me any help on restructuring the query so it will work? I've tried a lot of variations and interestingly enough the second query ALMOST works but it returns duplicate records (in this case four of the same record)
select workorder.workorderid, workorder.siteid,
FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,
categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid,
IFNULL(impactdefinition.name, "Not Set") as impactname, first_name,
sdorganization.name, statusname, title
from workorder, statusdefinition, sitedefinition, sdorganization,
prioritydefinition, categorydefinition, sduser, aaauser, workorderstates
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid
left join workorder on workorder.workorderid = workorderstates.workorderid
left join workorderstates on workorderstates.statusid = statusdefinition.statusid
left join workorder on workorder.siteid = sitedefinition.siteid
left join sitedefinition on sitedefinition.siteid = sdorganization.org_id
left join workorderstates on workorderstates.categoryid = categorydefinition.categoryid
left join workorder on workorder.requesterid = sduser.userid
left join sduser on sduser.userid = aaauser.user_id
where statusname='Open' and workorder.createdtime >= '1352678400000'
and sdorganization.name='MAPL'
order by workorder.workorderid
Query that almost works but is ugly (returns duplicated records):
select workorder.workorderid, workorder.siteid,
FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,
categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid,
IFNULL(impactdefinition.name, "Not Set") as impactname, first_name,
sdorganization.name, statusname, title
from workorder, statusdefinition, sitedefinition, sdorganization,
prioritydefinition, categorydefinition, sduser, aaauser, workorderstates
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid
where workorder.workorderid = workorderstates.workorderid
and workorderstates.statusid = statusdefinition.statusid
and workorder.siteid = sitedefinition.siteid
and sitedefinition.siteid = sdorganization.org_id
and workorderstates.categoryid = categorydefinition.categoryid
and workorder.requesterid = sduser.userid and sduser.userid = aaauser.user_id
and statusname='Open' and workorder.createdtime >= '1352678400000'
and sdorganization.name='MAPL'
order by workorder.workorderid
Any ideas of how to get this query working??? Thanks guys!
I took a look at your query and I think you have some basic misunderstandings about JOINs and how to write them. It's like you're just guessing at syntax at random, and that's not the way to write code.
I examined your query and converted it into SQL-92 syntax. I had to make some inferences about join conditions, so I can't guarantee it's correct for your application, but it's a lot closer to a legal query.
Only I couldn't find any condition in your example for the join to your prioritydefinition table. That's likely to be the cause of your duplicate rows. You're generating what's called a Cartesian product.
select workorder.workorderid, workorder.siteid,
FROM_UNIXTIME(workorder.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,
categoryname, IFNULL(workorderstates.impactid, "No Set") as impactid,
IFNULL(impactdefinition.name, "Not Set") as impactname, first_name,
sdorganization.name, statusname, title
from workorder
inner join statusdefinition on workorderstates.statusid = statusdefinition.statusid
inner join sitedefinition on workorder.siteid = sitedefinition.siteid
inner join sdorganization on sitedefinition.siteid = sdorganization.org_id
inner join prioritydefinition ...NO JOIN CONDITION FOUND...
inner join categorydefinition on workorderstates.categoryid = categorydefinition.categoryid
inner join sduser on workorder.requesterid = sduser.userid
inner join aaauser on sduser.userid = aaauser.user_id
inner join workorderstates on workorder.workorderid = workorderstates.workorderid
left Join impactdefinition on workorderstates.impactid = impactdefinition.impactid
where statusname='Open'
and workorder.createdtime >= '1352678400000'
and sdorganization.name='MAPL'
order by workorder.workorderid
You really need to get someone who knows your application and also knows how to write SQL to tutor you before you write any more SQL joins.
I too reformatted your query but have it more visually hierarchical to show relations from the first (left-side) table to what it is getting its details from (right-side) table. As Bill mentioned, you had an extra table that was not doing anything and thus your Cartesian product.
Now, if you ARE stuck and have no one else to really help, here is a basic of LEFT-JOIN vs INNER-JOIN. Left-join basically says I want every record from the table on the left (as I have listed first) REGARDLESS of there being a record found on the right side. If there IS a match, great, no problem... but if no match, your query will still run.
So, I've set to all LEFT-JOINs. You can change as needed for those you know MUST always exist... such as a work order is entered by a "user". So that you could change. Hopefully this helps you out. Also look at how I've nested from work order to work order states and from work order states to get the corresponding status definition and other things associated with the work order states table. Others were directly related with the work order, so those are at THAT hierarchical level.
One last note... not all your fields were table.field reference (which I changed to aliases to help readability). QUALIFY ALL your fields so you and others trying to help, or read your code in the future know the origin of the field, not just guessing (its in one of the tables)
select
WO.workorderid,
WO.siteid,
FROM_UNIXTIME(WO.CREATEDTIME/1000, '%m-%d-%Y %H:%i:%s') as createdate,
categoryname,
IFNULL(WOS.impactid, "No Set") as impactid,
IFNULL(ImpD.name, "Not Set") as impactname, first_name,
SDO.name,
statusname,
title
from
workorder WO
LEFT JOIN workorderstates WOS
ON WO.workorderid = WOS.workorderid
LEFT JOIN statusdefinition StatD
ON WOS.statusid = StatD.statusid
LEFT JOIN categorydefinition CatD
ON WOS.categoryid = CatD.categoryid
LEFT JOIN impactdefinition ImpD
ON WOS.impactid = ImpD.impactid
LEFT JOIN sitedefinition SiteD
ON WO.siteid = SiteD.siteid
LEFT JOIN sdorganization SDO
ON SiteD.siteid = SDO.org_id
and SDO.name = 'MAPL'
LEFT JOIN sduser U
ON WO.requesterid = U.userid
LEFT JOIN aaauser AU
ON U.userid = AU.user_id
where
statusname = 'Open'
and WO.createdtime >= '1352678400000'
order by
WO.workorderid
I try to use this Query to get Number of Records bu tits not display count in phpMyAdmin
And also give me the wrong result when i try to remove LIMIT from Query..
SELECT COUNT(*) as `num` FROM fm_detail
LEFT JOIN lang ON lang.l_id = fm_detail.language_id
LEFT JOIN country ON country.c_id = fm_detail.country_id
LEFT JOIN users ON users.usr_id = fm_detail.submitter_id
LEFT JOIN category ON category.cat_id = fm_detail.category_id
INNER JOIN city ON fm_detail.city_fm = city.city_id
where 1=1 AND fm_detail.category_id = '1' LIMIT 10 , 5
This query did not give me any Record Count..
But when i use..
SELECT * FROM fm_detail
LEFT JOIN lang ON lang.l_id = fm_detail.language_id
LEFT JOIN country ON country.c_id = fm_detail.country_id
LEFT JOIN users ON users.usr_id = fm_detail.submitter_id
LEFT JOIN category ON category.cat_id = fm_detail.category_id
INNER JOIN city ON fm_detail.city_fm = city.city_id
where 1=1 AND fm_detail.category_id = '1' LIMIT 10 , 5
This give me the Records list in PHPMYADMIN..
I don't know how to use this query to fix my problem.
Please help me asap..
Thanks,
Because you use COUNT function (which in your case returns one row) and LIMIT clause that starts from 10 record. So, you do not get any records at all.
About the LIMIT... maybe select distinct will help to get the right count. Joins sometimes create duplicated rows.