AllNews Article
------ -----------
|id | --> | article_id|
------ -----------
| date | | views |
------ -----------
| id |
-----------
All I want is to get sum of views for all articles between two dates for each date
articles = []
all_news = AllNews.query.filter(AllNews.date.between(date1, date2)).all()
for i in all_news:
articles += Article.query.filter_by(article_id=i.id).all()
Dunno what to do after this. How to filter articles by date and get sum of views for each date?
Firstly, think it out in SQL. That would be a simple join, like
SELECT AllNews.id, SUM(Article.views) FROM AllNews, Article WHERE
AllNews.id = Article.article_id GROUP BY AllNews.id
right?
Now, I am not familiar with flask-sqlalchemy, but from what I gather from
the docs you would do something like:
from yourapplication import db
q = db.session.query(AllNews.id, func.sum(Article.views)).filter(
AllNews.id == Article.article_id,
).group_by(AllNews.id)
for (article_id, count) in q:
pass
Related
I have a table "story" as follows:
+++++++++++++++++++++++++++++++++++++++++++
| id | keywords |
+++++++++++++++++++++++++++++++++++++++++++
| 1 | romance,movie,drama |
| 2 | newmovie,horor,comedy |
| 3 | movie,scifi |
| 4 | newmovie,romance,drama,asia |
| 5 | kids,movie |
+++++++++++++++++++++++++++++++++++++++++++
I try a query to search 'movie' in keywords field as below:
SELECT id FROM story WHERE keywords LIKE '%movie%'
and the result is
1,2,3,4,5
but in this case I wanted the result is 1,3,5 (field value with newmovie not include). Can someone help me how the query to do it?
Thank you for your help..
You want to use find_in_set like this:
SELECT id FROM story WHERE find_in_set('movie', keywords) > 0;
Though you should really consider normalizing your table structure.
In this case, you could've stored one single keyword in one row, then the query would be simply like:
select id from story where keyword = 'movie';
and that would've been the end of it. No heavy string functions needed.
You could have structure like this:
keywords(id, name);
story(story_id,. . ., keyword_id);
then, you could simply join the two like this:
select s.*
from story s
inner join keywords k on s.keyword_id = k.id
where k.name = 'movie';
Your problem is that "newmovie" can be found by "%movie%" you need only search "movie".
I have three tables, sketched below. The showid and actorid from the Shows-Actors table comes from the id column in the Shows and Actors table. They combine to form a composite primary key - An actor can be in many shows, and shows can have many different actors.
_______ _______ _______________
|Actors | |Shows| |Shows-Actors |
--------- --------- --------------
|id|name| |id|name| |actorid|showid|
--------- --------- ---------------
|1 |Bob | |1 |GoT | | 1 |1 |
--------- --------- ----------------
|2 |Lou| |2 |TWD | | 1 |2 |
--------- --------- ----------------
On one site page I want to display a list of all actors names, as well as all the shows they appear in. E.g. With the data above, The page would display:
1. Bob. Shows: GoT, TWD.
2. Lou. Shows: ...etc.
Currently I have the list of actors displaying correctly, But i'm stuck on how I'd use the composite PK to get a list of all the shows each actor has appeared in.
Here is what I have so far, in terms of code relevant to this question.
$query = "SELECT * FROM `Shows-Actors`
INNER JOIN `Actors`
ON `Actors`.`id` = `Shows-Actors`.`acid`
ORDER BY `Actors`.`name` ASC";
$result = mysqli_query($link, $query) or die(mysqli_error($link));
while($actor = mysqli_fetch_assoc($result))
{
print '<tr>';
print '<td>'.$actor['name'].'</td>';
//Insert all shows that actor appears in here
print '</tr>';
}
All help would be appreciated.
You could just join the Shows table like this:
SELECT
Actors.`name`,
Shows.`name`,
FROM `Shows-Actors`
INNER JOIN `Actors`
ON `Actors`.`id` = `Shows-Actors`.`acid`
INNER JOIN Shows
ON Shows.id = `Shows-Actors`.showid
ORDER BY `Actors`.`name` ASC
I have three tables for tagging. The first one is the question table that has a list of question with certain ID. The second one is the tag table that has a list of tag name with certain ID. And the third one is the question_tag table, a collection of question to a tag. A question that has multiple tag means multiple rows in question_tag, I thought of storing an serialized array into the question_tag table but it's in general not a good idea to store array inside of a SQL database.
Below is the schema. Arrow denoting foreign key.
-------------------
----------------- | question_tag |
| question | ------------------- ------------------
----------------- | question_tag_ID | | tag |
| question_ID | ---> | question_ID | ------------------
----------------- | tag_ID | <----- | tag_ID |
------------------- | tag_name |
------------------
I want to make a query that will output this table below.
----------------------------------------------------
| question_id | tag_name |
----------------------------------------------------
| 1 | algebra, calculus, differentiation |
| 2 | calculus |
| 3 | algebra, trigonometry |
----------------------------------------------------
How do I manage to do this query? I thought about SELECTING from question and JOINING a temporary table of SELECT tag.tag_name FROM tag WHERE question_tag.tag_ID = tag.tag_ID, but how do I output this RIGHT column (tag_name) like the table above.
I would really appreciate it if you can help me with this SQL query, I am guessing that I need to do a nesting SELECT query for the RIGHT (tag_name) column, then JOIN it to the question_table. But I am not sure how to the nesting of SELECT query.
This is what I have come up with:
SELECT * FROM question as Q LEFT JOIN (SELECT T.tag_name FROM tag as T WHERE T.tag_id IN (SELECT QT.tag_id FROM question_tag AS QT WHERE QT.question_ID = Q.id)) AS QT_T
You'll need to aggregate and concatenate. Please check out some of the related questions:
Does T-SQL have an aggregate function to concatenate strings?
Implode type function in SQL Server 2000?
Concatenate row values T-SQL
How to use GROUP BY to concatenate strings in MySQL?
Aggregate String Concatenation in Oracle 10g
Create a delimitted string from a query in DB2
How to concatenate strings of a string field in a PostgreSQL 'group by' query?
UPDATE
While I don't have a mysql DB to test this on, going off of one of the above links (with the knowledge this is mysql), I've designed the following query:
SELECT
qt.question_id,
GROUP_CONCAT(t.tag_name SEPARATOR ',')
FROM question_tag qt
LEFT JOIN tag t ON t.tag_id = qt.tag_id
GROUP BY qt.question_id;
Please try this out and let me know if it works.
I am going to store user Likes into database. But I am not sure which one of these 2 methods is better:
in my situation, users can like Posts, Comments and Groups. something like Facebook.
Assume there are 10 million likes for : Posts, Comments and Groups
Method A:
Create a Like table, and add a LikeType field in it:
+--------+----------+--------+
| likeID | LikeType | userID |
+--------+----------+--------+
| 1 | 1 | 1 | // User 1 liked a post
+--------+----------+--------+
| 2 | 2 | 1 | // User 1 liked a comment
+--------+----------+--------+
| 3 | 3 | 1 | // User 1 liked a group
which LikeType includes : 1,2,3
1 = Posts, 2= Comments, 3= Groups
Method B:
Create three separated tables for each one of Posts, Comments and Groups.
in Method A,
Because there are too many likes and it needs an extra condition ( Where status = 1, or 2, or 3 ) to get a Post, Comment or Group likes, which method is better?
UPDATED POST:
users
uid // PK
---------------------------------------
itemTypes
typeID // PK
typeText // comments, groups, posts
---------------------------------------
--------------------------------------- +
posts |
id // PK |
typeID // 1 |
... |
--------------------------------------- +
comments |
id // PK |
typeID // 2 |
... |
--------------------------------------- + Items
groups |
id // PK |
typeID // 3 |
... |
--------------------------------------- +
photos |
id // PK |
typeID // 4 |
... |
--------------------------------------- +
---------------------------------------
likes
uid // FK to user id
itemid // FK to posts, groups, photos, comments id
itemType // FK to itemsTypes.typeID
// select post #50 likes
SELECT count(*) FROM likes WHERE itemid = 50 and itemType = 1
// select comment #50 of user #2
SELECT * FROM likes WHERE itemid = 50 and uid = 2 and itemType = 2
is this a good schema ?
I don't like either of your methods. I would go more normalized. I would have a table for item types, such as comments, groups, posts, etc. Then I would have a table for items. It would have an ItemId as the PK and a FK reference to item types. There would also be a users table. Finally, the likes table would be a many to many relationship between items and users.
As Jan Doggen said, what you're doing with the information is an important consideration. In particular, if you want to be able to ask the question "what things does a given user like", then you will benefit from having all the data in one table -- otherwise, you'd have to have three separate queries to answer that question.
For the case of the question "which people like a given thing", the performance difference between the single-table model and the multiple-table model should be relatively small if your tables are properly indexed (with an index on likeID/likeType, in this case). The multiple-table model will make your application logic more complex, and will be harder to extend in the future when you want to add other things a user might be able to like.
Sorry for the confusing question, I will try to clarify.
I have an SQL database ( that I did not create ) that I would like to write a query for. I know very little about SQL, so it is hard for me to even know what to search for to see if this question has already been asked, so sorry if it has. It should be an easy solution for those in the know.
The query I need is for a search I would like to perform on an existing data management system. I want to return all the documents that a given user has NOT signed-off on, as indicated by rows in a signoffs_table. The data is stored similarly to as follows: (this is actually a simplification of the actual schema and hides several LEFT JOINS and columns)
signoffs_table:
| id | user_id | document_id | signers_list |
The naive solution I had was to do something like the following:
SELECT document_id from signoffs_table WHERE (user_id <> $BobsID) AND signers_list LIKE "%Bob%";
This works if ONLY Bob signs the document. The problem is that if Bob and Mary have signed the document then the table looks like this:
signoffs_table:
-----------------------------------------------
| id | user_id | document_id | signers_list |
-----------------------------------------------
| 1 | 10 | 100 | "Bob,Mary,Jim" |
| 2 | 20 | 100 | "Bob,Mary,Jim" |
-----------------------------------------------
(assume Bob's ID = 10 and mary's ID = 20).
and then when I do the query then I get back document_id 100 (in row #2) because there is a row that Bob should have signed, but did not.
Is what I am trying to do possible with the given database structure? I can provide more details if needed. I am not sure how much details are needed.
I guess this query is what you mean:
SELECT document_id FROM signoffs_table AS t1
WHERE signers_list LIKE "%Bob%"
AND NOT EXISTS (
SELECT 1 FROM signoffs_table AS t2
WHERE (t2.user_id = $BobsID) AND t2.document_id = t1.document_id )
I believe your design is incorrect. You have a many-to-many relationship between documents and signers. You should have a junction table, something like:
ID DocumentID SignerID