Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Please I need some help in writing an SQL statement for a PHP application that involves four tables. Here is the situation.
Each Art in Table B has a list of categories in Table D
Each PlaceID in Table A has a list of categories in Table C
I need to select Art from Table B to fill a PlaceID in Table A, but both Art and PlaceID must have at least one category in common.
I will appreciate any help that I can get.
TABLE A
PlaceID |
1 |
2 |
TABLE B
ArtID | Art
1 | Art1
2 | Art2
3 | Art3
TABLE C
ID | PlaceID | Category
1 | 1 | Cat1
2 | 1 | Cat2
3 | 2 | Cat3
4 | 2 | Cat1
5 | 3 | Cat1
TABLE D
TabID | ArtID | Category
1 | 1 | Cat1
2 | 1 | Cat2
3 | 1 | Cat3
4 | 2 | Cat1
5 | 2 | Cat2
For a given myPlaceID you can find possible Art values as follows:
SELECT DISTINCT B.Art
FROM B
INNER JOIN D
ON D.ArtID = B.ArtID
INNER JOIN C
ON C.Category = D.Category
WHERE C.PlaceID = :myPlaceID;
You don't need table A in this query.
Here is a fiddle. Note that for the existing values for PlaceID (1, 2, 3) you will always get 2 records as result (Art1, Art2) with the example data you provided. So you might want to use some other data to get more variation in your results.
Assuming the two tables tablec and tabled are related with Category, then you can do this:
SELECT
b.Art,
a.PlaceId,
COUNT(DISTINCT c.Category) AS TotalCategories
FROM tableA AS a
INNER JOIN tablec AS c ON a.placeID = c.PlaceID
INNER JOIN tabled AS d ON d.Category = c.Category
INNER JOIN tableB AS b ON b.ArtID = d.ArtID
GROUP BY b.Art, a.PlaceId
HAVING COUNT(DISTINCT c.Category) > 0;
This will give you only the places and arts that has at least one category in common, with count of categories in common.
SQL Fiddle Demo
This will give you:
| Art | PlaceID | TotalCategories |
|------|---------|-----------------|
| Art1 | 1 | 2 |
| Art1 | 2 | 2 |
| Art2 | 1 | 2 |
| Art2 | 2 | 1 |
As you can see this returned only art 1, 2 with places 1, 2 as they are the only arts and places have more than one category in common.
Side note: In your table designs, you are missing the many to many junction table between arts and places. So, iF the category is just to relate tablec with tabled, then you can get rid of either tablec or tabled, So that you will have both placeid and artid in the same table that will act as many to many junction table.
Related
having a fairly low level in sql, I come to seek your help because I am blocked.
So I have a database containing my 2 tables, an article table and a category table. In my article table, I have a field that contains the IDs of the categories to which it belongs in the JSON format.
Schematically, the categories table looks like this:
| Name | id |
| Cat1 | 1 |
| Cat2 | 2 |
| Cat3 | 3 |
And the table articles:
| Title | id | Categories |
| Title1 | 1 | [1,2] |
| Title2 | 2 | [1,3] |
| Title3 | 3 | [2,3] |
Currently, I retrieve my articles as follows:
SELECT *
FROM articles a
JOIN categories c
ON JSON_CONTAINS(a.categories, CAST(c.id AS CHAR))
Then in php I group them by categories. But I find that this solution is not very clean.
So I wanted to know if a SQL query could retrieve a list of articles already grouped by categories in this way:
Cat1
- Article 1
- Article 2
cat2
- Article 1
- Article 3
Cat3
- Article 2
- Article 3
It is better database design to make a new table ArticleCategories that lists each articles categories:
ArticleID, CatID
Where an ArticleID can have multiple CatID...
Now you can associate multiple categories to one article and easily search this new database with SQL for correlations between categories and articles.
SELECT c.category, STRING_AGG(a.title, ',')
FROM articles a
LEFT JOIN articleCategories ac
ON a.id = ac.articleID
LEFT JOIN categories c
ON c.id = ac.categoryID
GROUP BY c.category
I found this query that can combine two tables with different number of rows and without any related fields:
SELECT a.*, b.* FROM table1 a, table2 b;
Now my problem is that in my case I cannot change the value of the FROM.
Example I have this Query:
SELECT * FROM table1;
I cannot change that to:
SELECT * FROM table2;
At most, I can only add statements after FROM table_name LEFT JOIN somedefaulttable ON somedefaulttable2.id = somedefaulttable .id_c. (I forgot to add this important detail, I can only add custom queries after this line, I cannot remove this predetermined LEFT JOIN as this is system generated) The reason for this is because I am restricted by the CRM I am using, and I cannot edit the default select value but I can add additional custom queries after the said statement.
Now what my main problem here is that I need to combine a different table in my Query and I cannot use join as they don't have any common values and their number of rows are also different, I also tried using JOIN before to no avail, and thus decided to try using a different approach such as merging the two tables.
This is the link to my previous question where I was using JOIN to achieve my goal of combining the tables. In this link, you can see that I want to combine Table A and Table 4 but I cannot do so with JOIN as they have a different number of rows and that I am limited in changing my current Query to fit the posted answer.
Table A.
id | name | deleted | amount | due_date | status
1 | a | 0 | 10 | 2016-07-18 | Unpaid
2 | b | 0 | 20 | 2016-07-19 | Unpaid
3 | c | 0 | 15 | 2016-07-18 | Unpaid
Table B
id | name | due_date | status
1 | a | | Unpaid
2 | b | | Unpaid
3 | c | | Unpaid
4 | d | 2016-07-19 | Unpaid
Table C
id | table_d_id | table_a_id
1 | 1 | 1
2 | 2 | 2
3 | 3 | 3
Table D
id |
1
2
3
Try this for (inner) joining two tables without a JOIN Statement.
SELECT a.x, a.y, b.x, b.y FROM table1 a, table2 b WHERE a.x = b.x
What I do not understand is, how different numbers of rows affect the requested solution.
i have created a link of one to many between the tables
with your example and number of rows you inserted you should try this:
SELECT TableC.*
FROM TableB, TableD INNER JOIN (TableA INNER JOIN TableC ON TableA.ID = TableC.table_a_id) ON TableD.ID = TableC.table_d_id;
this will bring all the records of table C
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have three tables:
Table 1 contains a primary key.
Table 2 contains a foreign key that is equal to primary key of table 1.
Table 3 contains a foreign key that is equal to primary key of table 2.
QUESTION: Is it possible to SELECT information from table 2 and 3 while only knowing the primary key of table 1? If so please give a brief example of the SELECT QUERY. I have tried doing an Inner join but got a syntax error.
Yes you can.
Example:
table_a table_b table_c
_______________ _______________ _______________
| id | name | | id | gender | | id | age |
|------+--------| |------+--------| |------+--------|
| 1 | sam | | 1 | m | | 1 | 18 |
|------+--------| |------+--------| |------+--------|
| 2 | ana | | 2 | f | | 2 | 22 |
|------+--------| |------+--------| |------+--------|
In order to get the following result:
_________________________________
| id | name | gender | age |
|------+--------+--------+--------|
| 1 | sam | m | 18 |
|------+--------+--------+--------|
| 2 | ana | f | 22 |
You could use the following SQL statement:
SELECT a.id, a.name, b.gender, c.age
FROM table_a AS a
LEFT JOIN table_b AS b
ON a.id = b.id
LEFT JOIN table_c AS c
ON a.id = c.id
P.S.: only answered this to do the ascii art xD!
Table: team
id | name
---------
1 | team a
2 | team b
3 | team c
Table: event
home & away are foreign key of team
id | home | away
----------------
1 | 2 | 3
2 | 1 | 2
3 | 3 | 1
What I want to get:
id | home | away
------------------
1 | team b | team c
2 | team a | team b
3 | team c | team a
Can anyone please teach me how to write the query to get the latest table based on the structure of this 2 tables. Thanks.
You need to join twice:
select e.id, th.name as home, ta.name as away
from event e join
team th
on e.home = th.id join
team ta
on e.away = ta.id;
Note that the two instances of team in the from clause have different table aliases. That makes it possible to distinguish between those references when referencing columns.
Hi I have 2 table Offense table and User_jobs table
offense table:
crime_id |crime_type |casenumber|
---------+-----------+----------+
1 | 3 |1 |
2 | 3 |1 |
1 | 3 |2 |
12 | AA |2 |
user_jobs table:
casenumber |disposal_status |
-----------+----------------+
1 | yes |
1 | yes |
2 | no |
2 | no |
what i want is to count the number of rows with the same combination say crime_id=1 and crime_type= 3 but these must have a disposal status of yes in the user_jobs table.
i want to do this in mysql. pliz help
sorry but i am new to mysql. i now want to display the real names of those id not the id themselves.
the tables with these IDs are crime_category and Crime_type Crime_catgory
table:
category |crime_id |
-----------+----------------+
theft | 1 |
murder | 2 |
rape | 3 | 2 |
no |
Crime_type table:
Crime_type |id |
---------------+----------------+
administrative | yes |
criminal | yes |
You can do this with a simple inner join and an aggregate function:
select
o.crime_id,
o.crime_type,
count(*)
from
offence o
join user_jobs uj
on o.casenumber=uj.casenumber
where
uj.disposal_status='Yes'
group by
o.crime_id,
o.crime_type
This will pick up distinct combinations of the first two columns joined as they should tot he jobs table and only where the disposal_status is equal to 'Yes'
Edit: You would probably do really well to have a read of this Q&A that I put together for exactly this sort of situation - where I give you the code for it, but would like to explain this is a lot more detail. The Q&A explains why this type of thing (and many many others) work and how they do so:
How can an SQL query return data from multiple tables
Edit 2:
select
o.crime_id,
o.crime_type,
ct.category,
count(*)
from
offence o
join user_jobs uj
on o.casenumber=uj.casenumber
join crime_type ct
on o.crime_type=ct.crime_id
where
uj.disposal_status='Yes'
group by
o.crime_id,
o.crime_type,
ct.category,