根据评论进行编辑
我有2个表帖子和类别。结构和样本数据如下:
POSTS
ID NAME DESCRIPTION CATEGORY_ID
-- ----------------- ------------------- -----------
1 For Song Lovers A post all about music 8
2 For Music Lovers About passion of music 8
3 I love songs Listing favourite songs 8
4 Rock Music ImagineDragon 6
5 Retro Music Old choice musical themes 7
CATEGORIES
ID NAME
-- -----------------
6 Artists
7 Entertainment
8 Music
我想以这样的方式对记录进行排序:
我希望得到的结果是(如果 keyword = music ):
OUTPUT
---------
Post ID#2
Post ID#5
Post ID#4
Post ID#1
Post ID#3
我已经能够编写5个查询并将其组合起来以获得唯一记录。但这不是优化的解决方案。这是我试过的:
(
SELECT "posts".* FROM "posts" INNER JOIN "categories" ON "categories"."id" = "posts"."category_id" WHERE posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%') AND categories.name iLIKE ('%music%')
+
SELECT "posts".* FROM "posts" WHERE posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%')
+
SELECT "posts".* FROM "posts" WHERE posts.name iLIKE ('%music%')
+
SELECT "posts".* FROM "posts" WHERE posts.description iLIKE ('%music%')
+
SELECT "posts".* FROM "posts" INNER JOIN "categories" ON "categories"."id" = "posts"."category_id" WHERE categories.name iLIKE ('%music%')
).uniq
我甚至尝试编写单个查询,但这并没有返回我想要的结果(明显的原因是我没有使用GROUP OR COUNT)
SELECT posts.* FROM posts INNER JOIN categories ON categories.id = posts.category_id
WHERE (
(posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%') AND categories.name iLIKE ('%music%'))
OR (posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%'))
OR (posts.name iLIKE ('%music%'))
OR (posts.description iLIKE ('%music%'))
OR (categories.name iLIKE ('%music%')))
请建议我如何使用上述SQL实现相同的目标。
环境详情:
数据库:PostgreSQL
版本:postgres(PostgreSQL)9.4.5
答案 0 :(得分:3)
据我所知,PostgreSQL支持布尔值,因此这应符合您的描述,按单独的列排序:
SELECT posts.* FROM posts INNER JOIN categories ON categories.id = posts.category_id
WHERE -- can be simplified to
LOWER(posts.name) iLIKE ('%music%')
OR LOWER(posts.description) iLIKE ('%music%')
OR LOWER(categories.name) iLIKE ('%music%')
ORDER BY -- FALSE probably sorts lower than TRUE, thus DESC
LOWER(posts.name) iLIKE ('%music%') DESC, posts.name,
LOWER(posts.description) iLIKE ('%music%') DESC, posts.description
LOWER(categories.name) iLIKE ('%music%') DESC, categories.name
另一个评论:iLike
不区分大小写,为什么然后应用LOWER
?这应该返回相同的结果:
SELECT posts.* FROM posts INNER JOIN categories ON categories.id = posts.category_id
WHERE -- can be simplified to
posts.name iLIKE ('%music%')
OR posts.description iLIKE ('%music%')
OR categories.name iLIKE ('%music%')
ORDER BY -- FALSE probably sorts lower than TRUE, thus DESC
posts.name iLIKE ('%music%') DESC, posts.name,
posts.description iLIKE ('%music%') DESC, posts.description
categories.name iLIKE ('%music%') DESC, categories.name
现在结合@ JuanCarlosOropeza的答案: - )
答案 1 :(得分:2)
ORDER BY
CASE WHEN LOWER(posts.name) iLIKE ('%music%') THEN posts.name END,
CASE WHEN LOWER(posts.description) iLIKE ('%music%') THEN posts.description END,
CASE WHEN LOWER(categories.name) iLIKE ('%music%') THEN categories.name END,
答案 2 :(得分:0)
感谢@ juan-carlos-oropeza和@dnoeth的回复。根据您的建议和摘要,我在下面提出并能够解决此问题
ORDER BY
CASE WHEN posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%') AND categories.name iLIKE ('%music%') THEN 0 END,
CASE WHEN posts.name iLIKE ('%music%') AND posts.description iLIKE ('%music%') THEN 1 END,
CASE WHEN posts.name iLIKE ('%music%') THEN 2 END,
CASE WHEN posts.description iLIKE ('%music%') THEN 3 END,
CASE WHEN categories.name iLIKE ('%music%') THEN 4 END