Why error #1066 - Not unique table/alias: 'cat_rapoarte' - php

I'm working on a student->parent->teacher grading system for the school I work at and while using MySQL I have received this error. Why?
SELECT `cat_materii`.*
FROM `cat_rapoarte`
INNER JOIN `cat_rapoarte` on
`cat_materii`.`m_id`=`cat_rapoarte`.`rap_m_id`
WHERE `cat_rapoarte`.`k_id` = '7fbXe1dvltedEkIXELc8Q1NeMkKRb3pi' AND (data BETWEEN '2015-11-01' AND '2015-11-30') GROUP BY `rap_m_id`

You had the same table twice in the join clause. See the commented part in the query.
SELECT `cat_materii`.*
FROM `cat_materii` --`cat_rapoarte`
INNER JOIN `cat_rapoarte` on `cat_materii`.`m_id`=`cat_rapoarte`.`rap_m_id`
WHERE `cat_rapoarte`.`k_id` = '7fbXe1dvltedEkIXELc8Q1NeMkKRb3pi'
AND (data BETWEEN '2015-11-01' AND '2015-11-30')
GROUP BY `rap_m_id`

Related

MYSQL/PHP: Concat returning to many fields on LEFT JOIN

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`,

SQL query privatemsgs between users GROUP BY ERROR

I've build the following query:
(SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
privatemsgs.relatedto
FROM privatemsgs
LEFT JOIN
users AS u ON(privatemsgs.useraid = u.id)
WHERE userbid='5'
AND relatedto=0 and bdel=1)
UNION ALL
(SELECT
privatemsgs.id,
privatemsgs.useradn,
privatemsgs.useraid,
privatemsgs.title,
privatemsgs.created,
privatemsgs.timee,
privatemsgs.isread,
u.photo AS creatorphoto,
rel.relatedto
FROM privatemsgs AS rel
JOIN privatemsgs ON(rel.relatedto = privatemsgs.id)
LEFT JOIN
users AS u ON(rel.useraid = u.id)
WHERE rel.userbid='5')
GROUP BY id
ORDER BY timee DESC
This query select all Privatemsgs from the tables, and acting like mail,FOR EX:
If I sent a msg to user b, and user b answered me. I want to display the msg in inbox and outbox of each user.
A comment to private msg marked as "relatedto" the id of the main msg.
The query works, but duplicate the msgs in display (same msg display many times)
I tried to do "GROUP BY id" in order to fix it but i got the error:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY id ORDER BY timee DESC'
THANK YOU!!
First, as per PM 77's comment, a union instead of a union all will solve your problem of duplicates. You don't need a group by clause at all.
Second, you might have a logic error. The top have of your union query has this:
FROM privatemsgs
LEFT JOIN
users AS u ON(privatemsgs.useraid = u.id)
WHERE userbid='5'
AND relatedto=0 and bdel=1)
If any of those fields in the where clause are in the users table, your left join has become an inner join. To keep it as a left join, you have to put all the filters in the join, like this:
FROM privatemsgs
LEFT JOIN
users AS u ON privatemsgs.useraid = u.id
AND userbid='5'
AND relatedto=0 and bdel=1)

mysql left join with 9 tables

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

MySQL error with Not unique table/alias with join

SELECT `idstudii`
FROM (`studii`)
JOIN `studii` ON `mesaje`.`idstudii`=`studii`.`id`
JOIN `users` ON `users`.`id`=`studii`.`idusers`
WHERE `studii`.`idusers` = '1'
I have this sql query which gives me the error "Not unique table/alias". This is not the case as "studii" is the only table with that name. Why does this error show up?
FROM (`studii`)
JOIN `studii`
in this care you are referring to 2 different selections of a table with the same alias (studii)
FROM `studii` AS s1
JOIN `studii` AS s2 ON s2.something2 = s1.something1

Inner Join using COUNT(*)

I am selecting the user's information from my MySQL database as shown below:
SELECT * FROM `Users` WHERE `$user_or_id` = ?
However, I would like to add an extra bit off information to the returned data. The extra bit of data is the total number of records in a table named 'Venues' where the rows' field, 'user_id' is the same as the 'id' field in the table, 'Users'.
Please can you tell me where I am going wrong with the following query? Here is the error I am receiving:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '*) FROM Users AS u INNER JOIN Venues AS v ON u.id =
v.user_id WHERE u.id = '' at line 1
SELECT u.*, v.count(*) FROM `Users` AS u INNER JOIN `Venues` AS v ON u.id = v.user_id WHERE u.$user_or_id = ?
SELECT u.*, COUNT(v.*) FROM `Users` AS u INNER JOIN `Venues` AS v ON u.id = v.user_id WHERE u.$user_or_id = ?
COUNT is a MySQL function, not a member of table v. Pass it an argument representing what you want to count-- in this case, v's rows.
It should be COUNT(v.*). Otherwise it's interpreted as "function count inside table V", which isn't valid.
Just use count(*) instead of v.count(*).

Categories