Laravel SQLSTATE[42000]: Syntax error or access violation - php

I am new to laravel and im stuck with my relationshops what looks like the following
Categories
id name slug
-----------------------------------------------------------------
3 Location location
4 Outfits outfits
5 Other other
sub_categories
id category_id name slug
-----------------------------------------------------------------------------
12 3 Club club
13 3 Home / Hotel home-hotel
14 3 Outdoor outdoor
15 3 Studio studio
16 4 Bikini / Swimwear bikini-swimwear
17 4 Dress dress
19 4 Jeans jeans
35 5 Dancing dancing
Category model
<?php
class Category extends Eloquent {
public $timestamps = false;
public function subcategory()
{
return $this->belongsToMany('subcategory', "sub_categories");
}
}
And i get the following error
SQLSTATE[42000]: Syntax error or access violation: 1066 Not unique table/alias: 'sub_categories' (SQL: select `sub_categories`.*, `sub_categories`.`category_id` as `pivot_category_id`, `sub_categories`.`subcategory_id` as `pivot_subcategory_id` from `sub_categories` inner join `sub_categories` on `sub_categories`.`id` = `sub_categories`.`subcategory_id` where `sub_categories`.`category_id` = ?) (Bindings: array ( 0 => 1, ))
Could please someone point out what I am doing wrong?

you should give different aliases names to same table
change this
inner join `sub_categories`
to
inner join `sub_categories` as sc
^^--//-this alias use it instead of sub_categories
in your query it will be
select `sub_categories`.*, sc.`category_id` as `pivot_category_id`, sc.`subcategory_id` as `pivot_subcategory_id` from `sub_categories` inner join `sub_categories` sc on sc.`id` = `sub_categories`.`subcategory_id` where `sub_categories`.`category_id` = ?) (Bindings: array ( 0 => 1, )
Example:
select * from table1 as t1
inner join table1 as t2
on t1.id = t2.id
Clarification of your error: Not unique table/alias
you are joining same table without aliases to different between them.

The problem looks like that two tables are mapped to the same name sub_category at once.
A many-to-many relationship requires 3 tables (category/subcategory/category_subcategory) which need distinct names. If two of the tables get mapped with the same name, you'll get the error you're showing.
Change one of the mappings, and you should be up and running.

Related

How should be my mysql table structure?

This is what I want:
Users will send one or two values in my website and I will store them in two variables $genres1 and $genres2.
Like: If user sends, Action, then my code will show all movies with Action genres. If user sends Action+Crime, then my table will fetch all movies with Action+Crime.
Got it?
My current table structure is one to many relationship, like this
tmdb_id movie_title
-----------------------------
1 Iron man
2 Logan
3 Batman
4 The hangover
tmdb_id genres
-----------------------------
1 Action
1 Crime
2 Drama
2 Action
3 Crime
3 Action
4 Comedy
4 Drama
But the problem here is, I can't achieve what I explained above with this.
2nd option: I make a single table like this:
movie_tile genres1 genres2 genres3 genres4
----------------------------------------------------
Logan Action Crime Drama Null
Iron man Action Crime Null Null
And I can do what, I want with this single line:
SELECT * FROM movies WHERE (genres1='$genres1' or genres2='$genres1' orgenres1='$genres3' or genres3='$genres1')
Any other option?
use a table width genres
and use an other table connecting the movie to any genre
-----
movieid title
-----
1 Logan
2 Smurf
-----
-----
genreid genre
-----
1 animated
2 blue people
-----
-----
movieid genreid
-----
1 1
2 1
2 2
-----
that way you won't be limited to 4 genres per movie
now I read your question better.
That's what you do, but you put left out the genre-table.
The 2nd option is bad, as you limit yourself to only 4 categories
Is this connected to PHP? I think is easiest to solve this further by a join query, sorted by movie and a loop in PHP
you want all movies where (by user request) the genres are both Crime And Action?
SELECT mg.movieid, count(1), m.title
FROM movies_genres mg
JOIN movies m ON m.movieid mg.movieid
WHERE mg.genreid = 1 OR mg.genreid =3
group by mg.movieid, m.title
HAVING COUNT(1) = 2
edit: see other genres as well
SELECT movies.movieid,movies.title, genres.genre
FROM movies
JOIN movie_genre mg ON mg.movieid = movies.movieid
JOIN genres on genres.genreid = mg.genreid
WHERE movie.movieid IN (
SELECT mg.movieid
FROM movies_genres mg
WHERE mg.genreid = 1 OR mg.genreid =3
GROUP BY mg.movieid
HAVING COUNT(1) = 2
)
forgot to mention: count = 2, means you gave 2 genreid's to find. This could also be 1, 3 or 25
select distinct a.tmdb_id, a.movie_tittle
from movie_tittle a inner join genre_tittle b
on a.tmdb_id = b.tmdb_id
where b.genres in ('Action', 'Crime')
Based on your comment, try this :
SELECT
a.tmdb_id, a.movie_tittle
FROM
movie_tittle a inner join genre_tittle b
ON
a.tmdb_id = b.tmdb_id
WHERE
b.genres in ('Action', 'Crime')
GROUP BY
a.tmdb_id, a.movie_tittle
HAVING
count(a.tmdb_id) = 2
tmdb_id and genres in table genre_tittle should not duplicated. Make it as primary key.
But the problem here is, I can't achieve what I explained above with [the first two tables]
Yes, you can. Assuming the two tables are called movies and movie_genres, you can select the movies which have both tags using:
SELECT movie_title FROM movies
JOIN movie_genres genre1 USING (tmdb_id)
JOIN movie_genres genre2 USING (tmdb_id)
WHERE genre1.genres = 'Action'
AND genre2.genres = 'Crime'
See it for yourself here.
try something like this :
tableA
Movie_ID Movie_title
1 Iron man
2 Logan
3 Batman
4 The hangover
tableB
Genre_ID Genre_title
1 Action
2 Crime
3 Drama
4 Comedy
tableC
ID Movie_ID Genre_ID
1 1 1
2 1 2
3 2 2
4 2 3
query :
Select A.Movie_title,B.Genre_title
from tableC C
inner join tableA A on A.Movie_ID = C.Movie_ID
inner join tableB B on B.Genre_ID = C.Genre_ID
where
C.Genre_ID in (IFNULL(val1,0),IFNULL(val2,0))
you should make a relational table to solve you issues like so
movie table
movie_id movie_name genre_id
1 alien 2
2 logan 1
3 ps i love you 4
4 click 3
then you will need a genre table
genre table
genre_id genre_type
1 action
2 sci fi
3 comedy
4 romance
then your select would link the to tables
function get_movies_by_genre($genre_id) {
global $MySQLiConnect;
$query = '
SELECT *
FROM movies m
INNER JOIN genre g ON (g.genre_id = m.genre_id)
WHERE g.genre_id = ?
';
$stmt = $DBConnect->stmt_init();
if ($stmt->prepare($query)) {
$stmt->bind_param("i", $genre_id);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
}
return $rows;
}
or
function get_movies_by_genre($genre_id) {
global $MySQLiConnect;
$query = '
SELECT *
FROM movies m
INNER JOIN genre g ON (g.genre_id = m.genre_id)
WHERE g.genre_name = ?
';
$stmt = $DBConnect->stmt_init();
if ($stmt->prepare($query)) {
$stmt->bind_param("i", $genre_id);
$stmt->execute();
$result = $stmt->get_result();
$rows = $result->fetch_all(MYSQLI_ASSOC);
$stmt->close();
}
return $rows;
}
This is the base function to get you all information from the movie table depending on which genre id you send to it.
as for multiple ids you can then run the function through a foreach loop for as many genre_ids as you need and then display them as you need.
I hope this helps.

How can i use sql count in these multiple tables?

I am still a php/mysql newbie and I am working on mysql table relationship concept and i am having an issue with using mysql count in multiple table. Here is my db structure.
**product table**
id product_name product_img groupeid
1 Sneaker Mark sneaker_adi.png 1
2 bag Eric bageric.png 2
3 Sneaker Etoi sneakeretoi.jpg 1
**groupe table**
group_id group_name
1 men
2 women
**category table**
catid catname
1 sneaker-shoes
2 bag-woman
**productcategory table**
prod_id cat_ID
1 1
2 2
3 1
What i want to do is to determine the number of sneaker-shoes using mysql.
We can see that the number of sneaker-shoes in the db is 2.
But how can i use **count()** in these multiple tables.
I tried like this;
$sql = "SELECT COUNT(*) product.id,product_name,catname FROM product INNER JOIN productcategory ON product.id = prod_id INNER JOIN category ON catid = cat_ID WHERE catname='sneaker-shoes'";
i got error like:
Fatal error: Call to a member function execute() on a non-object in C:\wamp\www\kbashopping\Homme\index.php on line 32
Hope i exposed the issue clearly, any help and assistance will be appreciate
Thanks
If you are looking only for the count, mention only the count phrase in the Select clause.
Change :
SELECT COUNT(*) product.id,product_name,catname FROM
to :
SELECT COUNT(product.id) FROM
SELECT count (pc.cat_ID) FROM productcategory pc inner join category c on c.catid = pc.cat_ID where c.catname = 'sneaker shoes';
This will build a temporary table in mysql that joins category and product category but only including results where the catname is sneaker shoes. Then it selects a column to run the count operation on, and returns the result of count.

Select from three tables

I have three tables where table_2 is the middle(connected) between table_1 and table_3
tables
table_id
...
...
table_rest
rest_id
table_id
...
rest
rest_id
...
...
And the query to select I use
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
WHERE rest_id = '$rest_id'
What I need now is to join in this query another table reserv
id
...
status
To check if status is 0, 1,or 2 to not show me anything if there is no status this mean there is no record to show me. In other words this is resserved system where I show on screen few tables. If status is 0,1,2 thats mean the table is taken. If nothing is found for status this mean that there is no record for table and can be shown to user.
EDIT: Sample scenario
tables
table_id
1
2
3
4
5
rest
rest_id
1
2
table_rest
table_id | rest_id
1 2
2 2
3 2
4 2
5 2
So the query that is above will generate 5 tables for rest_id=2 and none for rest_id=1
So now I have another table
reserv
id | status
1 0
2 1
3 2
So in this table reserv currently are saved 3 tables. The idea is to show me other two whit id=4 and id=5 because they are not in table reserv and don't have any status.
Hope is a little bit more clear now.
You have to point from table reserv to which table is beign booked, let's call it reserv.table_id
SELECT m.table_id, table_name
FROM tables m
JOIN table_rest mr
ON m.table_id = mr.table_id
left join reserv
on reserv.table_id = m.id
WHERE rest_id = '$rest_id'
and reserv.status is null (*note)
*note use 'is' or 'is not' depending of your needs, as far as I read, first seems that you want !=, later that what you want is =
It's better if you provide sample data or sqlfiddle. Based on what I realize: Is this what you want:
select tables.table_id, rest.rest_id
from tables
left join table_rest on table_rest.table_id = tables.table_id
left join rest on rest.rest_id = table_rest.rest_id
where rest.rest_id = '$rest_id'
and tables.table_id not in (select id from reserv)

Table referencing itself , MySQL, primary key and foreign key in same table , select statement

how i select column of categories wich two types SubCat & MainCat from Table referencing itself called cat:
where FOREIGN KEY (maincat_id) REFERENCES at (cat_id) which is PrimeryKey
table in DataBase:
cat_id catname maincat_id cat_type
1 hello NULL 1
2 one 3 2
3 test 1 2
4 te3 3 2
As you see if cat_type=1 so it's SubCat.
i just need table select all the SubCat and the MainCat which it's belong, as this:
catname Root_name
one test
test hello
te3 test
more info:
We have One table of categories called 'cat', in it There are (Main Categories) and (Sub Categories), which make small tree (just one level depth) .
You can just use a simple inner join for this:
SELECT t1.catname AS Category, t2.catname AS Subcategory
FROM cat t1 INNER JOIN cat t2
ON t1.cat_id = t2.maincat_id
WHERE t1.cat_type = 1
After all, i hope i understand your question right, and this is what you need.
Fiddle: http://sqlfiddle.com/#!2/94e65/18
you can use self join for this
select c.catname as catname ,m.catname as Root_name from cat as c, cat as m
where c.maincat_id = m.cat_id && c.cat_type=2;

Fetch data from 4 tables mysql

I have 4 tables as below
Table1: restos
Structure:
resu_id resu_name resu_address
-------------------------------------
1 ABC Exapmple
2 DEF Example
3 GHD Example
Table2:foodtype
Structure:
id typename
---------------
12 Indian
23 Punjabi
Table3: resto_foodtypes
Structure:
resu_id foodty_id
--------------------
1 12
2 23
3 12
Table4: discnts
Structure:
id resu_id amt_dscPer(%age discount)
---------------------------
19 1 15
20 2 25
Now i want to display the restaurant along with discounts available for the restauarant.
Currently restaurants are getting displayed but for the restaurant not present in discnts table are returning null values from discnts table.
below is the query that m using
SELECT * from `restos` r join resto_foodtypes rf on rf.resu_id = r.resu_id
join foodtype f on rf.foodty_id = f.id left join discnts dcfm on
r.resu_id= dcfm.resu_id where true;
I want that the restaurants that are not present in discnts table should not be included in resultset. For e.g. resu_id=3 is not present in discnts table.
To exclude results that have no entry in discnts table, use a INNER JOIN instead of a LEFT JOIN.
To include these results, but have a 0 displayed (instead of the defaults NULL), you can use IFNULL(expr, 0) function:
SELECT
r.resu_name AS Name,
f.typename AS Food,
IFNULL(dcfm.amt_dscPer, 0) AS Discount
FROM `restos` r
JOIN resto_foodtypes rf ON rf.resu_id = r.resu_id
JOIN foodtype f ON rf.foodty_id = f.id
LEFT JOIN discnts dcfm ON r.resu_id= dcfm.resu_id;
IFNULL returns the first parameter if it is not null, the second if expr is indeed null.

Categories