如果随机选择很简单,则从另一个表中添加行

时间:2016-01-04 17:47:41

标签: sql postgresql

我遇到了以下问题,并且正在努力尝试使用SQL找出解决方案:

假设我有一张满是各种(德语)字样的表:

WORD
"Sammlung"
"stimmen"
"Stämme"
"immerzu"

从这张表中我想得到一个符合特殊标准的随机数量的单词,例如只有单词中含有“mm”的单词:

SELECT wo_id AS id, wo_word AS word
FROM word 
LEFT JOIN wo_wo_ca_rel USING (wo_id)
LEFT JOIN word_category USING (wo_ca_id) -- all word categories like "mm", "aa" ... are stored here
-- word_category stores wo_ca_id : SERIAL and wo_ca_category : TEXT ("mm")
WHERE wo_ca_id = (SELECT wo_ca_id FROM word_category ORDER BY RANDOM() LIMIT 1) -- this gets a random category, but lets pretend it gets us "mm"
ORDER BY RANDOM() LIMIT 5

要获取包含“mm”的随机单词,我使用此查询:

WORD
"Sammlung"
"stimmen"
"Stämme"
"immerzu"

我想出了这两件事情。我现在感兴趣的是以下内容:

假设我想在其中添加5个带有“mm”的随机单词。如果我的单词表中没有足够的内容(假设只有4个,就像在我的例子中那样),那么查询的结果应该用单词表中的随机单词填充,直到它总共返回5个单词。

所以不要只获得:

WORD
"Sammlung"
"stimmen"
"Stämme"
"immerzu"
"hallo"
它应该给我一些类似的东西:

$(".product-img").each(function(){
    $(this).attr("src","images/products/" + $(this).siblings(".product.sku").html() + ".jpg");
});

我知道我可以简单地得到“mm”查询的结果,检查我的应用程序中的计数/长度并发送另一个查询以获取遗漏的单词,但我很好奇是否可以通过查询我的方式来完成数据库一次。

2 个答案:

答案 0 :(得分:1)

-- DDL
CREATE TABLE words (
  val TEXT
);
-- sample data
INSERT INTO words VALUES
  ('Sammlung'),
  ('stimmen'),
  ('Stämme'),
  ('immerzu'),
  ('aaaaaaa'),
  ('bbbbbbb');

-- n -> number of records to return; 
-- value -> pattern to look for
CREATE OR REPLACE FUNCTION get_random_words(n integer,value text) RETURNS SETOF words AS $$
DECLARE
  word_count integer;
  pattern text;
  extra_row_count integer;
BEGIN
  pattern := '%' || value || '%';
  --count number of results for given pattern
  SELECT count(w.val) INTO word_count
    FROM words w WHERE w.val LIKE pattern;
  --check all possible conditions
  IF word_count = n THEN
    RETURN QUERY SELECT val FROM words WHERE val LIKE pattern ORDER BY RANDOM();
  ELSEIF word_count > n THEN
    RETURN QUERY SELECT val FROM words WHERE val LIKE pattern ORDER BY RANDOM() LIMIT n;
  ELSE
    extra_row_count := n - word_count;
    --return words matching criteria
    RETURN QUERY SELECT val FROM words WHERE val LIKE pattern ORDER BY RANDOM();
    --return additional number of random words
    RETURN QUERY SELECT val FROM words ORDER BY RANDOM() LIMIT extra_row_count;
  END IF;
END;
$$ LANGUAGE plpgsql;

-- Sample run
SELECT * FROM get_random_words(5,'mm');

答案 1 :(得分:0)

以下是使用limit条件排序(与where条件相比)的一个选项:

select word
from yourtable
order by word like '%aa%' desc
limit 2

鉴于您的编辑,这应该以相同的方式工作:

SELECT wo_id AS id, wo_word AS word
FROM word 
    LEFT JOIN wo_wo_ca_rel USING (wo_id)
    LEFT JOIN word_category USING (wo_ca_id)
ORDER BY wo_ca_id = (SELECT wo_ca_id FROM word_category ORDER BY RANDOM() LIMIT 1) DESC, 
         RANDOM() 
LIMIT 5