I have a custom CMS built on Yii2 and I need "related posts" functionality. The problem is I don't fully understand how to build an "appropriate" MySQL query. The way I see it:
we have Post X with tag A, tag B, tag C...
we cross-reference all the Posts under tags A, B, C...
we obtained N posts and we need to sort them from the most referenced to the least referenced
profit
But I don't know how to put all this into MySQL. everything I google'd is not working.
any help will be appreciated.
UPD2. Unfortunately, the suggestion by #Joe Miller won't work.
UPD. tables structure
post
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| title | varchar(160) | YES | | NULL | |
| slug | varchar(160) | YES | | NULL | |
| content | text | YES | | NULL | |
| cover_image_url | text | YES | | NULL | |
| created_at | int(11) | YES | | NULL | |
| updated_at | int(11) | YES | | NULL | |
| author_id | int(11) | YES | | NULL | |
| status | tinyint(1) | YES | | NULL | |
| category_id | int(11) | YES | | NULL | |
| access_type | tinyint(1) | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
post_tags
+---------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------+---------+------+-----+---------+-------+
| post_id | int(11) | NO | PRI | NULL | |
| tag_id | int(11) | NO | PRI | NULL | |
+---------+---------+------+-----+---------+-------+
tags
+-------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(45) | YES | | NULL | |
| description | varchar(200) | YES | | NULL | |
| slug | varchar(45) | YES | | NULL | |
+-------------+--------------+------+-----+---------+----------------+
Related
I have created a realistic table set using the ER model for MySQL. I am attempting to do joins, but seem to either be missing something, or not doing them correctly in order to produce NULL values. Below are my created tables:
+----------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------+-------------+------+-----+---------+-------+
| FilmNumber | char(3) | NO | PRI | NULL | |
| FilmName | varchar(60) | YES | | NULL | |
| OpeningDate | varchar(20) | YES | | NULL | |
| TopBilledActor | char(60) | YES | | NULL | |
| Genre | varchar(20) | YES | | NULL | |
+----------------+-------------+------+-----+---------+-------+
+------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+-------------+------+-----+---------+-------+
| CriticSiteNumber | char(3) | NO | PRI | NULL | |
| CriticSiteName | varchar(30) | YES | | NULL | |
| CriticName | char(50) | YES | | NULL | |
+------------------+-------------+------+-----+---------+-------+
+------------------+---------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+---------+------+-----+---------+-------+
| FilmNumber | char(3) | YES | MUL | NULL | |
| CriticSiteNumber | char(3) | YES | MUL | NULL | |
| OverallScore | int(5) | YES | | NULL | |
+------------------+---------+------+-----+---------+-------+
3 rows in set (0.00 sec)
My question is, what type of join query would I need in order to produce NULL values, or does something in my table need to be modified because each of the queries I attempt do not return those values.
I have following table called transactions and I want to add foreign key using column account_id. But when I execute the query (see below) 0 rows affected. I am not getting what is wrong with the query.
I have two tables called transactions and accounts. Accounts table has an id as primary key and an account has_many transactions.
transactions table
+---------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account_number | int(11) | YES | | NULL | |
| m_number | varchar(255) | YES | | NULL | |
| registration_number | varchar(255) | YES | | NULL | |
| page_number | varchar(255) | YES | | NULL | |
| entry_date | datetime | YES | | NULL | |
| narration | varchar(255) | YES | | NULL | |
| voucher_number | varchar(255) | YES | | NULL | |
| debit_credit | float | YES | | NULL | |
| profit | float | YES | | NULL | |
| account_code | int(11) | YES | | NULL | |
| balance | float | YES | | NULL | |
| branch | varchar(255) | YES | | NULL | |
| account_id | int(11) | YES | MUL | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+---------------------+--------------+------+-----+---------+----------------+
16 rows in set (0,01 sec)
mysql> ALTER TABLE transactions ADD FOREIGN KEY (account_id) REFERENCES accounts(id);
Query OK, 0 rows affected (0,03 sec)
Records: 0 Duplicates: 0 Warnings: 0
accounts table
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| account_number | int(11) | YES | | NULL | |
| account_code | int(11) | YES | | NULL | |
| branch | varchar(255) | YES | | NULL | |
| name | varchar(255) | YES | | NULL | |
| father_name | varchar(255) | YES | | NULL | |
| nic_number | varchar(255) | YES | | NULL | |
| mohalla | varchar(255) | YES | | NULL | |
| village | varchar(255) | YES | | NULL | |
| nominee | varchar(255) | YES | | NULL | |
| relationship | varchar(255) | YES | | NULL | |
| opening_balance | float | YES | | NULL | |
| opening_date | datetime | YES | | NULL | |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
After running the query shouldn't the column say F_K or something like PRI ?
Any help would be great. Thanks!
My database structure contains:
actions
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| placement_id | int(11) | YES | MUL | NULL | |
| lead_id | int(11) | NO | MUL | NULL | |
+--------------+--------------+------+-----+---------+----------------+
placements
+--------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| publisher_id | int(11) | YES | MUL | NULL | |
| name | varchar(255) | NO | | NULL | |
| status | tinyint(1) | NO | | NULL | |
+--------------+--------------+------+-----+---------+----------------+
leads
+---------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+---------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| status | varchar(255) | YES | | NULL | |
+---------+--------------+------+-----+---------+----------------+
I would like to retrieve a number of statuses per each placement (groupped):
| placement_id | placement_name | count
+--------------+----------------+-------
| 123 | PlacementOne | 12
| 567 | PlacementTwo | 15
I tried countless times and every query I wrote seems dumb, so I won't even post them here. I'm hopeless. An well commented query (so I can learn) would be much appreciated.
select a.placement_id, p.name as placement_name, count(l.status)
from actions a
inner join placements p on p.id = a.placement_id
inner join leads l on l.id = a.lead_id
group by a.placement_id, p.name
Im using the django comment system and want to fetch only the FIRST comments on posts.
mysql> desc django_comments ;
+-----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| content_type_id | int(11) | NO | MUL | NULL | |
| object_pk | longtext | NO | | NULL | |
| site_id | int(11) | NO | MUL | NULL | |
| user_id | int(11) | YES | MUL | NULL | |
| user_name | varchar(50) | NO | | NULL | |
| user_email | varchar(75) | NO | | NULL | |
| user_url | varchar(200) | NO | | NULL | |
| comment | longtext | NO | | NULL | |
| submit_date | datetime | NO | | NULL | |
| ip_address | char(15) | YES | | NULL | |
| is_public | tinyint(1) | NO | | NULL | |
| is_removed | tinyint(1) | NO | | NULL | |
+-----------------+--------------+------+-----+---------+----------------+
my posts are content_type_id = 48.
I want know the user that left the first comment (min submit_date) of each post (object_pk).
Is there a "django" way to do this?
Or need to use raw SQL?
Use a function like this:
def get_first_comment(post):
from django.contrib.comments.models import Comment
from django.contrib.contenttypes.models import ContentType
ct = ContentType.objects.get_for_model(post)
first_comments = Comment.objects.filter(
content_type=ct,
object_id=post.pk,
).order_by("submit_date")
if first_comments:
return first_comments[0]
return None
It loads the content type for your model instance and then filters comments by the content type and object id sorting them by submit date. Then it takes the first comment if a query is not empty.
I'm now trying to populate my 'testMatch' table (below) with data from my unormalised 'summary' table:
TESTMATCH TABLE
+------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+-------+
| match_id | int(11) | NO | PRI | NULL | |
| match_date | date | YES | | NULL | |
| ground | varchar(50) | YES | MUL | NULL | |
| homeTeam | varchar(100) | YES | MUL | NULL | |
| awayTeam | varchar(100) | YES | MUL | NULL | |
| matchResult | varchar(100) | YES | MUL | NULL | |
| manOfMatch | varchar(30) | YES | | NULL | |
| homeTeam_captain | int(10) | YES | MUL | NULL | |
| homeTeam_keeper | int(10) | YES | MUL | NULL | |
| awayTeam_captain | int(10) | YES | MUL | NULL | |
| awayTeam_keeper | int(10) | YES | MUL | NULL | |
+------------------+--------------+------+-----+---------+-------+
There is no problem populating match_id -----> manOfMatch - it is 'homeTeam_captain', 'homeTeam_keeper', 'awayTeam_captain' and 'awayTeam_keeper' that i'm having problems bringing in.
SUMMARY TABLE
mysql> DESCRIBE SUMMARY;
+-----------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+--------------+------+-----+---------+-------+
| matchID | int(11) | NO | PRI | NULL | |
| Test | int(11) | YES | | NULL | |
| matchDate | date | YES | | NULL | |
| Ground | varchar(50) | YES | | NULL | |
| HomeTeam | varchar(100) | YES | | NULL | |
| AwayTeam | varchar(100) | YES | | NULL | |
| matchResult | varchar(50) | YES | | NULL | |
| MarginRuns | int(11) | YES | | NULL | |
| MarginWickets | int(11) | YES | | NULL | |
| ManOfMatch | varchar(40) | YES | | NULL | |
| HomeTeamCaptain | varchar(30) | YES | | NULL | |
| HomeTeamKeeper | varchar(30) | YES | | NULL | |
| AwayTeamCaptain | varchar(30) | YES | | NULL | |
| AwayTeamKeeper | varchar(30) | YES | | NULL | |
+-----------------+--------------+------+-----+---------+-------+
I need to somehow select the data from summary, get the corresponding player_id and input the player_id into my 'testMatch'. Player table below:
PLAYERS TABLE
mysql> describe players;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| player_id | int(11) | NO | PRI | NULL | auto_increment |
| player_surname | varchar(30) | YES | | NULL | |
| team | varchar(100) | YES | MUL | NULL | |
+----------------+--------------+------+-----+---------+----------------+
So to clarify, eg. I want to select homeTeam_captain data FROM summary table BUT not the name, I want the corresponding player_id instead.
I assume I need to use some sort of join/subqueries to get this done... i've tried selecting with:
select matchID, player_id, player_surname, team from players p, summary s
where
s.hometeamcaptain = p.player_surname ORDER BY matchID;
but this brings back 73 rows and there should only be 65 (65 matches).
I hope this makes sense and thanks for your help!!
Theresa
Are there overlapping names? If so, also assure that the teams correspond (add s.HomeTeam = p.team to the where block). If there are players with the same name in one team, you will have to solve these conflicts manually.
To select all the keepers/captains at once, you need left outer joins. I guess it will be one join per player, so you have to join the same table 4 times.
Once you've selected the right data, you can insert it in your testMatch table with INSERT ... SELECT.