我有一个场景,我必须在出售书籍时获得最后10个日期。请考虑以下示例
stored.Id
我的结果基于 BookName 11/11/2015 15/11/2015 17/11/2015
XYZ 20 -- --
JHG 10 -- --
UYH -- 10 --
TRE -- -- 50
。当我传递ID时,应该使用bookname售出日期和销售副本数生成报告。
输出:
//if you want to make the select take a default color as the first option
color_Board.css({background: color_Board.find("option:eq(0)").parent().css("background-image")});
color_Board.on('change', function(e){
$(this).css({background: $(this).find("option:selected").parent().css("background-image") });
});
希望我的问题是可以理解的。
答案 0 :(得分:2)
这看起来不吉利,但这是一个地狱的问题。
integer
。NOT NULL
。 (name, sid, date)
在表book
中定义为唯一。 此顺序中的列优先(用于执行):
UNIQUE(sid, date, name)
详细说明:
crosstab()
查询要获得最佳效果和较短的查询字符串(特别是如果您经常运行此查询),我建议额外的模块 tablefunc
提供各种crosstab()
功能。 基本说明:
你需要先把这些做好。
过去10天:
SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY 1 DESC
LIMIT 10;
过去10天的数字:
SELECT name, date, count
FROM book
WHERE sid = 1
AND date >= (
SELECT DISTINCT date
FROM book
ORDER BY 1 DESC
OFFSET 9
LIMIT 1
)
ORDER BY 1,2;
输出列的列名(完整解决方案):
SELECT 'bookname, "' || string_agg(to_char(date, 'DD/MM/YYYY'), '", "') || '"'
FROM (
SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY 1 DESC
LIMIT 10
) sub;
SQL Fiddle演示SQL部分。 (此处未安装附加模块tablefunc。)
这对您来说可能已经足够了(但是您没有在结果中看到实际日期):
SELECT * FROM crosstab(
'SELECT name, date, count
FROM book
WHERE sid = 1
AND date >= (
SELECT DISTINCT date FROM book
ORDER BY 1 DESC
OFFSET 9 LIMIT 1
)
ORDER BY 1,2'
, 'SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY 1 DESC
LIMIT 10'
) AS (bookname text
, date1 int, date2 int, date3 int, date4 int, date5 int
, date6 int, date7 int, date8 int, date9 int, date10 int);
对于重复使用,我建议你为10个整数列创建一个(非常快)的通用C函数,以简化一些事情:
CREATE OR REPLACE FUNCTION crosstab_int10(text, text)
RETURNS TABLE (bookname
, date1, date2, date3, date4, date5
, date6, date7, date8, date9, date10) AS
'$libdir/tablefunc','crosstab_hash' LANGUAGE C STABLE STRICT;
此相关答案的详细信息:
然后你的电话就变成了:
SELECT * FROM crosstab_int10(
'SELECT name, date, count
FROM book
WHERE sid = 1
AND date >= (
SELECT DISTINCT date FROM book
ORDER BY 1 DESC
OFFSET 9 LIMIT 1
)
ORDER BY 1,2'
, 'SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY 1 DESC
LIMIT 10'
); -- no column definition list required!
您的实际问题更复杂,您还需要动态列名 对于给定的表,结果查询可能如下所示:
SELECT * FROM crosstab_int10(
'SELECT name, date, count
FROM book
WHERE sid = 1
AND date >= (
SELECT DISTINCT date FROM book
ORDER BY 1 DESC
OFFSET 9 LIMIT 1
)
ORDER BY 1,2'
, 'SELECT DISTINCT date
FROM book
WHERE sid = 1
ORDER BY 1 DESC
LIMIT 10'
) AS t(bookname
, "17/11/2015", "15/11/2015", "11/11/2015", "10/11/2015"
, "09/11/2015", "08/11/2015", "07/11/2015", "06/11/2015"
, "05/11/2015", "04/11/2015");
难点在于提炼动态列名。要么手工组装查询字符串,要么(更确切地说)让这个函数为你做:
CREATE OR REPLACE FUNCTION f_generate_date10_sql(_sid int = 1)
RETURNS text AS
$func$
SELECT format(
$$SELECT * FROM crosstab_int10(
'SELECT name, date, count
FROM book
WHERE sid = %1$s
AND date >= (
SELECT DISTINCT date FROM book
ORDER BY 1 DESC
OFFSET 9 LIMIT 1
)
ORDER BY 1,2'
, 'SELECT DISTINCT date
FROM book
WHERE sid = %1$s
ORDER BY 1 DESC
LIMIT 10'
) AS ct(bookname, "$$
|| string_agg(to_char(date, 'DD/MM/YYYY'), '", "') || '")'
, _sid)
FROM (
SELECT DISTINCT date
FROM book
ORDER BY 1 DESC
LIMIT 10
) sub
$func$ LANGUAGE sql;
呼叫:
SELECT f_generate_date10_sql(1);
此会生成所需的查询,您可以依次执行该查询。