我正在使用SQL Server manager 2008。
我的查询如下:
SELECT dbo.iLines.Part,
dbo.iLines.Pg,
SUM(dbo.iLines.Qty) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.iLines
RIGHT JOIN
dbo.product
ON
dbo.product.keycode = dbo.ilines.part
where prefix = 'i'
and ([datetime] > dateadd(month, -6, getdate()))
and dbo.ilines.part = 'BK939'
group by
dbo.ilines.pg,
dbo.ilines.part,
dbo.ilines.prefix
order by sales6months desc
因此,为了解释,我希望在产品表中的所有产品上获得最后6个月的销售额。
问题在于某些产品没有任何销售。我仍然需要它们来展示。 所以我要问的是显示所有产品的最后6个月销售额,包括0个销售额。
" iLines"是导致问题的表格,因为如果有销售,零件编号只存在于那里。
我知道可能有一种方法可以进行多次查询等。但我只需要1次查询就可以了。
我试过让null通过,但什么也没做,加上它真的很可怕使用空值呵呵。
要添加到此查询的任何代码段都非常棒!!
非常感谢!
如果您还需要更多信息,请询问!
UPDATE! 对不起,日期仅存在于Ilines。
Ilines =销售表 产品=只是我们所有产品的表格
这是主要的查询,它意味着拉动顶部" n"在过去6个月内售出的零件。 它起作用,除了我说它没有显示没有出售的零件。
ALTER PROCEDURE [dbo].[MyPareto]
@pgParam varchar(255)
AS
SELECT
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.part,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
FROM
OPENQUERY(SACBAUTO, 'SELECT dbo.iLines.Part,
dbo.iLines.Pg,
SUM(dbo.iLines.Qty) as sales6months,
dbo.iLines.Prefix
FROM Autopart.dbo.iLines
where prefix = ''i''
and [datetime] > dateadd(month, -6, getdate())
group by
dbo.ilines.pg,
dbo.ilines.part,
dbo.ilines.prefix
order by sales6months desc') i
RIGHT JOIN
dbo.OldParetoAnalysis
on
i.part collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
INNER JOIN
dbo.NewParetoAnalysis
ON
dbo.OldParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NewParetoAnalysis.Part
LEFT JOIN
OPENQUERY(SACBAUTO, 'SELECT dbo.aLines.Part,
dbo.aLines.Pg,
SUM(dbo.aLines.Qty) as LostSales6Months,
dbo.aLines.Prefix
FROM Autopart.dbo.aLines
where prefix = ''d''
and [datetime] > dateadd(month, -6, getdate())
group by
dbo.alines.pg,
dbo.alines.part,
dbo.alines.prefix
order by LostSales6Months desc') a
ON
dbo.NewParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = a.part
WHERE
i.pg = @pgParam
GROUP BY
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.part,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
ORDER BY
dbo.OldParetoAnalysis.Pareto asc
将pareto视为最佳部分的联盟。
希望这会有所帮助,我试图避免添加它,因为它可能会让一些人不予评论。
好的新更新,这个打开的查询有效!!!
SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )
WHERE
(dbo.iLines.Prefix = 'i' OR dbo.iLines.Prefix is null)
AND dbo.product.keycode = 'BK939'
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc#
但是当我加入我的帕累托表时如下:
SELECT
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.keycode,
i.sales6months
FROM
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )/* must be this*/
WHERE
(dbo.iLines.Prefix = ''i'' OR dbo.iLines.Prefix is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc') i
LEFT JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
WHERE i.pg = '40' AND i.keycode = 'BK939'
结果回归相同,所以这意味着问题是当我去加入时,但是老帕累托确实包含了部件号,而且我也试过改变连接....我希望这会缩小搜索范围对于这个问题我希望有人知道为什么会发生这种情况!
最终更新! 哇这是looong,但最后我想出了问题,我不得不重新检查产品表PG字段!!!!!因为它不会是空的!这是代码!
ALTER PROCEDURE [dbo].[MyPareto32TEST]
@pgParam varchar(255)
AS
SELECT
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.keycode,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
FROM
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
dbo.product.pg as ppg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )
WHERE
(dbo.iLines.Prefix = ''i'' OR dbo.iLines.Prefix is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix,
dbo.product.pg
order by sales6months desc') i
RIGHT JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
AND (i.pg = @pgParam or (i.pg is null AND i.ppg = @pgParam))
INNER JOIN
dbo.NewParetoAnalysis
ON
dbo.OldParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NewParetoAnalysis.Part
LEFT JOIN
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.aLines.Pg,
SUM(COALESCE(dbo.aLines.Qty, 0)) as lostsales6months,
dbo.aLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.alines
ON
dbo.product.keycode = dbo.alines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )
WHERE
(dbo.aLines.Prefix = ''d'' OR dbo.aLines.Prefix is null)
group by
dbo.alines.pg,
dbo.product.keycode,
dbo.alines.prefix
order by lostsales6months desc') a
ON
dbo.NewParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = a.keycode
WHERE(i.pg = @pgParam or (i.pg is null AND i.ppg = @pgParam) AND dbo.NewParetoAnalysis.Pareto is not null)
GROUP BY
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.keycode,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
ORDER BY
dbo.OldParetoAnalysis.Pareto asc
答案 0 :(得分:5)
以下条件会过滤掉right join
失败的任何行:
dbo.ilines.part = 'BK939'
要解决此问题,请将条件移至联接:
RIGHT JOIN
dbo.product
ON
dbo.product.keycode = dbo.ilines.part
and dbo.ilines.prefix = 'i'
and dbo.ilines.part = 'BK939'
where
([datetime] > dateadd(month, -6, getdate()))
假设[datetime]
是product
的列,您可以将其保留在where
子句中。
答案 1 :(得分:3)
我会从你想要的表格和我自己做的工作开始joins
。你说你想要product
。为什么不从该表开始,然后将LEFT JOIN
带到iLines
?
也许这样的话:
SELECT
dbo.product.keycode AS part,
dbo.iLines.Pg,
SUM(dbo.iLines.Qty) as sales6months,
dbo.iLines.Prefix
FROM
dbo.product
LEFT JOIN dbo.ilines
ON dbo.product.keycode = dbo.ilines.part
AND dbo.ilines.prefix = 'i'
and dbo.ilines.part = 'BK939'
where
([datetime] > dateadd(month, -6, getdate()))
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc
我不知道[datetime]
列是来自product
表,还是来自ilines
表。如果它来自product
表,那么上面的表可能适用。如果没有,那么也将它放在LEFT JOIN
中。像这样:
LEFT JOIN dbo.ilines
ON dbo.product.keycode = dbo.ilines.part
AND dbo.ilines.prefix = 'i'
and dbo.ilines.part = 'BK939'
AND ([datetime] > dateadd(month, -6, getdate()))
修改强>
根据您的描述,您需要FULL OUTER JOIN
。所以这次加入将是:
LEFT JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
像这样:
FULL OUTER JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
在msdn上它说:
通过在其中包含不匹配的行来保留不匹配的信息 连接的结果,使用完整的外连接。 SQL Server提供了 全外连接运算符,FULL OUTER JOIN,包括所有行 来自两个表,无论另一个表是否有 匹配价值。
参考here
<强> EDIT2 强>
您是否尝试过正确加入dbo.OldParetoAnalysis?像这样:
RIGHT JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
<强> EDIT3 强>
您可以尝试的另一件事是创建临时表。这不是最好的解决方案。但也许是这样的:
CREATE TABLE #tmp
(
Keycode VARCHAR(100),
Pg VARCHAR(100),
sales6months INT,
Prefix VARCHAR(100)
)
然后插入OPENQUERY
INSERT INTO #tmp(Keycode,Pg,sales6months,Prefix)
SELECT
i.Keycode,
i.pg,
i.sales6months
i.Prefix,
FROM
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )/* must be this*/
WHERE
(dbo.iLines.Prefix = ''i'' OR dbo.iLines.Prefix is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc') i
然后我们加入了临时表。像这样:
SELECT
*
FROM
#tmp AS i
LEFT JOIN dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
WHERE i.pg = '40' AND i.keycode = 'BK939'
请记住在完成后删除临时表。像这样:
DROP TABLE #tmp
<强> EDIT4 强>
如果你有原始的商店程序,那么代码应该和你一起使用临时表soulution,那么这可能会有所帮助:
ALTER PROCEDURE [dbo].[MyPareto]
@pgParam varchar(255)
AS
CREATE TABLE #tmp
(
Keycode VARCHAR(100),--The type I don't know
Pg VARCHAR(100),--The type I don't know
sales6months INT,--The type I don't know
Prefix VARCHAR(100)--The type I don't know
)
INSERT INTO #tmp(Keycode,Pg,sales6months,Prefix)
SELECT
i.Keycode,
i.pg,
i.sales6months,
i.Prefix
FROM
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )/* must be this*/
WHERE
(dbo.iLines.Prefix = ''i'' OR dbo.iLines.Prefix is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc') i
SELECT
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.part,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
FROM
#tmp i
RIGHT JOIN dbo.OldParetoAnalysis
on i.part collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
INNER JOIN dbo.NewParetoAnalysis
ON dbo.OldParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NewParetoAnalysis.Part
LEFT JOIN #tmp a
ON dbo.NewParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = a.part
WHERE
i.pg = @pgParam
GROUP BY
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.part,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
ORDER BY
dbo.OldParetoAnalysis.Pareto asc
DROP TABLE #tmp
答案 2 :(得分:3)
问题根源:怀疑子句条件限制了由于正确加入而原本会存在的数据。
可能的解决方案
这是在where子句上使用null。 (修改)我们似乎都错过了从PARTS中选择的选择!不是ilines。
SELECT dbo.product.keycode as PART,
dbo.iLines.Pg,
SUM(coalesce(dbo.iLines.Qty,0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.iLines
RIGHT JOIN
dbo.product
ON
dbo.product.keycode = dbo.ilines.part
where (prefix = 'i' or prefix is null)
and (([datetime] > dateadd(month, -6, getdate())) OR [datetime] is null)
and (dbo.ilines.part = 'BK939' or dbo.ilines.part is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix
order by sales6months desc
答案 3 :(得分:2)
你需要一个外部联接 - 像这样:
SELECT dbo.product.keycode,
dbo.iLines.Pg,
SUM(dbo.iLines.Qty) as sales6months,
dbo.iLines.Prefix
FROM
dbo.product
LEFT OUTER JOIN Autopart.dbo.iLines ON dbo.product.keycode = dbo.ilines.part
在您的查询中,您只选择prefix='i'
的销售,这将自动排除没有销售的产品,因此我不确定您希望如何处理。
答案 4 :(得分:2)
您仍在过滤外部联接中可能为NULL的内容。在where子句中加入Pareto表之后:
WHERE i.pg = '40'
该列的源(在您的OPENQUERY语句中)是dbo.ILines,它是外部连接到产品的,因此如果产品没有出现在ILines集中,则为NULL。您可以尝试:
WHERE ISNULL(i.pg, '40') = '40'
当然,如果即使dbo.ILines表中存在记录,i.pg也可以为NULL,那么您可能需要在原始查询中包含ILines中的键,并执行以下操作:
WHERE ( i.pg = '40'
OR i.<ILinesKeyField> IS NULL
)
这确保即使你在dbo.ILines.Pg中有NULL并且NULL字段不是由于外连接,也会过滤掉不需要的行。
答案 5 :(得分:1)
为什么不从产品表中选择all并在Autopart.dbo.iLines上保持联接?这将为您提供所有产品,然后加入匹配且不匹配的iLines表。
答案 6 :(得分:0)
下面是代码,只需要从产品表和ilines中检查PG !!
ALTER PROCEDURE [dbo].[MyPareto32TEST]
@pgParam varchar(255)
AS
SELECT
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.keycode,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
FROM
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.iLines.Pg,
dbo.product.pg as ppg,
SUM(COALESCE(dbo.iLines.Qty, 0)) as sales6months,
dbo.iLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.ilines
ON
dbo.product.keycode = dbo.ilines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )
WHERE
(dbo.iLines.Prefix = ''i'' OR dbo.iLines.Prefix is null)
group by
dbo.ilines.pg,
dbo.product.keycode,
dbo.ilines.prefix,
dbo.product.pg
order by sales6months desc') i
RIGHT JOIN
dbo.OldParetoAnalysis
on
i.keycode collate SQL_Latin1_General_CP1_CI_AS = dbo.OldParetoAnalysis.Part
AND (i.pg = @pgParam or (i.pg is null AND i.ppg = @pgParam))
INNER JOIN
dbo.NewParetoAnalysis
ON
dbo.OldParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = dbo.NewParetoAnalysis.Part
LEFT JOIN
OPENQUERY(SACBAUTO, 'SELECT
dbo.product.Keycode,
dbo.aLines.Pg,
SUM(COALESCE(dbo.aLines.Qty, 0)) as lostsales6months,
dbo.aLines.Prefix
FROM
Autopart.dbo.product
LEFT OUTER JOIN
Autopart.dbo.alines
ON
dbo.product.keycode = dbo.alines.part
AND ([datetime] > dateadd(month, -6, getdate()) OR [datetime] is null )
WHERE
(dbo.aLines.Prefix = ''d'' OR dbo.aLines.Prefix is null)
group by
dbo.alines.pg,
dbo.product.keycode,
dbo.alines.prefix
order by lostsales6months desc') a
ON
dbo.NewParetoAnalysis.Part collate SQL_Latin1_General_CP1_CI_AS = a.keycode
WHERE(i.pg = @pgParam or (i.pg is null AND i.ppg = @pgParam) AND dbo.NewParetoAnalysis.Pareto is not null)
GROUP BY
i.pg,
dbo.OldParetoAnalysis.Pareto,
i.keycode,
i.sales6months,
a.LostSales6Months,
dbo.NewParetoAnalysis.Pareto
ORDER BY
dbo.OldParetoAnalysis.Pareto asc
答案 7 :(得分:-1)
SELECT
dbo.iLines.Part,
dbo.iLines.Pg,
SUM(dbo.iLines.Qty) as sales6months,
dbo.iLines.Prefix
FROM Autopart.dbo.iLines
RIGHT JOIN dbo.product
ON dbo.product.keycode = dbo.ilines.part
where prefix = 'i'
and ([datetime] > dateadd(month, -6, getdate()))
and dbo.ilines.part = 'BK939'
group by
dbo.ilines.pg,
dbo.ilines.part,
dbo.ilines.prefix
union
SELECT
dbo.iLines.Part,
dbo.iLines.Pg,
0 as sales6months,
dbo.iLines.Prefix
FROM Autopart.dbo.iLines
RIGHT JOIN dbo.product
ON dbo.product.keycode = dbo.ilines.part
where prefix = 'i'
and max([datetime]) < dateadd(month, -6, getdate())
and dbo.ilines.part = 'BK939'
group by
dbo.ilines.pg,
dbo.ilines.part,
dbo.ilines.prefix
order by sales6months desc