only select 5 newest posts - sql

I have a database table containing the news on my site. It's divided into to group - team and board. I connect using LINQ.
The team news are being shown on all pages and the board news are being shown only on the front page.
I have tried this, because i want the 5 newest entires about team to be shown:
var query = from esh in gr.nyheders
where esh.typeBeskrivelse.Equals("team") && esh.id > ((from es in gr.nyheders where esh.typeBeskrivelse.Equals("team") select es.id).Max() - 5)
orderby esh.dato descending
select esh;
But it only shows two, since the 2 team news have ID <= 5.
how do I select the 5 newest team posts??

There is a Take method, that can be given a number of records to return. Take a look at http://msdn.microsoft.com/de-de/library/bb503062.aspx for more information

Related

Sql Left or Right Join One To Many Pagination

I have one main table and join other tables via left outer or right outer outer join.One row of main table have over 30 row in join query as result. And I try pagination. But the problem is I can not know how many rows will it return for one main table row result.
Example :
Main table first row result is in my query 40 rows.
Main table second row result is 120 row.
Problem(Question) UPDATE:
For pagination I need give the pagesize the count of select result. But I can not know the right count for my select result. Example I give page no 1 and pagesize 50, because of this I cant get the right result.I need give the right pagesize for my main table top 10 result. Maybe for top 10 row will the result row count 200 but my page size is 50 this is the problem.
I am using Sql 2014. I need it for my ASP.NET project but is not important.
Sample UPDATE :
it is like searching an hotel for booking. Your main table is hotel table. And the another things are (mediatable)images, (mediatable)videos, (placetable)location and maybe (commenttable)comments they are more than one rows and have one to many relationship for the hotel. For one hotel the result will like 100, 50 or 10 rows for this all info. And I am trying to paginate this hotels result. I need get always 20 or 30 or 50 hotels for performance in my project.
Sample Query UPDATE :
SELECT
*
FROM
KisiselCoach KC
JOIN WorkPlace WP
ON KC.KisiselCoachId = WP.WorkPlaceOwnerId
JOIN Album A
ON KC.KisiselCoachId = A.AlbumId
JOIN Media M
ON A.AlbumId = M.AlbumId
LEFT JOIN Rating R
ON KC.KisiselCoachId = R.OylananId
JOIN FrUser Fr
ON KC.CoachId = Fr.UserId
JOIN UserJob UJ
ON KC.KisiselCoachId = UJ.UserJobOwnerId
JOIN Job J
ON UJ.JobId = J.JobId
JOIN UserExpertise UserEx
ON KC.KisiselCoachId = UserEx.UserExpertiseOwnerId
JOIN Expertise Ex
ON UserEx.ExpertiseId = Ex.ExpertiseId
Hotel Table :
HotelId HotelName
1 Barcelona
2 Berlin
Media Table :
MediaID MediaUrl HotelId
1 www.xxx.com 1
2 www.xxx.com 1
3 www.xxx.com 1
4 www.xxx.com 1
Location Table :
LocationId Adress HotelId
1 xyz, Berlin 1
2 xyz, Nice 1
3 xyz, Sevilla 1
4 xyz, Barcelona 1
Comment Table :
CommentId Comment HotelId
1 you are cool 1
2 you are great 1
3 you are bad 1
4 hmm you are okey 1
This is only sample! I have 9999999 hotels in my database. Imagine a hotel maybe it has 100 images maybe zero. I can not know this. And I need get 20 hotels in my result(pagination). But 20 hotels means 1000 rows maybe or 100 rows.
First, your query is poorly written for readability flow / relationship of tables. I have updated and indented to try and show how/where tables related in hierarchical relativity.
You also want to paginate, lets get back to that. Are you intending to show every record as a possible item, or did you intend to show a "parent" level set of data... Ex so you have only one instance per Media, Per User, or whatever, then once that entry is selected you would show details for that one entity? if so, I would do a query of DISTINCT at the top-level, or at least grab the few columns with a count(*) of child records it has to show at the next level.
Also, mixing inner, left and right joins can be confusing. Typically a right-join means you want the records from the right-table of the join. Could this be rewritten to have all required tables to the left, and non-required being left-join TO the secondary table?
Clarification of all these relationships would definitely help along with the context you are trying to get out of the pagination. I'll check for comments, but if lengthy, I would edit your original post question with additional details vs a long comment.
Here is my SOMEWHAT clarified query rewritten to what I THINK the relationships are within your database. Notice my indentations showing where table A -> B -> C -> D for readability. All of these are (INNER) JOINs indicating they all must have a match between all respective tables. If some things are NOT always there, they would be changed to LEFT JOINs
SELECT
*
FROM
KisiselCoach KC
JOIN WorkPlace WP
ON KC.KisiselCoachId = WP.WorkPlaceOwnerId
JOIN Album A
ON KC.KisiselCoachId = A.AlbumId
JOIN Media M
ON A.AlbumId = M.AlbumId
LEFT JOIN Rating R
ON KC.KisiselCoachId = R.OylananId
JOIN FrUser Fr
ON KC.CoachId = Fr.UserId
JOIN UserJob UJ
ON KC.KisiselCoachId = UJ.UserJobOwnerId
JOIN Job J
ON UJ.JobId = J.JobId
JOIN UserExpertise UserEx
ON KC.KisiselCoachId = UserEx.UserExpertiseOwnerId
JOIN Expertise Ex
ON UserEx.ExpertiseId = Ex.ExpertiseId
Readability of a query is a BIG help for yourself, and/or anyone assisting or following you. By not having the "on" clauses near the corresponding joins can be very confusing to follow.
Also, which is your PRIMARY table where the rest are lookup reference tables.
ADDITION PER COMMENT
Ok, so I updated a query which appears to have no context to the sample data and what you want in your post. That said, I would start with a list of hotels only and a count(*) of things per hotel so you can give SOME indication of how much stuff you have in detail. Something like
select
H.HotelID,
H.HotelName,
coalesce( MedSum.recs, 0 ) as MediaItems,
coalesce( LocSum.recs, 0 ) as NumberOfLocations,
coalesce( ComSum.recs, 0 ) as NumberOfLocations
from
Hotel H
LEFT JOIN
( select M.HotelID,
count(*) recs
from Media M
group by M.HotelID ) MedSum
on H.HotelID = MedSum.HotelID
LEFT JOIN
( select L.HotelID,
count(*) recs
from Location L
group by L.HotelID ) LocSum
on H.HotelID = LocSum.HotelID
LEFT JOIN
( select C.HotelID,
count(*) recs
from Comment C
group by C.HotelID ) ComSum
on H.HotelID = ComSum.HotelID
order by
H.HotelName
--- apply any limit per pagination
Now this will return every hotel at a top-level and the total count of things per the hotel per the individual counts which may or not exist hence each sub-check is a LEFT-JOIN. Expose a page of 20 different hotels. Now, as soon as one person picks a single hotel, you can then drill-into the locations, media and comments per that one hotel.
Now, although this COULD work, having to do these counts on an every-time query might get very time consuming. You might want to add counter columns to your main hotel table representing such counts as being performed here. Then, via some nightly process, you could re-update the counts ONCE to get them primed across all history, then update counts only for those hotels that have new activity since entered the date prior. Not like you are going to have 1,000,000 posts of new images, new locations, new comments in a day, but of 22,000, then those are the only hotel records you would re-update counts for. Each incremental cycle would be short based on only the newest entries added. For the web, having some pre-aggregate counts, sums, etc is a big time saver where practical.

Top [TAG] Answerers in the Last 30 days for a given location

How would you put together a SQL query for data.stackexchange that will display the most active users (in terms of answers given) for a tag in a given location?
EG. something similar to the top 30 listed here https://stackoverflow.com/tags/ruby-on-rails-3/topusers but location specific.
So top Ruby Answerers in the last 30 days in Berlin etc
Thanks!
So, after looking at the database schema this is the query I came up with.
-- Top 10 Ruby Answerers in the last 30 days in Berlin based on score
select top 10
u.displayname,
number_of_answers = count(*),
total_score = sum(p.score)
from
users u
join
posts p on p.owneruserid = u.id -- joined to get answer posts
join
posts pp on p.parentid = pp.id -- post parent is the question
join
posttags pt on pt.postid = pp.id -- tags for post parent
join
tags t on t.id = pt.tagid -- tags for tag name
where
t.tagname like '%ruby%' -- tags to filter for
and -- includes everything ruby inc. rails
p.creationdate > (getdate()-30) -- past 30 days
and
u.location like '%Berlin%' -- locations differ in format
group by
u.displayname
order by
3 desc; -- order by total score for "best" answerers
-- order by 2 (count) to get most active
I'm not an expert in the data explorer schema so it's possible that the query isn't quite correct and there are some caveats: the date filter applies to the question and not the answer so it's possible that there are users with more answers in the last 30 days overall if they have answered older questions, and also, the location is a really unreliable field as many users haven't specified location at all. It's probably as close as it's possible to get though.
The data explorer isn't that hard to use - experiment a bit with it and you'll realize how the tables are connected. It's a good exercise :)
Here's the query

Sorting a list of objects by another list of objects VB.NET LINQ

So, here's a simplified version of the situation:
I have Gyms in a database:
Gym: GymID, Name
GymAmenities: GymID, AmenityID
Amenities: AmenityID
So a Gym, can have 0 to many "Amenities". Along comes a user who prioritizes amenities that are important to him or her:
UserPrefAmenities: UserID, AmenityID, Ranking
Now when searching for a gym in a zip code, I want the search results to be in order of the user preferred amenities in order of rank...
gyms = (From g In db.Gyms Where g.Zip = thisRequest.Zip Order By g.GymAmenitys.Contains(From upa In thisUser.UserPrefAmenitys Order By upa.Rank)).ToList
Or something like that...
*note that running the above results in:
Unable to create a constant value of type 'UserPrefAmenity'. Only
primitive types or enumeration types are supported in this context.
I think this should do it:
gyms = (
From g In db.Gyms
Where g.Zip = thisRequest.Zip
Order By If((From ga in g.GymAmenitys
Join upa In db.UserPrefAmenitys On ga.AmenityID
Equals upa.AmenityID
Where upa.UserID = thisUser.UserID
Order By upa.Rank Descending
Select CType(upa.Rank, integer?)).FirstOrDefault(), 0)
).ToList
The idea is that you find a user's highest ranked UserPrefAmenity that shares an AmenityID of the Gym's amenities. If the user has no matching UserPrefAmenity the value 0 is taken as rank.

SQLite Select first row per category

I'm trying to write a mutli-language blog software using Python and sqlite and I'm struggeling with making an sql query elegant.
I've got all articles of the blog in two tables:
articleindex (contains most of the metadata of the articles like the URL, etc)
articlecontent (contains well, the content of the article, and a flag for the language, and when this specific translation was written (aka, the date))
I now try to select all articles ordered by date and by language. This if for the main view of the blog. It should list all articles in chronological order, regardless of the language they are in, but only once (I don't want to have the english version of an article below or above the german version) - if there are multiple translations the main view should contain the default language (english) if it exists. If there is no english version it should show the german version (if it exits) if there is no german version it shall show the esperanto version, etc.
Of course I can do this in python, select all articles, and skip a record if the another version of the article has already been written. However this seemed inelegant. I'd rather liked SQLite to return the data as need.
So far I could manage to get the data in the order I want, I just don't seem to be able to eliminate the unneeded records.
Here is the table structure:
CREATE TABLE articleindex (id INTEGER PRIMARY KEY,
category text,
translationid text,
webid text) `
CREATE TABLE articlecontent (id INTEGER PRIMARY KEY,
articleindexid INTEGER,
lang text,
content text,
date text) `
I came up with this query, which gives me the right order, but has duplicates in it:
SELECT * FROM articlecontent AS ac LEFT JOIN articleindex AS ai
ON ac.articleindexid = ai.id ORDER BY ac.date DESC, CASE ac.lang
WHEN "en" THEN 0
WHEN "de" THEN 1
WHEN "eo" THEN 2
END
This results in the (shortend) output:
articleindexid. lang
21, en
21, de
12, en
12, de
8, en
8, de
2, en
2, de
2, eo
How do I skip for example the second record with the articleindexid 21 or 12?
Using search engines I came across suggestions about using Partitions, but it seems Sqlite doesn't support those. I also have difficulties for what to search for, so any suggestion is appreciated.
Thanks
Ben
I think you should create table for language priorities to use it instead of CASE in SQL statemens. For example
LANG_PRIORITY(lang text,Ord INTEGER) = (("en",0),("de",1),("eo",2))
Anyway in your current environment try to use the following query. The subquery with LIMIT 1 will select one row per DATE with higher priority:
SELECT * FROM articlecontent AS ac
LEFT JOIN articleindex AS ai
ON ac.articleindexid = ai.id
WHERE ac.id =
(
SELECT ID FROM articlecontent as ac2
WHERE ac.date=ac2.date
ORDER BY CASE ac2.lang
WHEN "en" THEN 0
WHEN "de" THEN 1
WHEN "eo" THEN 2
END
LIMIT 1
)
ORDER BY ac.date DESC

sqlzoo track join exercise

I've found a great site to practice sql - http://sqlzoo.net. my sql is very weak that is why i want to improve it by working on the exercises online. But i have this one problem that I cannot solve. can you please give me a hand.
3a. Find the songs that appear on more than 2 albums. Include a count of the number of times each shows up.
album(asin, title, artist, price, release, label, rank)
track(album, dsk, posn, song)
my answer is incorrect as i ran the query.
select a.song, count(a.song) from track a, track b
where a.song = b.song
a.album != b.album
group by a.song
having count(a.song) > 2
thanks in advance! :D
I realize this answer may be late but for future reference to anyone taking on this tutorial the answer is as such
SELECT track.song, count(album.title)
FROM album INNER JOIN track ON (album.asin = track.album)
GROUP BY track.song
HAVING count(DISTINCT album.title) > 2
Some things that my help you in your quest for this query is that what to group by is usually specified by the word each. As per the tip presented in the previous answers you want to select by distinct albums, SINCE it mentioned in the database description that album titles would be repeated when the two tables are joined
Your original answer is very close, with the GROUP BY and HAVING clause. What is wrong, is just that you don't need to join the track table against itself.
SELECT song, count(*)
FROM track
GROUP BY song
HAVING count(*) > 2
Another answer here uses COUNT(DISTNCT album), which is necessary only if a song can appear on an album more than once.
If they support nested querys, you can:
Select song, count(*)
from(
select a.song
from track a
group by a.song, a.album
having count(*) > 1
)
group by song
or(best way to write it)if they support this syntax:
select a.song, count(distinct a.album)
from track a
group by a.song
having count(distinct a.album) > 1